17#define POOLSTL_STD_SUPPLEMENT 1
18#include <poolstl/poolstl.hpp>
25void on_play_begin_impl(animation_component& comp)
27 if(comp.get_autoplay())
29 auto& player = comp.get_player();
30 player.blend_to(0, comp.get_animation());
38 APPLOG_TRACE(
"{}::{}", hpp::type_name_str(*
this), __func__);
39 auto& ev = ctx.get_cached<
events>();
42 ev.on_play_end.connect(sentinel_, -10,
this, &animation_system::on_play_end);
43 ev.on_pause.connect(sentinel_, 10,
this, &animation_system::on_pause);
44 ev.on_resume.connect(sentinel_, -10,
this, &animation_system::on_resume);
45 ev.on_skip_next_frame.connect(sentinel_, 10,
this, &animation_system::on_skip_next_frame);
52 APPLOG_TRACE(
"{}::{}", hpp::type_name_str(*
this), __func__);
68 APPLOG_TRACE(
"{}::{}", hpp::type_name_str(*
this), __func__);
74 [&](
auto e,
auto&& animation_comp)
76 on_play_begin_impl(animation_comp);
83 for(
auto entity : entities)
87 on_play_begin_impl(*animation_comp);
95 APPLOG_TRACE(
"{}::{}", hpp::type_name_str(*
this), __func__);
101 [&](
auto e,
auto&& animation_comp)
103 auto& player = animation_comp.get_player();
122 on_update(scn, step,
true);
125void animation_system::on_update(scene& scn,
delta_t dt,
bool force)
132 auto view = scn.registry->view<model_component, animation_component, transform_component>();
136 std::for_each(std::execution::par,
141 auto& animation_comp = view.get<animation_component>(entity);
142 auto& model_comp = view.get<model_component>(entity);
144 bool should_update_poses = true;
145 if(animation_comp.get_culling_mode() == animation_component::culling_mode::renderer_based)
147 if(!model_comp.was_used_last_frame())
149 should_update_poses = false;
153 auto& player = animation_comp.get_player();
156 auto speed = animation_comp.get_speed();
157 auto adjusted_dt = dt * speed;
159 bool updated = player.update_time(adjusted_dt,
force);
161 if(updated && should_update_poses)
163 auto& transform_comp = view.get<transform_component>(entity);
166 bool apply_root_motion = animation_comp.get_apply_root_motion();
169 model_comp.get_bind_pose(),
170 [&](const animation_pose::node_desc& desc,
171 const math::transform& transform,
172 const animation_pose::root_motion_result& motion_result)
174 auto armature = model_comp.get_armature_by_index(desc.index);
177 auto& armature_transform_comp = armature.template get<transform_component>();
179 bool processed_by_root_motion = false;
181 if(apply_root_motion && desc.index == motion_result.root_position_node_index)
183 armature_transform_comp.set_scale_local(transform.get_scale());
185 auto position_local = armature_transform_comp.get_position_local();
186 auto result_positon_local = math::lerp(position_local,
187 transform.get_position(),
188 motion_result.bone_position_weights);
189 armature_transform_comp.set_position_local(result_positon_local);
191 math::vec3 delta_translation_logical =
192 motion_result.root_transform_delta.get_translation();
196 auto scale_global = armature_transform_comp.get_scale_global();
197 delta_translation_logical *= scale_global;
200 auto result_move_local = math::lerp(math::zero<math::vec3>(),
201 delta_translation_logical,
202 motion_result.root_position_weights);
217 transform_comp.move_by_local(result_move_local);
219 processed_by_root_motion = true;
222 if(apply_root_motion && desc.index == motion_result.root_position_node_index)
224 armature_transform_comp.set_scale_local(transform.get_scale());
226 auto rotation_local = armature_transform_comp.get_rotation_local();
227 auto result_rotation_local = math::slerp(rotation_local,
228 transform.get_rotation(),
229 motion_result.bone_rotation_weight);
230 armature_transform_comp.set_rotation_local(result_rotation_local);
233 math::quat delta_rotation_logical =
234 motion_result.root_transform_delta.get_rotation();
237 auto result_rotate_local = math::slerp(math::identity<math::quat>(),
238 delta_rotation_logical,
239 motion_result.root_rotation_weight);
240 transform_comp.rotate_by_local(result_rotate_local);
242 processed_by_root_motion = true;
245 if(false == processed_by_root_motion)
247 armature_transform_comp.set_transform_local(transform);
258 APPLOG_WARNING(
"Cannot find armature with index {}", desc.index);
267 on_update(scn, dt,
false);
static void on_create_component(entt::registry &r, entt::entity e)
Called when the component is created.
void on_play_begin(hpp::span< const entt::handle > entities, delta_t dt)
auto init(rtti::context &ctx) -> bool
auto deinit(rtti::context &ctx) -> bool
static void on_destroy_component(entt::registry &r, entt::entity e)
Called when the component is destroyed.
std::chrono::duration< float > delta_t
#define APPLOG_TRACE(...)
#define APP_SCOPE_PERF(name)
Create a scoped performance timer that only accepts string literals.
Manages the entity-component-system (ECS) operations for the ACE framework.
auto get_scene() -> scene &
Gets the current scene.
static auto context() -> rtti::context &
hpp::event< void(rtti::context &)> on_play_begin
Represents a scene in the ACE framework, managing entities and their relationships.