rdeits / MeshCat.jl

WebGL-based 3D visualizer in Julia
MIT License
235 stars 43 forks source link

How to create an animation where the object being shown changes over time #113

Closed JohnEdChristensen closed 1 year ago

JohnEdChristensen commented 5 years ago

Is there no documentation or am I just missing something? I would like to create an animation that changes what object is being displayed over time. The animation demo wasn't helpful for this case.

tkoolen commented 5 years ago

You'll need to add all the objects you'll ever use to the visualizer first using setobject!, and then I think you should just be able to use setvisible! at the desired frames.

JohnEdChristensen commented 5 years ago

When I do this:

setobject!(vis[:box1], 
    HyperRectangle(Vec(0., 0, 0), Vec(2, 0.1, 1)))
setobject!(vis[:box2], 
    HyperRectangle(Vec(0., 0, 0), Vec(0.1, 2, 1)))
setvisible!(vis[:box1],false)
setvisible!(vis[:box2],false)

anim = Animation()
atframe(anim, vis, 0) do frame
    setvisible!(vis[:box2],false)
    setvisible!(vis[:box1],true)
    settransform!(frame["/Cameras/default"], Translation(0., 0, 0))
end

atframe(anim, vis, 50) do frame
    setvisible!(vis[:box2],true)
    setvisible!(vis[:box1],false)
    settransform!(frame["/Cameras/default"], Translation(0., 0, 1))
end
atframe(anim, vis, 100) do frame
    setvisible!(vis[:box2],true)
    setvisible!(vis[:box1],true)
    settransform!(frame["/Cameras/default"], Translation(0., 1, 1))
end

setanimation!(vis, anim)

It shows both objects for the entire animation. if I setvisible! to false for both objects at frame 100 it doesn't show either object for the entire animation.

tkoolen commented 5 years ago

You should pass frame[:box1] as an argument to setvisible! instead of vis[:box1], but with that change it still doesn't work yet. It should be possible though, since https://threejs.org/docs/index.html#manual/en/introduction/Animation-system explicitly mentions visibility. Updated (and runnable):

using MeshCat
using CoordinateTransformations
using GeometryTypes: Vec, HyperRectangle

vis = Visualizer()
open(vis)

setobject!(vis[:box1], 
    HyperRectangle(Vec(0., 0, 0), Vec(2, 0.1, 1)))
setobject!(vis[:box2], 
    HyperRectangle(Vec(0., 0, 0), Vec(0.1, 2, 1)))
setvisible!(vis[:box1],false)
setvisible!(vis[:box2],false)

anim = Animation()
atframe(anim, vis, 0) do frame
    setvisible!(frame[:box2],false)
    setvisible!(frame[:box1],true)
end

atframe(anim, vis, 50) do frame
    setvisible!(frame[:box2],true)
    setvisible!(frame[:box1],false)
end
atframe(anim, vis, 100) do frame
    setvisible!(frame[:box2],true)
    setvisible!(frame[:box1],true)
end

setanimation!(vis, anim)
ferrolho commented 1 year ago

Closing this issue due to inactivity and because a proof of concept was provided above.