Loading...
Searching...
No Matches
AnimationPlayer.hpp
1#pragma once
2#include <halp/controls.hpp>
3#include <halp/meta.hpp>
4
5#include <ossia/dataflow/geometry_port.hpp>
6
7#include <cstdint>
8#include <memory>
9#include <unordered_map>
10
11namespace Threedim
12{
13
14// Samples an incoming scene's animation channels at a user-provided time and
15// emits a scene_spec whose animated scene_nodes carry updated scene_transform
16// payloads, or whose skeletons carry updated bone poses. Passthrough when the
17// input scene has no animations.
18//
19// animation_channel.target_node_id refers to a scene_node::id; target_path is one
20// of translation, rotation, scale, weights, custom; `times` and `values` hold the
21// keyframes and `interpolation` is step, linear or cubic_spline.
22//
23// For TRS channels the first scene_transform payload among the matching node's
24// children is overridden -- the convention GltfParser and FbxParser follow, since
25// they prepend one per node. Subtrees touching no animated node are shared as-is
26// by shared_ptr, so downstream identity caches stay hot outside the animated
27// branch, and materials, skeletons, cameras and environment pass through by
28// identity.
29//
30// Passthrough for now: morph-target weights, custom paths, and skeletal joint
31// tracks targeting joints inside a skeleton_component rather than scene_node ids.
33{
34public:
35 halp_meta(name, "Animation Player")
36 halp_meta(category, "Visuals/3D/Scene")
37 halp_meta(c_name, "animation_player")
38 halp_meta(authors, "ossia team")
39 halp_meta(
40 manual_url,
41 "https://ossia.io/score-docs/processes/animation-player.html")
42 halp_meta(uuid, "2b4d7e8c-3a5f-4b9d-91c6-8d2e0f3a7b5e")
43
44 struct ins
45 {
46 struct
47 {
48 halp_meta(name, "Scene In");
49 ossia::scene_spec scene;
50 uint8_t dirty{0};
51 } scene_in;
52
53 halp::hslider_f32<"Time", halp::range{0., 3600., 0.}> time;
54 halp::hslider_f32<"Speed", halp::range{-4., 4., 1.}> speed;
55 halp::toggle<"Loop"> loop;
56 // When unset, 0 = first animation_component, 1 = second, …. -1 =
57 // blend all (sum of all channels — useful when animations target
58 // disjoint node sets, which is common for glTF scenes). Clamped to
59 // the number of components at sample time.
60 halp::spinbox_i32<"Clip index", halp::irange{-1, 32, -1}> clip_index;
61 } inputs;
62
63 struct outs
64 {
65 struct
66 {
67 halp_meta(name, "Scene Out");
68 ossia::scene_spec scene;
69 uint8_t dirty{0};
70 } scene_out;
71 } outputs;
72
73 void operator()();
74
75 std::shared_ptr<const ossia::scene_state> m_cached_state;
76 int64_t m_version_counter{0};
77
78 // Last value seen on the Time inlet. Used solely to detect whether the
79 // user is actively driving Time (value changed) vs. leaving it constant
80 // so the Speed control should auto-advance. NEVER holds the advanced
81 // playback position (that lives in m_playback_time).
82 float m_prev_time{0.f};
83 // Auto-advance accumulator for the Speed control. Integrated by
84 // speed*dt every call while Time is held constant; resynced to the Time
85 // inlet whenever the user actually moves it.
86 float m_playback_time{0.f};
87};
88
89}
Definition AnimationPlayer.hpp:33
Definition AnimationPlayer.hpp:45
Definition AnimationPlayer.hpp:64