Hi,
I’m starting to visualize a collection of meshes in Makie, currently using the mouse to navigate the content. However, after a while the rotate, drag and zoom performed usually make me end up with parts of the content getting clipped (i assume there is a frustum defined somewhere) when I try to take a closer look.
I believe that what I would need is essentially better camera control, preferably by a combination of mous and keyboard eg right/left/forward/back/up/down (strafe?) to control both position and orientation. I guess someone has dome something simliar - or even cooler - already, but searching for something like it I failed find something.
When I did try the keyboard example from documentation I ran into events not liking being called with a ::Make.Scene
Currently I use GLMakie from the REPL for this, but I could see it moving to WGLMakie eventually.
I have some ancient code that added some keyboard controls, though not the ones you want. I also don’t know how well it works on other operating systems. Maybe it’s helpful anyway, so here’s a version that should work with the current version of Makie:
Code
using GLMakie, LinearAlgebra
function key_controls!(
ax::LScene;
tilt_up = Keyboard.w,
tilt_down = Keyboard.s,
roll_clockwise = Keyboard.e,
roll_counterclockwise = Keyboard.q,
pan_left = Keyboard.a,
pan_right = Keyboard.d,
step_size::AbstractFloat = Float32(pi/180)
)
camera = ax.scene.camera_controls[]
map(events(ax.scene).keyboardbutton) do event
event.action == Keyboard.release && return false
# Get camera information
eyepos = camera.eyeposition[]
lookat = camera.lookat[]
up = camera.upvector[]
# camera coordinate system
dir = eyepos - lookat
dir_norm = normalize(dir)
right = normalize(cross(dir, up))
# compute combined rotation
rotation = Makie.Quaternion{Float32}(0, 0, 0, 1)
for key in events(ax.scene).keyboardstate
if key in (pan_left, pan_right)
rotation *= qrotation(up, step_size * ((pan_left == key) - (pan_right == key)))
end
if key in (tilt_down, tilt_up)
rotation *= qrotation(right, step_size * ((tilt_down == key) - (tilt_up == key)))
end
if key in (roll_clockwise, roll_counterclockwise)
rotation *= qrotation(dir_norm,
step_size * ((roll_clockwise == key) - (roll_counterclockwise == key))
)
end
end
# Set values, update camera
camera.eyeposition[] = lookat + rotation * dir
camera.upvector[] = normalize(rotation * up)
update_cam!(ax.scene, camera)
return false
end
end
fig, ax, p = scatter(rand(Point3f0, 10))
controls = key_controls!(ax)
fig
I also started a pull request for a more controllable/adjustable camera:
Nice job, I did use the version in the PR with pretty good results. But now that it’s merged into 0.15.0, how do I continue to use it - the keyboard controls don’t seem to be active as default and mesh no longer takes a camera attribute?
It should be the default in an LScene
. If not you can try calling Camera3D(lscene.scene)
(or cam3d!
or cam3d_cad!
).
Tried the example at https://makie.juliaplots.org/stable/makielayout/lscene.html with GLMakie rather than WGLMakie, but no keyboard controls working in the Makie window (mouse works as before).
My env:
(annotell) pkg> st
Status ~/proj/julia/annotell/Project.toml
[cd3eb016] HTTP v0.9.12
[682c06a0] JSON v0.21.1
[ee78f7c6] Makie v0.15.0
(annotell) pkg>
Trying to call Camera3D(lscene.scene) fails:
julia> Camera3D(lscene.scene)
ERROR: MethodError: no method matching Camera3D(::Scene)
ping @ffreyer
I don’t know what’s wrong. 0.15 has Camera3D, with GLMakie you should be getting keyboard controls unless you explicitly use old_cam3d!
etc…