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