Skip to content

Commit fb118ce

Browse files
committed
add live looped rendering
1 parent 017f80a commit fb118ce

File tree

3 files changed

+48
-6
lines changed

3 files changed

+48
-6
lines changed

docs/src/examples/pendulum.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ end
220220
model = complete(model)
221221
ssys = structural_simplify(IRSystem(model))
222222
223-
prob = ODEProblem(ssys, [model.shoulder_joint.phi => 0.0, model.elbow_joint.phi => 0.1], (0, 12))
223+
prob = ODEProblem(ssys, [model.shoulder_joint.phi => 0.0, model.elbow_joint.phi => 0.1], (0, 10))
224224
sol = solve(prob, Rodas4())
225225
plot(sol, layout=4)
226226
```

ext/Render.jl

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
module Render
22
using Makie
33
using Multibody
4-
import Multibody: render, render!, encode, decode, get_rot, get_trans, get_frame
4+
import Multibody: render, render!, loop_render, encode, decode, get_rot, get_trans, get_frame
55
using Rotations
66
using LinearAlgebra
77
using ModelingToolkit
8-
export render
8+
export render, loop_render
99
using MeshIO, FileIO
1010
using StaticArrays
1111

@@ -130,6 +130,7 @@ function render(model, sol,
130130
show_axis = false,
131131
timescale = 1.0,
132132
traces = nothing,
133+
display = false,
133134
kwargs...
134135
)
135136
scene, fig = default_scene(x,y,z; lookat,up,show_axis)
@@ -150,9 +151,25 @@ function render(model, sol,
150151
end
151152
end
152153

153-
fn = record(fig, filename, timevec; framerate) do time
154-
t[] = time/timescale
154+
if display
155+
Base.display(fig)
156+
sleep(2)
157+
fnt = @async begin
158+
record(fig, filename, timevec; framerate) do time
159+
if time == timevec[1]
160+
Base.display(fig)
161+
end
162+
t[] = time/timescale
163+
sleep(1/framerate)
164+
end
165+
end
166+
fn = fetch(fnt)
167+
else
168+
fn = record(fig, filename, timevec; framerate) do time
169+
t[] = time/timescale
170+
end
155171
end
172+
156173
fn, scene, fig
157174
end
158175

@@ -186,6 +203,21 @@ function render(model, sol, time::Real;
186203
fig, t
187204
end
188205

206+
function Multibody.loop_render(model, sol; timescale = 1.0, framerate = 30, kwargs...)
207+
fig, t = render(model, sol, sol.t[1]; kwargs...)
208+
sleeptime = 1/framerate
209+
timevec = range(sol.t[1], sol.t[end]*timescale, step=sleeptime)
210+
display(fig)
211+
@async begin
212+
for i = 1:5
213+
for ti in timevec
214+
execution_time = @elapsed t[] = ti
215+
sleep(sleeptime - execution_time)
216+
end
217+
end
218+
end
219+
end
220+
189221
"""
190222
Internal function: Recursively render all subsystem components of a multibody system. If a particular component returns `true` from its `render!` method, indicating that the component performaed rendering, the recursion stops.
191223
"""

src/Multibody.jl

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export render, render!
1212

1313
"""
1414
scene, time = render(model, sol, t::Real; framerate = 30, traces = [])
15-
path = render(model, sol, timevec = range(sol.t[1], sol.t[end], step = 1 / framerate); framerate = 30, timescale=1)
15+
path = render(model, sol, timevec = range(sol.t[1], sol.t[end], step = 1 / framerate); framerate = 30, timescale=1, display=false)
1616
1717
Create a 3D animation of a multibody system
1818
@@ -33,9 +33,19 @@ The following keyword arguments are available to control the camera pose:
3333
- `z = 2`
3434
- `lookat = [0,0,0]`: a three-vector of coordinates indicating the point at which the camera looks.
3535
- `up = [0,1,0]`: A vector indicating the direction that is up.
36+
- `display`: if `true`, the figure will be displayed during the recording process and time will advance in real-time. This allows the user to manipulate the camera options using the mouse during the recording.
37+
38+
See also [`loop_render`](@ref)
3639
"""
3740
function render end
3841

42+
"""
43+
loop_render(model, sol; framerate = 30, timescale = 1, kwargs...)
44+
45+
Similar to the method of [`render`](@ref) that produces an animation, but instead opens an interactive window where the time is automatically advanced in real time. This allows the user to manually manipulate the camera using the mouse is a live animation.
46+
"""
47+
function loop_render end
48+
3949
"""
4050
did_render::Bool = render!(scene, ::typeof(ComponentConstructor), sys, sol, t)
4151

0 commit comments

Comments
 (0)