1use std::ptr;
2
3use crate::error::Result;
4use crate::ffi;
5use crate::handle::ObjectHandle;
6use crate::types::{AnimatedValueInfo, AnimatedValueInterpolation};
7use crate::util::{parse_json, required_handle};
8
9fn animated_info(handle: &ObjectHandle, context: &'static str) -> Result<AnimatedValueInfo> {
10 parse_json(
11 unsafe { ffi::mdl_animated_value_info_json(handle.as_ptr()) },
13 context,
14 )
15}
16
17fn animated_clear(handle: &ObjectHandle) {
18 unsafe { ffi::mdl_animated_value_clear(handle.as_ptr()) };
20}
21
22fn animated_set_interpolation(handle: &ObjectHandle, interpolation: AnimatedValueInterpolation) {
23 unsafe { ffi::mdl_animated_value_set_interpolation(handle.as_ptr(), interpolation.as_raw()) };
25}
26
27fn convert_vectors<const N: usize>(raw: &[f32]) -> Vec<[f32; N]> {
28 raw.chunks_exact(N)
29 .map(|chunk| {
30 let mut value = [0.0_f32; N];
31 value.copy_from_slice(chunk);
32 value
33 })
34 .collect()
35}
36
37#[derive(Debug, Clone)]
38pub struct AnimatedValue {
40 handle: ObjectHandle,
41}
42
43impl AnimatedValue {
44 pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
46 Self { handle }
47 }
48
49 pub fn info(&self) -> Result<AnimatedValueInfo> {
51 animated_info(&self.handle, "MDLAnimatedValue")
52 }
53
54 pub fn clear(&self) {
56 animated_clear(&self.handle);
57 }
58
59 pub fn set_interpolation(&self, interpolation: AnimatedValueInterpolation) {
61 animated_set_interpolation(&self.handle, interpolation);
62 }
63}
64
65#[derive(Debug, Clone)]
66pub struct AnimatedScalar {
68 handle: ObjectHandle,
69}
70
71impl AnimatedScalar {
72 pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
74 Self { handle }
75 }
76
77 pub fn new() -> Result<Self> {
79 let mut out_value = ptr::null_mut();
80 let mut out_error = ptr::null_mut();
81 let status = unsafe { ffi::mdl_animated_scalar_new(&mut out_value, &mut out_error) };
83 crate::util::status_result(status, out_error)?;
84 Ok(Self::from_handle(required_handle(
85 out_value,
86 "MDLAnimatedScalar",
87 )?))
88 }
89
90 pub fn info(&self) -> Result<AnimatedValueInfo> {
92 animated_info(&self.handle, "MDLAnimatedScalar")
93 }
94
95 pub fn clear(&self) {
97 animated_clear(&self.handle);
98 }
99
100 pub fn set_interpolation(&self, interpolation: AnimatedValueInterpolation) {
102 animated_set_interpolation(&self.handle, interpolation);
103 }
104
105 pub fn set_float(&self, value: f32, time: f64) {
107 unsafe { ffi::mdl_animated_scalar_set_float(self.handle.as_ptr(), value, time) };
109 }
110
111 #[must_use]
112 pub fn float_value(&self, time: f64) -> f32 {
114 unsafe { ffi::mdl_animated_scalar_float_value(self.handle.as_ptr(), time) }
116 }
117}
118
119#[derive(Debug, Clone)]
120pub struct AnimatedVector2 {
122 handle: ObjectHandle,
123}
124
125impl AnimatedVector2 {
126 pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
128 Self { handle }
129 }
130
131 pub fn new() -> Result<Self> {
133 let mut out_value = ptr::null_mut();
134 let mut out_error = ptr::null_mut();
135 let status = unsafe { ffi::mdl_animated_vector2_new(&mut out_value, &mut out_error) };
137 crate::util::status_result(status, out_error)?;
138 Ok(Self::from_handle(required_handle(
139 out_value,
140 "MDLAnimatedVector2",
141 )?))
142 }
143
144 pub fn info(&self) -> Result<AnimatedValueInfo> {
146 animated_info(&self.handle, "MDLAnimatedVector2")
147 }
148
149 pub fn clear(&self) {
151 animated_clear(&self.handle);
152 }
153
154 pub fn set_interpolation(&self, interpolation: AnimatedValueInterpolation) {
156 animated_set_interpolation(&self.handle, interpolation);
157 }
158
159 pub fn set_float2(&self, value: [f32; 2], time: f64) {
161 unsafe {
163 ffi::mdl_animated_vector2_set_float2(self.handle.as_ptr(), value[0], value[1], time);
164 };
165 }
166
167 #[must_use]
168 pub fn float2_value(&self, time: f64) -> [f32; 2] {
170 let mut value = [0.0_f32; 2];
171 unsafe {
173 ffi::mdl_animated_vector2_copy_float2_value(
174 self.handle.as_ptr(),
175 time,
176 &mut value[0],
177 &mut value[1],
178 );
179 };
180 value
181 }
182}
183
184#[derive(Debug, Clone)]
185pub struct AnimatedVector3 {
187 handle: ObjectHandle,
188}
189
190impl AnimatedVector3 {
191 pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
193 Self { handle }
194 }
195
196 pub fn new() -> Result<Self> {
198 let mut out_value = ptr::null_mut();
199 let mut out_error = ptr::null_mut();
200 let status = unsafe { ffi::mdl_animated_vector3_new(&mut out_value, &mut out_error) };
202 crate::util::status_result(status, out_error)?;
203 Ok(Self::from_handle(required_handle(
204 out_value,
205 "MDLAnimatedVector3",
206 )?))
207 }
208
209 pub fn info(&self) -> Result<AnimatedValueInfo> {
211 animated_info(&self.handle, "MDLAnimatedVector3")
212 }
213
214 pub fn clear(&self) {
216 animated_clear(&self.handle);
217 }
218
219 pub fn set_interpolation(&self, interpolation: AnimatedValueInterpolation) {
221 animated_set_interpolation(&self.handle, interpolation);
222 }
223
224 pub fn set_float3(&self, value: [f32; 3], time: f64) {
226 unsafe {
228 ffi::mdl_animated_vector3_set_float3(
229 self.handle.as_ptr(),
230 value[0],
231 value[1],
232 value[2],
233 time,
234 );
235 };
236 }
237
238 #[must_use]
239 pub fn float3_value(&self, time: f64) -> [f32; 3] {
241 let mut value = [0.0_f32; 3];
242 unsafe {
244 ffi::mdl_animated_vector3_copy_float3_value(
245 self.handle.as_ptr(),
246 time,
247 &mut value[0],
248 &mut value[1],
249 &mut value[2],
250 );
251 };
252 value
253 }
254}
255
256#[derive(Debug, Clone)]
257pub struct AnimatedVector4 {
259 handle: ObjectHandle,
260}
261
262impl AnimatedVector4 {
263 pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
265 Self { handle }
266 }
267
268 pub fn new() -> Result<Self> {
270 let mut out_value = ptr::null_mut();
271 let mut out_error = ptr::null_mut();
272 let status = unsafe { ffi::mdl_animated_vector4_new(&mut out_value, &mut out_error) };
274 crate::util::status_result(status, out_error)?;
275 Ok(Self::from_handle(required_handle(
276 out_value,
277 "MDLAnimatedVector4",
278 )?))
279 }
280
281 pub fn info(&self) -> Result<AnimatedValueInfo> {
283 animated_info(&self.handle, "MDLAnimatedVector4")
284 }
285
286 pub fn clear(&self) {
288 animated_clear(&self.handle);
289 }
290
291 pub fn set_interpolation(&self, interpolation: AnimatedValueInterpolation) {
293 animated_set_interpolation(&self.handle, interpolation);
294 }
295
296 pub fn set_float4(&self, value: [f32; 4], time: f64) {
298 unsafe {
300 ffi::mdl_animated_vector4_set_float4(
301 self.handle.as_ptr(),
302 value[0],
303 value[1],
304 value[2],
305 value[3],
306 time,
307 );
308 };
309 }
310
311 #[must_use]
312 pub fn float4_value(&self, time: f64) -> [f32; 4] {
314 let mut value = [0.0_f32; 4];
315 unsafe {
317 ffi::mdl_animated_vector4_copy_float4_value(
318 self.handle.as_ptr(),
319 time,
320 &mut value[0],
321 &mut value[1],
322 &mut value[2],
323 &mut value[3],
324 );
325 };
326 value
327 }
328}
329
330#[derive(Debug, Clone)]
331pub struct AnimatedQuaternion {
333 handle: ObjectHandle,
334}
335
336impl AnimatedQuaternion {
337 pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
339 Self { handle }
340 }
341
342 pub fn new() -> Result<Self> {
344 let mut out_value = ptr::null_mut();
345 let mut out_error = ptr::null_mut();
346 let status = unsafe { ffi::mdl_animated_quaternion_new(&mut out_value, &mut out_error) };
348 crate::util::status_result(status, out_error)?;
349 Ok(Self::from_handle(required_handle(
350 out_value,
351 "MDLAnimatedQuaternion",
352 )?))
353 }
354
355 pub fn info(&self) -> Result<AnimatedValueInfo> {
357 animated_info(&self.handle, "MDLAnimatedQuaternion")
358 }
359
360 pub fn clear(&self) {
362 animated_clear(&self.handle);
363 }
364
365 pub fn set_interpolation(&self, interpolation: AnimatedValueInterpolation) {
367 animated_set_interpolation(&self.handle, interpolation);
368 }
369
370 pub fn set_float_quaternion(&self, value: [f32; 4], time: f64) {
372 unsafe {
374 ffi::mdl_animated_quaternion_set_float(
375 self.handle.as_ptr(),
376 value[0],
377 value[1],
378 value[2],
379 value[3],
380 time,
381 );
382 };
383 }
384
385 #[must_use]
386 pub fn float_quaternion_value(&self, time: f64) -> [f32; 4] {
388 let mut raw = [0.0_f32; 4];
389 unsafe {
391 ffi::mdl_animated_quaternion_copy_float_value(
392 self.handle.as_ptr(),
393 time,
394 raw.as_mut_ptr(),
395 );
396 };
397 raw
398 }
399}
400
401#[derive(Debug, Clone)]
402pub struct AnimatedMatrix4x4 {
404 handle: ObjectHandle,
405}
406
407impl AnimatedMatrix4x4 {
408 pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
410 Self { handle }
411 }
412
413 pub fn new() -> Result<Self> {
415 let mut out_value = ptr::null_mut();
416 let mut out_error = ptr::null_mut();
417 let status = unsafe { ffi::mdl_animated_matrix4x4_new(&mut out_value, &mut out_error) };
419 crate::util::status_result(status, out_error)?;
420 Ok(Self::from_handle(required_handle(
421 out_value,
422 "MDLAnimatedMatrix4x4",
423 )?))
424 }
425
426 pub fn info(&self) -> Result<AnimatedValueInfo> {
428 animated_info(&self.handle, "MDLAnimatedMatrix4x4")
429 }
430
431 pub fn clear(&self) {
433 animated_clear(&self.handle);
434 }
435
436 pub fn set_interpolation(&self, interpolation: AnimatedValueInterpolation) {
438 animated_set_interpolation(&self.handle, interpolation);
439 }
440
441 pub fn set_float4x4(&self, value: [f32; 16], time: f64) {
443 unsafe {
445 ffi::mdl_animated_matrix4x4_set_float(self.handle.as_ptr(), value.as_ptr(), time);
446 };
447 }
448
449 #[must_use]
450 pub fn float4x4_value(&self, time: f64) -> [f32; 16] {
452 let mut raw = [0.0_f32; 16];
453 unsafe {
455 ffi::mdl_animated_matrix4x4_copy_float_value(
456 self.handle.as_ptr(),
457 time,
458 raw.as_mut_ptr(),
459 );
460 };
461 raw
462 }
463}
464
465#[derive(Debug, Clone)]
466pub struct AnimatedScalarArray {
468 handle: ObjectHandle,
469}
470
471impl AnimatedScalarArray {
472 pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
474 Self { handle }
475 }
476
477 pub fn new(element_count: usize) -> Result<Self> {
479 let mut out_value = ptr::null_mut();
480 let mut out_error = ptr::null_mut();
481 let status = unsafe {
483 ffi::mdl_animated_scalar_array_new(element_count as u64, &mut out_value, &mut out_error)
484 };
485 crate::util::status_result(status, out_error)?;
486 Ok(Self::from_handle(required_handle(
487 out_value,
488 "MDLAnimatedScalarArray",
489 )?))
490 }
491
492 pub fn info(&self) -> Result<AnimatedValueInfo> {
494 animated_info(&self.handle, "MDLAnimatedScalarArray")
495 }
496
497 pub fn clear(&self) {
499 animated_clear(&self.handle);
500 }
501
502 pub fn set_interpolation(&self, interpolation: AnimatedValueInterpolation) {
504 animated_set_interpolation(&self.handle, interpolation);
505 }
506
507 pub fn set_float_array(&self, values: &[f32], time: f64) {
509 unsafe {
511 ffi::mdl_animated_scalar_array_set_float(
512 self.handle.as_ptr(),
513 values.as_ptr(),
514 values.len() as u64,
515 time,
516 );
517 };
518 }
519
520 pub fn float_array_at_time(&self, time: f64) -> Result<Vec<f32>> {
522 let element_count = self.info()?.element_count.unwrap_or(0);
523 if element_count == 0 {
524 return Ok(Vec::new());
525 }
526 let mut values = vec![0.0_f32; element_count];
527 let written = unsafe {
529 ffi::mdl_animated_scalar_array_copy_float_at_time(
530 self.handle.as_ptr(),
531 time,
532 values.as_mut_ptr(),
533 element_count as u64,
534 )
535 } as usize;
536 values.truncate(written);
537 Ok(values)
538 }
539}
540
541#[derive(Debug, Clone)]
542pub struct AnimatedVector3Array {
544 handle: ObjectHandle,
545}
546
547impl AnimatedVector3Array {
548 pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
550 Self { handle }
551 }
552
553 pub fn new(element_count: usize) -> Result<Self> {
555 let mut out_value = ptr::null_mut();
556 let mut out_error = ptr::null_mut();
557 let status = unsafe {
559 ffi::mdl_animated_vector3_array_new(
560 element_count as u64,
561 &mut out_value,
562 &mut out_error,
563 )
564 };
565 crate::util::status_result(status, out_error)?;
566 Ok(Self::from_handle(required_handle(
567 out_value,
568 "MDLAnimatedVector3Array",
569 )?))
570 }
571
572 pub fn info(&self) -> Result<AnimatedValueInfo> {
574 animated_info(&self.handle, "MDLAnimatedVector3Array")
575 }
576
577 pub fn clear(&self) {
579 animated_clear(&self.handle);
580 }
581
582 pub fn set_interpolation(&self, interpolation: AnimatedValueInterpolation) {
584 animated_set_interpolation(&self.handle, interpolation);
585 }
586
587 pub fn set_float3_array(&self, values: &[[f32; 3]], time: f64) {
589 let flattened = values
590 .iter()
591 .flat_map(|value| value.iter().copied())
592 .collect::<Vec<_>>();
593 unsafe {
595 ffi::mdl_animated_vector3_array_set_float(
596 self.handle.as_ptr(),
597 flattened.as_ptr(),
598 values.len() as u64,
599 time,
600 );
601 };
602 }
603
604 pub fn float3_array_at_time(&self, time: f64) -> Result<Vec<[f32; 3]>> {
606 let element_count = self.info()?.element_count.unwrap_or(0);
607 if element_count == 0 {
608 return Ok(Vec::new());
609 }
610 let mut values = vec![0.0_f32; element_count * 3];
611 let written = unsafe {
613 ffi::mdl_animated_vector3_array_copy_float_at_time(
614 self.handle.as_ptr(),
615 time,
616 values.as_mut_ptr(),
617 element_count as u64,
618 )
619 } as usize;
620 values.truncate(written * 3);
621 Ok(convert_vectors::<3>(&values))
622 }
623}
624
625#[derive(Debug, Clone)]
626pub struct AnimatedQuaternionArray {
628 handle: ObjectHandle,
629}
630
631impl AnimatedQuaternionArray {
632 pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
634 Self { handle }
635 }
636
637 pub fn new(element_count: usize) -> Result<Self> {
639 let mut out_value = ptr::null_mut();
640 let mut out_error = ptr::null_mut();
641 let status = unsafe {
643 ffi::mdl_animated_quaternion_array_new(
644 element_count as u64,
645 &mut out_value,
646 &mut out_error,
647 )
648 };
649 crate::util::status_result(status, out_error)?;
650 Ok(Self::from_handle(required_handle(
651 out_value,
652 "MDLAnimatedQuaternionArray",
653 )?))
654 }
655
656 pub fn info(&self) -> Result<AnimatedValueInfo> {
658 animated_info(&self.handle, "MDLAnimatedQuaternionArray")
659 }
660
661 pub fn clear(&self) {
663 animated_clear(&self.handle);
664 }
665
666 pub fn set_interpolation(&self, interpolation: AnimatedValueInterpolation) {
668 animated_set_interpolation(&self.handle, interpolation);
669 }
670
671 pub fn set_float_quaternion_array(&self, values: &[[f32; 4]], time: f64) {
673 let flattened = values
674 .iter()
675 .flat_map(|value| value.iter().copied())
676 .collect::<Vec<_>>();
677 unsafe {
679 ffi::mdl_animated_quaternion_array_set_float(
680 self.handle.as_ptr(),
681 flattened.as_ptr(),
682 values.len() as u64,
683 time,
684 );
685 };
686 }
687
688 pub fn float_quaternion_array_at_time(&self, time: f64) -> Result<Vec<[f32; 4]>> {
690 let element_count = self.info()?.element_count.unwrap_or(0);
691 if element_count == 0 {
692 return Ok(Vec::new());
693 }
694 let mut values = vec![0.0_f32; element_count * 4];
695 let written = unsafe {
697 ffi::mdl_animated_quaternion_array_copy_float_at_time(
698 self.handle.as_ptr(),
699 time,
700 values.as_mut_ptr(),
701 element_count as u64,
702 )
703 } as usize;
704 values.truncate(written * 4);
705 Ok(convert_vectors::<4>(&values))
706 }
707}