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()) },
12 context,
13 )
14}
15
16fn animated_clear(handle: &ObjectHandle) {
17 unsafe { ffi::mdl_animated_value_clear(handle.as_ptr()) };
18}
19
20fn animated_set_interpolation(handle: &ObjectHandle, interpolation: AnimatedValueInterpolation) {
21 unsafe { ffi::mdl_animated_value_set_interpolation(handle.as_ptr(), interpolation.as_raw()) };
22}
23
24fn convert_vectors<const N: usize>(raw: &[f32]) -> Vec<[f32; N]> {
25 raw.chunks_exact(N)
26 .map(|chunk| {
27 let mut value = [0.0_f32; N];
28 value.copy_from_slice(chunk);
29 value
30 })
31 .collect()
32}
33
34#[derive(Debug, Clone)]
35pub struct AnimatedValue {
36 handle: ObjectHandle,
37}
38
39impl AnimatedValue {
40 pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
41 Self { handle }
42 }
43
44 pub fn info(&self) -> Result<AnimatedValueInfo> {
45 animated_info(&self.handle, "MDLAnimatedValue")
46 }
47
48 pub fn clear(&self) {
49 animated_clear(&self.handle);
50 }
51
52 pub fn set_interpolation(&self, interpolation: AnimatedValueInterpolation) {
53 animated_set_interpolation(&self.handle, interpolation);
54 }
55}
56
57#[derive(Debug, Clone)]
58pub struct AnimatedScalar {
59 handle: ObjectHandle,
60}
61
62impl AnimatedScalar {
63 pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
64 Self { handle }
65 }
66
67 pub fn new() -> Result<Self> {
68 let mut out_value = ptr::null_mut();
69 let mut out_error = ptr::null_mut();
70 let status = unsafe { ffi::mdl_animated_scalar_new(&mut out_value, &mut out_error) };
71 crate::util::status_result(status, out_error)?;
72 Ok(Self::from_handle(required_handle(
73 out_value,
74 "MDLAnimatedScalar",
75 )?))
76 }
77
78 pub fn info(&self) -> Result<AnimatedValueInfo> {
79 animated_info(&self.handle, "MDLAnimatedScalar")
80 }
81
82 pub fn clear(&self) {
83 animated_clear(&self.handle);
84 }
85
86 pub fn set_interpolation(&self, interpolation: AnimatedValueInterpolation) {
87 animated_set_interpolation(&self.handle, interpolation);
88 }
89
90 pub fn set_float(&self, value: f32, time: f64) {
91 unsafe { ffi::mdl_animated_scalar_set_float(self.handle.as_ptr(), value, time) };
92 }
93
94 #[must_use]
95 pub fn float_value(&self, time: f64) -> f32 {
96 unsafe { ffi::mdl_animated_scalar_float_value(self.handle.as_ptr(), time) }
97 }
98}
99
100#[derive(Debug, Clone)]
101pub struct AnimatedVector2 {
102 handle: ObjectHandle,
103}
104
105impl AnimatedVector2 {
106 pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
107 Self { handle }
108 }
109
110 pub fn new() -> Result<Self> {
111 let mut out_value = ptr::null_mut();
112 let mut out_error = ptr::null_mut();
113 let status = unsafe { ffi::mdl_animated_vector2_new(&mut out_value, &mut out_error) };
114 crate::util::status_result(status, out_error)?;
115 Ok(Self::from_handle(required_handle(
116 out_value,
117 "MDLAnimatedVector2",
118 )?))
119 }
120
121 pub fn info(&self) -> Result<AnimatedValueInfo> {
122 animated_info(&self.handle, "MDLAnimatedVector2")
123 }
124
125 pub fn clear(&self) {
126 animated_clear(&self.handle);
127 }
128
129 pub fn set_interpolation(&self, interpolation: AnimatedValueInterpolation) {
130 animated_set_interpolation(&self.handle, interpolation);
131 }
132
133 pub fn set_float2(&self, value: [f32; 2], time: f64) {
134 unsafe {
135 ffi::mdl_animated_vector2_set_float2(self.handle.as_ptr(), value[0], value[1], time);
136 };
137 }
138
139 #[must_use]
140 pub fn float2_value(&self, time: f64) -> [f32; 2] {
141 let mut value = [0.0_f32; 2];
142 unsafe {
143 ffi::mdl_animated_vector2_copy_float2_value(
144 self.handle.as_ptr(),
145 time,
146 &mut value[0],
147 &mut value[1],
148 );
149 };
150 value
151 }
152}
153
154#[derive(Debug, Clone)]
155pub struct AnimatedVector3 {
156 handle: ObjectHandle,
157}
158
159impl AnimatedVector3 {
160 pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
161 Self { handle }
162 }
163
164 pub fn new() -> Result<Self> {
165 let mut out_value = ptr::null_mut();
166 let mut out_error = ptr::null_mut();
167 let status = unsafe { ffi::mdl_animated_vector3_new(&mut out_value, &mut out_error) };
168 crate::util::status_result(status, out_error)?;
169 Ok(Self::from_handle(required_handle(
170 out_value,
171 "MDLAnimatedVector3",
172 )?))
173 }
174
175 pub fn info(&self) -> Result<AnimatedValueInfo> {
176 animated_info(&self.handle, "MDLAnimatedVector3")
177 }
178
179 pub fn clear(&self) {
180 animated_clear(&self.handle);
181 }
182
183 pub fn set_interpolation(&self, interpolation: AnimatedValueInterpolation) {
184 animated_set_interpolation(&self.handle, interpolation);
185 }
186
187 pub fn set_float3(&self, value: [f32; 3], time: f64) {
188 unsafe {
189 ffi::mdl_animated_vector3_set_float3(
190 self.handle.as_ptr(),
191 value[0],
192 value[1],
193 value[2],
194 time,
195 );
196 };
197 }
198
199 #[must_use]
200 pub fn float3_value(&self, time: f64) -> [f32; 3] {
201 let mut value = [0.0_f32; 3];
202 unsafe {
203 ffi::mdl_animated_vector3_copy_float3_value(
204 self.handle.as_ptr(),
205 time,
206 &mut value[0],
207 &mut value[1],
208 &mut value[2],
209 );
210 };
211 value
212 }
213}
214
215#[derive(Debug, Clone)]
216pub struct AnimatedVector4 {
217 handle: ObjectHandle,
218}
219
220impl AnimatedVector4 {
221 pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
222 Self { handle }
223 }
224
225 pub fn new() -> Result<Self> {
226 let mut out_value = ptr::null_mut();
227 let mut out_error = ptr::null_mut();
228 let status = unsafe { ffi::mdl_animated_vector4_new(&mut out_value, &mut out_error) };
229 crate::util::status_result(status, out_error)?;
230 Ok(Self::from_handle(required_handle(
231 out_value,
232 "MDLAnimatedVector4",
233 )?))
234 }
235
236 pub fn info(&self) -> Result<AnimatedValueInfo> {
237 animated_info(&self.handle, "MDLAnimatedVector4")
238 }
239
240 pub fn clear(&self) {
241 animated_clear(&self.handle);
242 }
243
244 pub fn set_interpolation(&self, interpolation: AnimatedValueInterpolation) {
245 animated_set_interpolation(&self.handle, interpolation);
246 }
247
248 pub fn set_float4(&self, value: [f32; 4], time: f64) {
249 unsafe {
250 ffi::mdl_animated_vector4_set_float4(
251 self.handle.as_ptr(),
252 value[0],
253 value[1],
254 value[2],
255 value[3],
256 time,
257 );
258 };
259 }
260
261 #[must_use]
262 pub fn float4_value(&self, time: f64) -> [f32; 4] {
263 let mut value = [0.0_f32; 4];
264 unsafe {
265 ffi::mdl_animated_vector4_copy_float4_value(
266 self.handle.as_ptr(),
267 time,
268 &mut value[0],
269 &mut value[1],
270 &mut value[2],
271 &mut value[3],
272 );
273 };
274 value
275 }
276}
277
278#[derive(Debug, Clone)]
279pub struct AnimatedQuaternion {
280 handle: ObjectHandle,
281}
282
283impl AnimatedQuaternion {
284 pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
285 Self { handle }
286 }
287
288 pub fn new() -> Result<Self> {
289 let mut out_value = ptr::null_mut();
290 let mut out_error = ptr::null_mut();
291 let status = unsafe { ffi::mdl_animated_quaternion_new(&mut out_value, &mut out_error) };
292 crate::util::status_result(status, out_error)?;
293 Ok(Self::from_handle(required_handle(
294 out_value,
295 "MDLAnimatedQuaternion",
296 )?))
297 }
298
299 pub fn info(&self) -> Result<AnimatedValueInfo> {
300 animated_info(&self.handle, "MDLAnimatedQuaternion")
301 }
302
303 pub fn clear(&self) {
304 animated_clear(&self.handle);
305 }
306
307 pub fn set_interpolation(&self, interpolation: AnimatedValueInterpolation) {
308 animated_set_interpolation(&self.handle, interpolation);
309 }
310
311 pub fn set_float_quaternion(&self, value: [f32; 4], time: f64) {
312 unsafe {
313 ffi::mdl_animated_quaternion_set_float(
314 self.handle.as_ptr(),
315 value[0],
316 value[1],
317 value[2],
318 value[3],
319 time,
320 );
321 };
322 }
323
324 #[must_use]
325 pub fn float_quaternion_value(&self, time: f64) -> [f32; 4] {
326 let mut raw = [0.0_f32; 4];
327 unsafe {
328 ffi::mdl_animated_quaternion_copy_float_value(
329 self.handle.as_ptr(),
330 time,
331 raw.as_mut_ptr(),
332 );
333 };
334 raw
335 }
336}
337
338#[derive(Debug, Clone)]
339pub struct AnimatedMatrix4x4 {
340 handle: ObjectHandle,
341}
342
343impl AnimatedMatrix4x4 {
344 pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
345 Self { handle }
346 }
347
348 pub fn new() -> Result<Self> {
349 let mut out_value = ptr::null_mut();
350 let mut out_error = ptr::null_mut();
351 let status = unsafe { ffi::mdl_animated_matrix4x4_new(&mut out_value, &mut out_error) };
352 crate::util::status_result(status, out_error)?;
353 Ok(Self::from_handle(required_handle(
354 out_value,
355 "MDLAnimatedMatrix4x4",
356 )?))
357 }
358
359 pub fn info(&self) -> Result<AnimatedValueInfo> {
360 animated_info(&self.handle, "MDLAnimatedMatrix4x4")
361 }
362
363 pub fn clear(&self) {
364 animated_clear(&self.handle);
365 }
366
367 pub fn set_interpolation(&self, interpolation: AnimatedValueInterpolation) {
368 animated_set_interpolation(&self.handle, interpolation);
369 }
370
371 pub fn set_float4x4(&self, value: [f32; 16], time: f64) {
372 unsafe {
373 ffi::mdl_animated_matrix4x4_set_float(self.handle.as_ptr(), value.as_ptr(), time);
374 };
375 }
376
377 #[must_use]
378 pub fn float4x4_value(&self, time: f64) -> [f32; 16] {
379 let mut raw = [0.0_f32; 16];
380 unsafe {
381 ffi::mdl_animated_matrix4x4_copy_float_value(
382 self.handle.as_ptr(),
383 time,
384 raw.as_mut_ptr(),
385 );
386 };
387 raw
388 }
389}
390
391#[derive(Debug, Clone)]
392pub struct AnimatedScalarArray {
393 handle: ObjectHandle,
394}
395
396impl AnimatedScalarArray {
397 pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
398 Self { handle }
399 }
400
401 pub fn new(element_count: usize) -> Result<Self> {
402 let mut out_value = ptr::null_mut();
403 let mut out_error = ptr::null_mut();
404 let status = unsafe {
405 ffi::mdl_animated_scalar_array_new(element_count as u64, &mut out_value, &mut out_error)
406 };
407 crate::util::status_result(status, out_error)?;
408 Ok(Self::from_handle(required_handle(
409 out_value,
410 "MDLAnimatedScalarArray",
411 )?))
412 }
413
414 pub fn info(&self) -> Result<AnimatedValueInfo> {
415 animated_info(&self.handle, "MDLAnimatedScalarArray")
416 }
417
418 pub fn clear(&self) {
419 animated_clear(&self.handle);
420 }
421
422 pub fn set_interpolation(&self, interpolation: AnimatedValueInterpolation) {
423 animated_set_interpolation(&self.handle, interpolation);
424 }
425
426 pub fn set_float_array(&self, values: &[f32], time: f64) {
427 unsafe {
428 ffi::mdl_animated_scalar_array_set_float(
429 self.handle.as_ptr(),
430 values.as_ptr(),
431 values.len() as u64,
432 time,
433 );
434 };
435 }
436
437 pub fn float_array_at_time(&self, time: f64) -> Result<Vec<f32>> {
438 let element_count = self.info()?.element_count.unwrap_or(0);
439 if element_count == 0 {
440 return Ok(Vec::new());
441 }
442 let mut values = vec![0.0_f32; element_count];
443 let written = unsafe {
444 ffi::mdl_animated_scalar_array_copy_float_at_time(
445 self.handle.as_ptr(),
446 time,
447 values.as_mut_ptr(),
448 element_count as u64,
449 )
450 } as usize;
451 values.truncate(written);
452 Ok(values)
453 }
454}
455
456#[derive(Debug, Clone)]
457pub struct AnimatedVector3Array {
458 handle: ObjectHandle,
459}
460
461impl AnimatedVector3Array {
462 pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
463 Self { handle }
464 }
465
466 pub fn new(element_count: usize) -> Result<Self> {
467 let mut out_value = ptr::null_mut();
468 let mut out_error = ptr::null_mut();
469 let status = unsafe {
470 ffi::mdl_animated_vector3_array_new(
471 element_count as u64,
472 &mut out_value,
473 &mut out_error,
474 )
475 };
476 crate::util::status_result(status, out_error)?;
477 Ok(Self::from_handle(required_handle(
478 out_value,
479 "MDLAnimatedVector3Array",
480 )?))
481 }
482
483 pub fn info(&self) -> Result<AnimatedValueInfo> {
484 animated_info(&self.handle, "MDLAnimatedVector3Array")
485 }
486
487 pub fn clear(&self) {
488 animated_clear(&self.handle);
489 }
490
491 pub fn set_interpolation(&self, interpolation: AnimatedValueInterpolation) {
492 animated_set_interpolation(&self.handle, interpolation);
493 }
494
495 pub fn set_float3_array(&self, values: &[[f32; 3]], time: f64) {
496 let flattened = values
497 .iter()
498 .flat_map(|value| value.iter().copied())
499 .collect::<Vec<_>>();
500 unsafe {
501 ffi::mdl_animated_vector3_array_set_float(
502 self.handle.as_ptr(),
503 flattened.as_ptr(),
504 values.len() as u64,
505 time,
506 );
507 };
508 }
509
510 pub fn float3_array_at_time(&self, time: f64) -> Result<Vec<[f32; 3]>> {
511 let element_count = self.info()?.element_count.unwrap_or(0);
512 if element_count == 0 {
513 return Ok(Vec::new());
514 }
515 let mut values = vec![0.0_f32; element_count * 3];
516 let written = unsafe {
517 ffi::mdl_animated_vector3_array_copy_float_at_time(
518 self.handle.as_ptr(),
519 time,
520 values.as_mut_ptr(),
521 element_count as u64,
522 )
523 } as usize;
524 values.truncate(written * 3);
525 Ok(convert_vectors::<3>(&values))
526 }
527}
528
529#[derive(Debug, Clone)]
530pub struct AnimatedQuaternionArray {
531 handle: ObjectHandle,
532}
533
534impl AnimatedQuaternionArray {
535 pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
536 Self { handle }
537 }
538
539 pub fn new(element_count: usize) -> Result<Self> {
540 let mut out_value = ptr::null_mut();
541 let mut out_error = ptr::null_mut();
542 let status = unsafe {
543 ffi::mdl_animated_quaternion_array_new(
544 element_count as u64,
545 &mut out_value,
546 &mut out_error,
547 )
548 };
549 crate::util::status_result(status, out_error)?;
550 Ok(Self::from_handle(required_handle(
551 out_value,
552 "MDLAnimatedQuaternionArray",
553 )?))
554 }
555
556 pub fn info(&self) -> Result<AnimatedValueInfo> {
557 animated_info(&self.handle, "MDLAnimatedQuaternionArray")
558 }
559
560 pub fn clear(&self) {
561 animated_clear(&self.handle);
562 }
563
564 pub fn set_interpolation(&self, interpolation: AnimatedValueInterpolation) {
565 animated_set_interpolation(&self.handle, interpolation);
566 }
567
568 pub fn set_float_quaternion_array(&self, values: &[[f32; 4]], time: f64) {
569 let flattened = values
570 .iter()
571 .flat_map(|value| value.iter().copied())
572 .collect::<Vec<_>>();
573 unsafe {
574 ffi::mdl_animated_quaternion_array_set_float(
575 self.handle.as_ptr(),
576 flattened.as_ptr(),
577 values.len() as u64,
578 time,
579 );
580 };
581 }
582
583 pub fn float_quaternion_array_at_time(&self, time: f64) -> Result<Vec<[f32; 4]>> {
584 let element_count = self.info()?.element_count.unwrap_or(0);
585 if element_count == 0 {
586 return Ok(Vec::new());
587 }
588 let mut values = vec![0.0_f32; element_count * 4];
589 let written = unsafe {
590 ffi::mdl_animated_quaternion_array_copy_float_at_time(
591 self.handle.as_ptr(),
592 time,
593 values.as_mut_ptr(),
594 element_count as u64,
595 )
596 } as usize;
597 values.truncate(written * 4);
598 Ok(convert_vectors::<4>(&values))
599 }
600}