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(description, "Sample scene animation channels at a chosen time to update animated transforms.")
39 halp_meta(authors, "ossia team")
40 halp_meta(
41 manual_url,
42 "https://ossia.io/score-docs/processes/animation-player.html")
43 halp_meta(uuid, "2b4d7e8c-3a5f-4b9d-91c6-8d2e0f3a7b5e")
44
45 struct ins
46 {
47 struct
48 {
49 halp_meta(name, "Scene In");
50 ossia::scene_spec scene;
51 uint8_t dirty{0};
52 } scene_in;
53
54 halp::hslider_f32<"Time", halp::range{0., 3600., 0.}> time;
55 halp::hslider_f32<"Speed", halp::range{-4., 4., 1.}> speed;
56 halp::toggle<"Loop"> loop;
57 // When unset, 0 = first animation_component, 1 = second, …. -1 =
58 // blend all (sum of all channels — useful when animations target
59 // disjoint node sets, which is common for glTF scenes). Clamped to
60 // the number of components at sample time.
61 halp::spinbox_i32<"Clip index", halp::irange{-1, 32, -1}> clip_index;
62 } inputs;
63
64 struct outs
65 {
66 struct
67 {
68 halp_meta(name, "Scene Out");
69 ossia::scene_spec scene;
70 uint8_t dirty{0};
71 } scene_out;
72 } outputs;
73
74 void operator()();
75
76 std::shared_ptr<const ossia::scene_state> m_cached_state;
77 int64_t m_version_counter{0};
78
79 // Last value seen on the Time inlet. Used solely to detect whether the
80 // user is actively driving Time (value changed) vs. leaving it constant
81 // so the Speed control should auto-advance. NEVER holds the advanced
82 // playback position (that lives in m_playback_time).
83 float m_prev_time{0.f};
84 // Auto-advance accumulator for the Speed control. Integrated by
85 // speed*dt every call while Time is held constant; resynced to the Time
86 // inlet whenever the user actually moves it.
87 float m_playback_time{0.f};
88};
89
90}
Definition AnimationPlayer.hpp:33
Definition AnimationPlayer.hpp:46
Definition AnimationPlayer.hpp:65