1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
|
import math
import os
import time
from pathlib import Path
from typing import Any
import f3d
TEST_DATA_DIR = Path(__file__).parent.parent.parent.parent.parent / "testing/data"
def main():
model_path = TEST_DATA_DIR / "suzanne.obj"
options: dict[str, Any] = {
"scene.up_direction": "+Y",
"render.effect.tone_mapping": True,
"render.effect.ambient_occlusion": True,
"render.effect.translucency_support": True,
"render.effect.antialiasing.enable": True,
}
anim_fps = 30
anim_duration = 4
orbit_count = 2
try:
rows, cols = os.get_terminal_size()
except OSError:
rows, cols = 40, 20
# setup offscreen engine
engine = f3d.Engine.create(offscreen=True)
engine.options.update(options)
engine.scene.add(model_path)
engine.window.size = rows, cols * 2
# fit view to loaded model and grab computed camera position
engine.window.camera.reset_to_bounds()
x0, y0, z0 = engine.window.camera.position
r = math.sqrt(x0**2 + z0**2)
# loop to move the camera and render frames
for t in realtime_animation_timesteps(anim_fps, anim_duration):
# set camera using polar coordinates on XZ plane, and original Y altitude
a = (t / anim_duration * orbit_count) * 2 * math.pi
engine.window.camera.position = math.sin(a) * r, y0, math.cos(a) * r
engine.window.camera.view_up = 0, 1, 0
# render
image = engine.window.render_to_image(no_background=True)
print(image.to_terminal_text(), end="")
print()
def realtime_animation_timesteps(fps: float, duration: float):
"""Generate times at `fps`frame/s accounting for actual frame computation time."""
target_frame_duration = 1.0 / fps
start_time = time.time()
end_time = start_time + duration
while time.time() < end_time:
frame_start_time = time.time()
yield frame_start_time - start_time
actual_frame_duration = time.time() - frame_start_time
time.sleep(max(target_frame_duration - actual_frame_duration, 0))
if __name__ == "__main__":
main()
|