From 85fc54f4f9a7dfd36798fbd21844b3af18c81efd Mon Sep 17 00:00:00 2001 From: Manuel Brea Date: Fri, 15 Nov 2024 12:12:45 +0000 Subject: [PATCH] Add sample_clamped method to animation curves, returning Boxed values --- crates/bevy_animation/src/animation_curves.rs | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/crates/bevy_animation/src/animation_curves.rs b/crates/bevy_animation/src/animation_curves.rs index fbe555ca3b..89a262bf7f 100644 --- a/crates/bevy_animation/src/animation_curves.rs +++ b/crates/bevy_animation/src/animation_curves.rs @@ -81,6 +81,7 @@ use core::{ fmt::{self, Debug, Formatter}, marker::PhantomData, }; +use std::any::Any; use bevy_ecs::{component::Component, world::Mut}; use bevy_math::{ @@ -209,6 +210,21 @@ where phantom: PhantomData

, } +pub struct AnimatableCurveSample { + pub component_type: TypeId, + pub property_type: TypeId, + pub get_mut_boxed: fn(&mut dyn Any) -> Option<&mut dyn Reflect>, + pub value: Box, +} + +fn get_mut_boxed(component: &mut dyn Any) -> Option<&mut dyn Reflect> { + if let Some(component) = component.downcast_mut::() { + P::get_mut(component).map(|p| p.as_reflect_mut()) + } else { + panic!("Type mismatch") + } +} + impl AnimatableCurve where P: AnimatableProperty, @@ -294,6 +310,17 @@ where }); Ok(()) } + + fn sample_clamped(&self, t: f32) -> Box { + let value = self.curve.sample_clamped(t); + + Box::new(AnimatableCurveSample { + component_type: TypeId::of::(), + property_type: TypeId::of::(), + get_mut_boxed: get_mut_boxed::

, + value: Box::new(value), + }) + } } impl

AnimationCurveEvaluator for AnimatableCurveEvaluator

@@ -353,6 +380,14 @@ pub struct TranslationCurveEvaluator { evaluator: BasicAnimationCurveEvaluator, } +/// Type indicating that the sampled value from an animation curve is coming from a +/// [`TranslationCurve`]. +/// +/// You shouldn't need to interact with this type unless you're manually evaluating animation +/// curves. +#[derive(Reflect)] +pub struct TranslationCurveSample(Vec3); + impl AnimationCurve for TranslationCurve where C: AnimationCompatibleCurve, @@ -396,6 +431,12 @@ where }); Ok(()) } + + fn sample_clamped(&self, t: f32) -> Box { + let value = self.0.sample_clamped(t); + + Box::new(TranslationCurveSample(value)) + } } impl AnimationCurveEvaluator for TranslationCurveEvaluator { @@ -450,6 +491,14 @@ pub struct RotationCurveEvaluator { evaluator: BasicAnimationCurveEvaluator, } +/// Type indicating that the sampled value from an animation curve is coming from a +/// [`RotationCurve`]. +/// +/// You shouldn't need to interact with this type unless you're manually evaluating animation +/// curves. +#[derive(Reflect)] +pub struct RotationCurveSample(Quat); + impl AnimationCurve for RotationCurve where C: AnimationCompatibleCurve, @@ -493,6 +542,12 @@ where }); Ok(()) } + + fn sample_clamped(&self, t: f32) -> Box { + let value = self.0.sample_clamped(t); + + Box::new(RotationCurveSample(value)) + } } impl AnimationCurveEvaluator for RotationCurveEvaluator { @@ -547,6 +602,14 @@ pub struct ScaleCurveEvaluator { evaluator: BasicAnimationCurveEvaluator, } +/// Type indicating that the sampled value from an animation curve is coming from a +/// [`ScaleCurve`]. +/// +/// You shouldn't need to interact with this type unless you're manually evaluating animation +/// curves. +#[derive(Reflect)] +pub struct ScaleCurveSample(Vec3); + impl AnimationCurve for ScaleCurve where C: AnimationCompatibleCurve, @@ -590,6 +653,12 @@ where }); Ok(()) } + + fn sample_clamped(&self, t: f32) -> Box { + let value = self.0.sample_clamped(t); + + Box::new(ScaleCurveSample(value)) + } } impl AnimationCurveEvaluator for ScaleCurveEvaluator { @@ -671,6 +740,14 @@ struct WeightsCurveEvaluator { morph_target_count: Option, } +/// Type indicating that the sampled value from an animation curve is coming from a +/// [`ScaleCurve`]. +/// +/// You shouldn't need to interact with this type unless you're manually evaluating animation +/// curves. +#[derive(Reflect)] +pub struct WeightsCurveSample(Vec); + impl AnimationCurve for WeightsCurve where C: IterableCurve + Debug + Clone + Reflectable, @@ -722,6 +799,12 @@ where .push((weight, graph_node)); Ok(()) } + + fn sample_clamped(&self, t: f32) -> Box { + let value = self.0.sample_iter_clamped(t); + + Box::new(WeightsCurveSample(value.collect())) + } } impl WeightsCurveEvaluator { @@ -1010,6 +1093,8 @@ pub trait AnimationCurve: Reflect + Debug + Send + Sync { weight: f32, graph_node: AnimationNodeIndex, ) -> Result<(), AnimationEvaluationError>; + + fn sample_clamped(&self, t: f32) -> Box; } /// A low-level trait for use in [`crate::VariableCurve`] that provides fine