Repository: JuliaPlots/Makie.jl (julia)

Issue:
arrows doesn't start at base
- [x] what version of Makie are you running? (`]st -m Makie`) v0.22.2
- [x] can you reproduce the bug with a fresh environment ? (`]activate --temp; add Makie`)
- [x] What platform + GPU are you on? Arch Linux, integrated Intel graphics on laptop.

just updated, so:
Julia 1.11.4
GLMakie v0.11.3

the arrows drawn here don't start at 0
```julia
fig = Figure()
ax = Axis3(fig[1, 1]) # also with aspect = :data.
o = Point3f(0.0, 0.0, 0.0)
n = Vec3f(0, 0, 1) 
arrows!(ax,[o], [n])
```

![Image](https://github.com/user-attachments/assets/5f34840e-46b9-4925-928f-8161d8ad450a)
![Image](https://github.com/user-attachments/assets/d3f82642-131e-42cd-ae23-81d5f9b60e9a)

Pull request:
# Description

Fixes #4870

Reverts a change in defaults caused by #4606

Arrows assumes the scattered meshes to transform just like a normal mesh. I.e. to get the correct length all the vertices should effectively go through the full transformation pipeline. This is not the case with `transform_marker = false`, as that excludes model. 

## Type of change

- [x] Bug fix (non-breaking change which fixes an issue)

## Checklist

- [x] Added an entry in CHANGELOG.md (for new features and breaking changes)
- [ ] Added or changed relevant sections in the documentation
- [ ] Added unit tests for new algorithms, conversion methods, etc.
- [x] Added reference image tests for new plotting functions, recipes, visual options, etc.

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3aabe4b5f41..200392528c2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,8 @@
 - Improved compatibility of marker attributes with float32convert, fixing issues with scatter markers being render too small with `markerspace = :data` in an Axis [#4869](https://github.com/MakieOrg/Makie.jl/pull/4869)
 - Added `font` attribute and fixed faulty selection in `scatter`. Scatter fonts can now be themed with `markerfont`. [#4832](https://github.com/MakieOrg/Makie.jl/pull/4832)
 - Fixed categorical `cgrad` interpolating at small enough steps [#4858](https://github.com/MakieOrg/Makie.jl/pull/4858)
+- Added `transform_marker` to arrows [#4871](https://github.com/MakieOrg/Makie.jl/pull/4871)
+- Reverted change in `meshscatter` transformation behavior by using `transform_marker = true` as the default [#4871](https://github.com/MakieOrg/Makie.jl/pull/4871)
 - Fixed an error with Colorbar for categorical colormaps, where they displayed values out of colorrange and NaN. [#4894](https://github.com/MakieOrg/Makie.jl/pull/4894)
 - Fixed minor grid not showing in Axis when minorticks are hidden [#4896](https://github.com/MakieOrg/Makie.jl/pull/4896)
 - Fixed issue with small scatter markers disappearing in CairoMakie [#4882](https://github.com/MakieOrg/Makie.jl/pull/4882)
diff --git a/MakieCore/src/basic_plots.jl b/MakieCore/src/basic_plots.jl
index 12af5ab0e92..ac8805e48bc 100644
--- a/MakieCore/src/basic_plots.jl
+++ b/MakieCore/src/basic_plots.jl
@@ -535,8 +535,8 @@ Plots a mesh for each element in `(x, y, z)`, `(x, y)`, or `positions` (similar
     can be changed by passing a tuple `(op3, op2, op1)`.
     """
     uv_transform = automatic
-    "Controls whether the (complete) model matrix applies to the scattered mesh, rather than just the positions. (If this is true, `scale!`, `rotate!` and `translate!()` will affect the scattered mesh.)"
-    transform_marker = false
+    "Controls whether the (complete) model matrix applies to the scattered mesh, rather than just the positions. (If this is false, `scale!`, `rotate!` and `translate!()` will not affect the scattered mesh.)"
+    transform_marker = true
     mixin_generic_plot_attributes()...
     mixin_shading_attributes()...
     mixin_colormap_attributes()...
@@ -803,4 +803,6 @@ or other array-like output.
     linewidth = automatic
     """Sets the color of the arrow head. Will copy `color` if set to `automatic`."""
     arrowcolor = automatic
+    "Controls whether marker attributes get transformed by the model matrix."
+    transform_marker = automatic
 end
diff --git a/src/basic_recipes/arrows.jl b/src/basic_recipes/arrows.jl
index ef872dd0290..d2f75b3e53c 100644
--- a/src/basic_recipes/arrows.jl
+++ b/src/basic_recipes/arrows.jl
@@ -85,7 +85,7 @@ function plot!(arrowplot::Arrows{<: Tuple{AbstractVector{<: Point{N}}, V}}) wher
     @extract arrowplot (
         points, directions, colormap, colorscale, normalize, align,
         arrowtail, color, linecolor, linestyle, linewidth, lengthscale,
-        arrowhead, arrowsize, arrowcolor, quality,
+        arrowhead, arrowsize, arrowcolor, quality, transform_marker,
         # passthrough
         diffuse, specular, shininess, shading,
         fxaa, ssao, transparency, visible, inspectable
@@ -93,7 +93,8 @@ function plot!(arrowplot::Arrows{<: Tuple{AbstractVector{<: Point{N}}, V}}) wher
 
     line_c = lift((a, c)-> a === automatic ? c : a , arrowplot, linecolor, color)
     arrow_c = lift((a, c)-> a === automatic ? c : a , arrowplot, arrowcolor, color)
-    fxaa_bool = lift(fxaa -> fxaa == automatic ? N == 3 : fxaa, arrowplot, fxaa) # automatic == fxaa for 3D
+    fxaa_bool = lift(fxaa -> fxaa == automatic ? N == 3 : fxaa, arrowplot, fxaa) # automatic -> true for 3D, false for 2D
+    tm = lift(tm -> tm == automatic ? N == 3 : tm, arrowplot, transform_marker) # automatic -> true for 3D, false for 2D
 
     marker_head = lift((ah, q) -> arrow_head(N, ah, q), arrowplot, arrowhead, quality)
     if N == 2
@@ -148,7 +149,8 @@ function plot!(arrowplot::Arrows{<: Tuple{AbstractVector{<: Point{N}}, V}}) wher
             color = arrow_c, rotation = rotations, strokewidth = 0.0,
                  colormap=colormap, markerspace=arrowplot.markerspace, colorrange=arrowplot.colorrange,
             fxaa = fxaa_bool, inspectable = inspectable,
-            transparency = transparency, visible = visible
+            transparency = transparency, visible = visible,
+            transform_marker = tm
         )
     else
         msize = Observable{Union{Vec3f, Vector{Vec3f}}}()
@@ -184,7 +186,8 @@ function plot!(arrowplot::Arrows{<: Tuple{AbstractVector{<: Point{N}}, V}}) wher
             color = line_c, colormap = colormap, colorscale = colorscale, colorrange = arrowplot.colorrange,
             fxaa = fxaa_bool, ssao = ssao, shading = shading,
             diffuse = diffuse, specular = specular, shininess = shininess,
-            inspectable = inspectable, transparency = transparency, visible = visible
+            inspectable = inspectable, transparency = transparency, visible = visible,
+            transform_marker = tm
         )
         meshscatter!(
             arrowplot,
@@ -193,7 +196,8 @@ function plot!(arrowplot::Arrows{<: Tuple{AbstractVector{<: Point{N}}, V}}) wher
             color = arrow_c, colormap = colormap, colorscale = colorscale, colorrange = arrowplot.colorrange,
             fxaa = fxaa_bool, ssao = ssao, shading = shading,
             diffuse = diffuse, specular = specular, shininess = shininess,
-            inspectable = inspectable, transparency = transparency, visible = visible
+            inspectable = inspectable, transparency = transparency, visible = visible,
+            transform_marker = tm
         )
     end
 


Test patch:
diff --git a/ReferenceTests/src/tests/examples3d.jl b/ReferenceTests/src/tests/examples3d.jl
index 3b521b3b8e3..687f2fc010b 100644
--- a/ReferenceTests/src/tests/examples3d.jl
+++ b/ReferenceTests/src/tests/examples3d.jl
@@ -215,6 +215,20 @@ end
     arrows(pts, (normalize.(pts) .* 0.1f0), arrowsize=0.02, linecolor=:green, arrowcolor=:darkblue)
 end
 
+@reference_test "Arrows 3D marker_transform" begin
+    f = Figure()
+    a = Axis3(f[1,1])
+    r = range(-1, 1, length = 5)
+    arrows!(a, Point3f[(1, 0, 0), (0,0,0)], Point3f[(0,0,0.1), (1,0,0)], color = :gray)
+    arrows!(a, Point3f[(-1, 1, 0), (0,0,0)], Point3f[(0,0,0.1), (-1,1,0)], color = :lightblue,
+        transform_marker = false)
+    arrows!(a, Point3f[(1, -1, 0), (0,0,0)], Point3f[(0,0,0.1), (1,-1,0)], color = :yellow,
+        transform_marker = true)
+    mesh!(a, Rect2f(-1,-1,2,2), color = (:red, 0.5), transparency = true)
+    f
+end
+
+
 @reference_test "Image on Surface Sphere" begin
     n = 20
     θ = [0;(0.5:n - 0.5) / n;1]
diff --git a/ReferenceTests/src/tests/figures_and_makielayout.jl b/ReferenceTests/src/tests/figures_and_makielayout.jl
index ddfdf829c89..8de3aff0f66 100644
--- a/ReferenceTests/src/tests/figures_and_makielayout.jl
+++ b/ReferenceTests/src/tests/figures_and_makielayout.jl
@@ -419,7 +419,7 @@ end
     )
     lines!(a, ls, linewidth = 3, transparency = true)
     mesh!(a, m, color = (:orange, 0.2), transparency = true)
-    meshscatter!(a, ps, markersize = 0.15, transparency = false)
+    meshscatter!(a, ps, markersize = 0.15, transparency = false, transform_marker = false)
     f
 end
 
diff --git a/test/boundingboxes.jl b/test/boundingboxes.jl
index 277a2d24677..48839a6dea5 100644
--- a/test/boundingboxes.jl
+++ b/test/boundingboxes.jl
@@ -53,6 +53,8 @@ end
             marker = Rect3f(Point3f(0), Vec3f(2)),
             markersize = 0.1
         )
+        @test p.transform_marker[] == true
+
         bb = boundingbox(p)
         @test bb.origin ≈ Point3f(1)
         @test bb.widths ≈ Vec3f(4 + 0.2)
@@ -65,18 +67,18 @@ end
         scale!(p, 0.5, 0.25, 0.5)
         bb = boundingbox(p)
         @test bb.origin ≈ Vec3f(0.5, 0.25, 0.5) .* Point3f(1) + Point3f(1, 0.5, 2)
-        @test bb.widths ≈ Vec3f(0.5, 0.25, 0.5) .* 4f0 .+ 0.2f0
+        @test bb.widths ≈ Vec3f(0.5, 0.25, 0.5) .* (4f0 .+ 0.2f0)
 
         Makie.rotate!(p, pi/2)
         bb = boundingbox(p)
-        @test bb.origin ≈ Vec3f(0.5, 0.25, 0.5) .* Point3f(-5, 1, 1) + Point3f(1, 0.5, 2)
-        @test bb.widths ≈ Vec3f(0.5, 0.25, 0.5) .* 4f0 .+ 0.2f0
-
-        p.transform_marker = true
-        bb = boundingbox(p)
         @test bb.origin ≈ Vec3f(0.5, 0.25, 0.5) .* Point3f(-5-0.2, 1, 1) + Point3f(1, 0.5, 2)
         @test bb.widths ≈ Vec3f(0.5, 0.25, 0.5) .* (4f0 .+ 0.2f0)
 
+        p.transform_marker = false
+        bb = boundingbox(p)
+        @test bb.origin ≈ Vec3f(0.5, 0.25, 0.5) .* Point3f(-5, 1, 1) + Point3f(1, 0.5, 2)
+        @test bb.widths ≈ Vec3f(0.5, 0.25, 0.5) .* 4f0 .+ 0.2f0
+
         # Testing path with per element markersize and/or rotations
         fig, ax, p = meshscatter(
             [Point3f(0) for _ in 1:3],