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