Cannot change the init_value of look_at kwarg from Makie.Camera3D

This is the code modified (only 1 line) from Cameras | Makie

HAVE tried some other walkarounds, none works, either…

using GeometryBasics, LinearAlgebra

function frustum_snapshot(cam)
    r = Rect3f(Point3f(-1, -1, -1), Vec3f(2, 2, 2))
    rect_ps = coordinates(r) .|> Point3f
    insert!(rect_ps, 13, Point3f(1, -1, 1)) # fix bad line

    inv_pv = inv(cam.projectionview[])
    return map(rect_ps) do p
        p = inv_pv * to_ndim(Point4f, p, 1)
        return p[Vec(1,2,3)] / p[4]
    end
end


ex = Point3f(1,0,0)
ey = Point3f(0,1,0)
ez = Point3f(0,0,1)

fig = Figure()
scene = LScene(fig[1, 1])
cc = Makie.Camera3D(scene.scene, 
    projectiontype = Makie.Perspective, 
    lookat = [0,0,0]) # --------------> not work, HAVE tried some other walkarounds, none works, either.

linesegments!(scene, Rect3f(Point3f(-1), Vec3f(2)), color = :black)
linesegments!(scene,
    [-ex, ex, -ey, ey, -ez, ez],
    color = [:red, :red, :green, :green, :blue, :blue]
)
center!(scene.scene)

cam = scene.scene.camera
eyeposition = cc.eyeposition
lookat = cc.lookat
frustum = map(pv -> frustum_snapshot(cam), cam.projectionview)

scene = LScene(fig[1, 2])
_cc = Makie.Camera3D(scene.scene, projectiontype = Makie.Orthographic)
lines!(scene, frustum, color = :blue, linestyle = :dot)
scatter!(scene, eyeposition, color = :black)
scatter!(scene, lookat, color = :black)

linesegments!(scene,
    [-ex, ex, -ey, ey, -ez, ez],
    color = [:red, :red, :green, :green, :blue, :blue]
)
linesegments!(scene, Rect3f(Point3f(-1), Vec3f(2)), color = :black)

fig

In this case I think the method you’re using to construct cc doesn’t forward the lookat attribute.

You can set the value by setting cc.lookat[] = Vec3f(0, 0, 0) though! Though it only takes effect when you interact with the scene.

Yep, modifying the built-in observable cc.lookat[] will work, when interacting with EPRL afterwards. But this can be done only after the script finishing running, so it is not that ‘automatic’ for involving unnecessary interaction.

I found that the problem seems to be that Makie updates cc.lookat[] for the overall geometric/gravitational center of all objects drawn.

Therefore, even if the default value of cc.lookat[] was previously set, it will still be automatically reset in the fig line.

It seems that all other 3D scenes involving LScene have this feature or issue. For example: LScene | Makie has the same issue:

using GLMakie

fig = Figure()
pl = PointLight(Point3f(0), RGBf(20, 20, 20))
al = AmbientLight(RGBf(0.2, 0.2, 0.2))
ax = LScene(fig[1, 1], show_axis=false, scenekw = (lights = [pl, al], backgroundcolor=:black, clear=true))
# now you can plot into lscene like you're used to
p = meshscatter!(ax, randn(300, 3), color=:gray)

cc = Makie.Camera3D(ax.scene)
println(cc.lookat[])
on(events(fig.scene).window_open) do event
    if event
        println(cc.lookat[])
    end
end

fig

I found a temporary solution: add a paragraph before the ‘fig’ line:

on(events(fig.scene).window_open) do event
    if event
        cc.lookat[] = [0, 0, 0]
    end
end

The complete code is as follows:

using GeometryBasics, LinearAlgebra

function frustum_snapshot(cam)
    r = Rect3f(Point3f(-1, -1, -1), Vec3f(2, 2, 2))
    rect_ps = coordinates(r) .|> Point3f
    insert!(rect_ps, 13, Point3f(1, -1, 1)) # fix bad line

    inv_pv = inv(cam.projectionview[])
    return map(rect_ps) do p
        p = inv_pv * to_ndim(Point4f, p, 1)
        return p[Vec(1,2,3)] / p[4]
    end
end


ex = Point3f(1,0,0)
ey = Point3f(0,1,0)
ez = Point3f(0,0,1)

fig = Figure()
scene = LScene(fig[1, 1])
cc = Makie.Camera3D(scene.scene, 
    projectiontype = Makie.Perspective, 
    lookat = [0,0,0]) # --------------> not work, HAVE tried some other walkarounds, none works, either.

linesegments!(scene, Rect3f(Point3f(-1), Vec3f(2)), color = :black)
linesegments!(scene,
    [-ex, ex, -ey, ey, -ez, ez],
    color = [:red, :red, :green, :green, :blue, :blue]
)
center!(scene.scene)

cam = scene.scene.camera
eyeposition = cc.eyeposition
lookat = cc.lookat
frustum = map(pv -> frustum_snapshot(cam), cam.projectionview)

scene = LScene(fig[1, 2])
_cc = Makie.Camera3D(scene.scene, projectiontype = Makie.Orthographic)
lines!(scene, frustum, color = :blue, linestyle = :dot)
scatter!(scene, eyeposition, color = :black)
scatter!(scene, lookat, color = :black)

linesegments!(scene,
    [-ex, ex, -ey, ey, -ez, ez],
    color = [:red, :red, :green, :green, :blue, :blue]
)
linesegments!(scene, Rect3f(Point3f(-1), Vec3f(2)), color = :black)

on(events(fig.scene).window_open) do event
    if event
        cc.lookat[] = [0, 0, 0]
    end
end

fig

It seems that other :kwargs of Camera3D cannot be modified from the defaults as well, by testing:

cc.eyeposition[] = Point3f(0.75f0)
println(cc.eyeposition[])
on(events(fig.scene).window_open) do event
    if event
        println(cc.eyeposition[])
    end
end

before the ‘fig’ line.

So I have to add some magics like:

on(events(fig.scene).window_open) do event
    if event
        cc.lookat[] = [0, 0, 0]
        cc.eyeposition[] = Point3f(0.75f0)
    end
end

before the ‘fig’ line,

to fix some bugs like: