1use crate::core::{
25 algebra::{Unit, UnitQuaternion, Vector2, Vector3, Vector4},
26 log::Log,
27 math::lerpf,
28 num_traits::AsPrimitive,
29 reflect::prelude::*,
30 visitor::prelude::*,
31 ImmutableString,
32};
33use std::any::TypeId;
34use std::{
35 any,
36 any::Any,
37 fmt::{Debug, Display, Formatter},
38};
39
40#[derive(Visit, Reflect, Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]
42pub enum ValueType {
43 Bool,
45 #[default]
47 F32,
48 F64,
50 U64,
52 I64,
54 U32,
56 I32,
58 U16,
60 I16,
62 U8,
64 I8,
66
67 Vector2Bool,
69 Vector2F32,
71 Vector2F64,
73 Vector2U64,
75 Vector2I64,
77 Vector2U32,
79 Vector2I32,
81 Vector2U16,
83 Vector2I16,
85 Vector2U8,
87 Vector2I8,
89
90 Vector3Bool,
92 Vector3F32,
94 Vector3F64,
96 Vector3U64,
98 Vector3I64,
100 Vector3U32,
102 Vector3I32,
104 Vector3U16,
106 Vector3I16,
108 Vector3U8,
110 Vector3I8,
112
113 Vector4Bool,
115 Vector4F32,
117 Vector4F64,
119 Vector4U64,
121 Vector4I64,
123 Vector4U32,
125 Vector4I32,
127 Vector4U16,
129 Vector4I16,
131 Vector4U8,
133 Vector4I8,
135
136 UnitQuaternionF32,
138 UnitQuaternionF64,
140}
141
142impl ValueType {
143 pub fn into_type_id(self) -> TypeId {
145 match self {
146 ValueType::Bool => TypeId::of::<bool>(),
147 ValueType::F32 => TypeId::of::<f32>(),
148 ValueType::F64 => TypeId::of::<f64>(),
149 ValueType::U64 => TypeId::of::<u64>(),
150 ValueType::I64 => TypeId::of::<i64>(),
151 ValueType::U32 => TypeId::of::<u32>(),
152 ValueType::I32 => TypeId::of::<i32>(),
153 ValueType::U16 => TypeId::of::<u16>(),
154 ValueType::I16 => TypeId::of::<i16>(),
155 ValueType::U8 => TypeId::of::<u8>(),
156 ValueType::I8 => TypeId::of::<i8>(),
157 ValueType::Vector2Bool => TypeId::of::<Vector2<bool>>(),
158 ValueType::Vector2F32 => TypeId::of::<Vector2<f32>>(),
159 ValueType::Vector2F64 => TypeId::of::<Vector2<f64>>(),
160 ValueType::Vector2U64 => TypeId::of::<Vector2<u64>>(),
161 ValueType::Vector2I64 => TypeId::of::<Vector2<i64>>(),
162 ValueType::Vector2U32 => TypeId::of::<Vector2<u32>>(),
163 ValueType::Vector2I32 => TypeId::of::<Vector2<i32>>(),
164 ValueType::Vector2U16 => TypeId::of::<Vector2<u16>>(),
165 ValueType::Vector2I16 => TypeId::of::<Vector2<i16>>(),
166 ValueType::Vector2U8 => TypeId::of::<Vector2<u8>>(),
167 ValueType::Vector2I8 => TypeId::of::<Vector2<i8>>(),
168 ValueType::Vector3Bool => TypeId::of::<Vector3<bool>>(),
169 ValueType::Vector3F32 => TypeId::of::<Vector3<f32>>(),
170 ValueType::Vector3F64 => TypeId::of::<Vector3<f64>>(),
171 ValueType::Vector3U64 => TypeId::of::<Vector3<u64>>(),
172 ValueType::Vector3I64 => TypeId::of::<Vector3<i64>>(),
173 ValueType::Vector3U32 => TypeId::of::<Vector3<u32>>(),
174 ValueType::Vector3I32 => TypeId::of::<Vector3<i32>>(),
175 ValueType::Vector3U16 => TypeId::of::<Vector3<u16>>(),
176 ValueType::Vector3I16 => TypeId::of::<Vector3<i16>>(),
177 ValueType::Vector3U8 => TypeId::of::<Vector3<u8>>(),
178 ValueType::Vector3I8 => TypeId::of::<Vector3<i8>>(),
179 ValueType::Vector4Bool => TypeId::of::<Vector4<bool>>(),
180 ValueType::Vector4F32 => TypeId::of::<Vector4<f32>>(),
181 ValueType::Vector4F64 => TypeId::of::<Vector4<f64>>(),
182 ValueType::Vector4U64 => TypeId::of::<Vector4<u64>>(),
183 ValueType::Vector4I64 => TypeId::of::<Vector4<i64>>(),
184 ValueType::Vector4U32 => TypeId::of::<Vector4<u32>>(),
185 ValueType::Vector4I32 => TypeId::of::<Vector4<i32>>(),
186 ValueType::Vector4U16 => TypeId::of::<Vector4<u16>>(),
187 ValueType::Vector4I16 => TypeId::of::<Vector4<i16>>(),
188 ValueType::Vector4U8 => TypeId::of::<Vector4<u8>>(),
189 ValueType::Vector4I8 => TypeId::of::<Vector4<i8>>(),
190 ValueType::UnitQuaternionF32 => TypeId::of::<UnitQuaternion<f32>>(),
191 ValueType::UnitQuaternionF64 => TypeId::of::<UnitQuaternion<f64>>(),
192 }
193 }
194}
195
196#[derive(Clone, Debug, PartialEq)]
200pub enum TrackValue {
201 Real(f32),
203
204 Vector2(Vector2<f32>),
206
207 Vector3(Vector3<f32>),
209
210 Vector4(Vector4<f32>),
212
213 UnitQuaternion(UnitQuaternion<f32>),
215}
216
217impl TrackValue {
218 pub fn blend_with(&mut self, other: &Self, weight: f32) {
221 match (self, other) {
222 (Self::Real(a), Self::Real(b)) => *a = lerpf(*a, *b, weight),
223 (Self::Vector2(a), Self::Vector2(b)) => *a = a.lerp(b, weight),
224 (Self::Vector3(a), Self::Vector3(b)) => *a = a.lerp(b, weight),
225 (Self::Vector4(a), Self::Vector4(b)) => *a = a.lerp(b, weight),
226 (Self::UnitQuaternion(a), Self::UnitQuaternion(b)) => *a = nlerp(*a, b, weight),
227 _ => (),
228 }
229 }
230
231 pub fn apply_to_any(&self, any: &mut dyn Any, value_type: ValueType) -> bool {
234 fn convert_vec2<T>(vec2: &Vector2<f32>) -> Vector2<T>
235 where
236 f32: AsPrimitive<T>,
237 T: Copy + 'static,
238 {
239 Vector2::new(vec2.x.as_(), vec2.y.as_())
240 }
241
242 fn convert_vec3<T>(vec3: &Vector3<f32>) -> Vector3<T>
243 where
244 f32: AsPrimitive<T>,
245 T: Copy + 'static,
246 {
247 Vector3::new(vec3.x.as_(), vec3.y.as_(), vec3.z.as_())
248 }
249
250 fn convert_vec4<T>(vec4: &Vector4<f32>) -> Vector4<T>
251 where
252 f32: AsPrimitive<T>,
253 T: Copy + 'static,
254 {
255 Vector4::new(vec4.x.as_(), vec4.y.as_(), vec4.z.as_(), vec4.w.as_())
256 }
257
258 fn set<T>(any: &mut dyn Any, value: T) -> bool
259 where
260 T: Any + Copy,
261 {
262 if let Some(any_val) = any.downcast_mut::<T>() {
263 *any_val = value;
264 true
265 } else {
266 Log::err(format!(
267 "Animation: unable to set value of type {}! Types mismatch!",
268 any::type_name::<T>()
269 ));
270 false
271 }
272 }
273
274 match self {
275 TrackValue::Real(real) => match value_type {
276 ValueType::Bool => set(any, real.ne(&0.0)),
277 ValueType::F32 => set(any, *real),
278 ValueType::F64 => set(any, *real as f64),
279 ValueType::U64 => set(any, *real as u64),
280 ValueType::I64 => set(any, *real as i64),
281 ValueType::U32 => set(any, *real as u32),
282 ValueType::I32 => set(any, *real as i32),
283 ValueType::U16 => set(any, *real as u16),
284 ValueType::I16 => set(any, *real as i16),
285 ValueType::U8 => set(any, *real as u8),
286 ValueType::I8 => set(any, *real as i8),
287 _ => false,
288 },
289 TrackValue::Vector2(vec2) => match value_type {
290 ValueType::Vector2Bool => set(any, Vector2::new(vec2.x.ne(&0.0), vec2.y.ne(&0.0))),
291 ValueType::Vector2F32 => set(any, *vec2),
292 ValueType::Vector2F64 => set(any, convert_vec2::<f64>(vec2)),
293 ValueType::Vector2U64 => set(any, convert_vec2::<u64>(vec2)),
294 ValueType::Vector2I64 => set(any, convert_vec2::<i64>(vec2)),
295 ValueType::Vector2U32 => set(any, convert_vec2::<u32>(vec2)),
296 ValueType::Vector2I32 => set(any, convert_vec2::<i32>(vec2)),
297 ValueType::Vector2U16 => set(any, convert_vec2::<u16>(vec2)),
298 ValueType::Vector2I16 => set(any, convert_vec2::<i16>(vec2)),
299 ValueType::Vector2U8 => set(any, convert_vec2::<u8>(vec2)),
300 ValueType::Vector2I8 => set(any, convert_vec2::<i8>(vec2)),
301 _ => false,
302 },
303 TrackValue::Vector3(vec3) => match value_type {
304 ValueType::Vector3Bool => set(
305 any,
306 Vector3::new(vec3.x.ne(&0.0), vec3.y.ne(&0.0), vec3.z.ne(&0.0)),
307 ),
308 ValueType::Vector3F32 => set(any, *vec3),
309 ValueType::Vector3F64 => set(any, convert_vec3::<f64>(vec3)),
310 ValueType::Vector3U64 => set(any, convert_vec3::<u64>(vec3)),
311 ValueType::Vector3I64 => set(any, convert_vec3::<i64>(vec3)),
312 ValueType::Vector3U32 => set(any, convert_vec3::<u32>(vec3)),
313 ValueType::Vector3I32 => set(any, convert_vec3::<i32>(vec3)),
314 ValueType::Vector3U16 => set(any, convert_vec3::<u16>(vec3)),
315 ValueType::Vector3I16 => set(any, convert_vec3::<i16>(vec3)),
316 ValueType::Vector3U8 => set(any, convert_vec3::<u8>(vec3)),
317 ValueType::Vector3I8 => set(any, convert_vec3::<i8>(vec3)),
318 _ => false,
319 },
320 TrackValue::Vector4(vec4) => match value_type {
321 ValueType::Vector4Bool => set(
322 any,
323 Vector4::new(
324 vec4.x.ne(&0.0),
325 vec4.y.ne(&0.0),
326 vec4.z.ne(&0.0),
327 vec4.w.ne(&0.0),
328 ),
329 ),
330 ValueType::Vector4F32 => set(any, *vec4),
331 ValueType::Vector4F64 => set(any, convert_vec4::<f64>(vec4)),
332 ValueType::Vector4U64 => set(any, convert_vec4::<u64>(vec4)),
333 ValueType::Vector4I64 => set(any, convert_vec4::<i64>(vec4)),
334 ValueType::Vector4U32 => set(any, convert_vec4::<u32>(vec4)),
335 ValueType::Vector4I32 => set(any, convert_vec4::<i32>(vec4)),
336 ValueType::Vector4U16 => set(any, convert_vec4::<u16>(vec4)),
337 ValueType::Vector4I16 => set(any, convert_vec4::<i16>(vec4)),
338 ValueType::Vector4U8 => set(any, convert_vec4::<u8>(vec4)),
339 ValueType::Vector4I8 => set(any, convert_vec4::<i8>(vec4)),
340 _ => false,
341 },
342 TrackValue::UnitQuaternion(quat) => match value_type {
343 ValueType::UnitQuaternionF32 => set(any, *quat),
344 ValueType::UnitQuaternionF64 => set(any, quat.cast::<f64>()),
345 _ => false,
346 },
347 }
348 }
349}
350
351#[derive(Default, Clone, Visit, Reflect, Debug, PartialEq, Eq)]
356pub enum ValueBinding {
357 #[default]
359 Position,
360 Scale,
362 Rotation,
364 Property {
366 name: ImmutableString,
368 value_type: ValueType,
370 },
371}
372
373impl Display for ValueBinding {
374 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
375 match self {
376 ValueBinding::Position => write!(f, "Position"),
377 ValueBinding::Scale => write!(f, "Scale"),
378 ValueBinding::Rotation => write!(f, "Rotation"),
379 ValueBinding::Property { name, .. } => write!(f, "{name}"),
380 }
381 }
382}
383
384#[derive(Clone, Debug, PartialEq)]
386pub struct BoundValue {
387 pub binding: ValueBinding,
389 pub value: TrackValue,
391}
392
393impl BoundValue {
394 pub fn blend_with(&mut self, other: &Self, weight: f32) {
397 assert_eq!(self.binding, other.binding);
398 self.value.blend_with(&other.value, weight);
399 }
400
401 pub fn apply_to_object(
403 &self,
404 object: &mut dyn Reflect,
405 property_path: &str,
406 value_type: ValueType,
407 ) {
408 object.as_reflect_mut(&mut |object_ref| {
409 object_ref.resolve_path_mut(property_path, &mut |result| match result {
410 Ok(property) => {
411 let mut applied = false;
412 property.as_any_mut(&mut |any| {
413 applied = self.value.apply_to_any(any, value_type);
414 });
415 if applied {
416 property.as_inheritable_variable_mut(&mut |var| {
417 if let Some(var) = var {
418 var.mark_modified();
419 }
420 });
421 }
422 }
423 Err(err) => {
424 Log::err(format!(
425 "Failed to set property {property_path}! Reason: {err:?}"
426 ));
427 }
428 });
429 })
430 }
431}
432
433#[derive(Clone, Debug, Default, PartialEq)]
435pub struct BoundValueCollection {
436 pub values: Vec<BoundValue>,
438}
439
440impl BoundValueCollection {
441 pub fn blend_with(&mut self, other: &Self, weight: f32) {
444 for value in self.values.iter_mut() {
445 if let Some(other_value) = other.values.iter().find(|v| v.binding == value.binding) {
446 value.blend_with(other_value, weight);
447 }
448 }
449 }
450}
451
452pub fn nlerp(mut a: UnitQuaternion<f32>, b: &UnitQuaternion<f32>, w: f32) -> UnitQuaternion<f32> {
455 if a.dot(b) < 0.0 {
456 a = negate_unit_quaternion(&a)
457 }
458 a.nlerp(b, w)
459}
460
461pub fn negate_unit_quaternion(a: &UnitQuaternion<f32>) -> UnitQuaternion<f32> {
463 Unit::new_unchecked(-a.as_ref())
464}
465
466#[cfg(test)]
467mod test {
468 use crate::value::{BoundValue, TrackValue, ValueBinding, ValueType};
469 use fyrox_core::{reflect::prelude::*, variable::InheritableVariable};
470
471 #[derive(Reflect, Debug, Clone, PartialEq)]
472 struct OtherStruct {
473 field: u32,
474 inheritable_variable: InheritableVariable<u32>,
475 }
476
477 impl Default for OtherStruct {
478 fn default() -> Self {
479 Self {
480 field: 0,
481 inheritable_variable: InheritableVariable::new_non_modified(0),
482 }
483 }
484 }
485
486 #[derive(Default, Reflect, Clone, Debug, PartialEq)]
487 struct MyStruct {
488 some_bool: bool,
489 some_property: f32,
490 other_struct: OtherStruct,
491 }
492
493 #[test]
494 fn test_apply_value() {
495 let some_bool_value = BoundValue {
496 binding: ValueBinding::Property {
497 name: "some_bool".into(),
498 value_type: ValueType::Bool,
499 },
500 value: TrackValue::Real(1.0),
501 };
502
503 let some_property_value = BoundValue {
504 binding: ValueBinding::Property {
505 name: "some_property".into(),
506 value_type: ValueType::F32,
507 },
508 value: TrackValue::Real(123.0),
509 };
510
511 let field_value = BoundValue {
512 binding: ValueBinding::Property {
513 name: "field".into(),
514 value_type: ValueType::U32,
515 },
516 value: TrackValue::Real(123.0),
517 };
518
519 let inheritable_variable_value = BoundValue {
520 binding: ValueBinding::Property {
521 name: "inheritable_variable".into(),
522 value_type: ValueType::U32,
523 },
524 value: TrackValue::Real(123.0),
525 };
526
527 let mut object = MyStruct::default();
528
529 some_bool_value.apply_to_object(&mut object, "some_bool", ValueType::Bool);
530 assert!(object.some_bool);
531
532 some_property_value.apply_to_object(&mut object, "some_property", ValueType::F32);
533 assert_eq!(object.some_property, 123.0);
534
535 field_value.apply_to_object(&mut object, "other_struct.field", ValueType::U32);
536 assert_eq!(object.other_struct.field, 123);
537
538 assert!(!object.other_struct.inheritable_variable.is_modified());
539 inheritable_variable_value.apply_to_object(
540 &mut object,
541 "other_struct.inheritable_variable",
542 ValueType::U32,
543 );
544 assert_eq!(object.other_struct.field, 123);
545 assert!(object.other_struct.inheritable_variable.is_modified());
546 }
547}