Skip to main content

whiteout/
m2.rs

1// SPDX-License-Identifier: BSD-3-Clause
2// Copyright (c) 2026 Fernando Sahmkow
3// AUTOGENERATED by tools/codegen/emit_rust.py — do not edit.
4// Regenerate via:  python -m tools.codegen.codegen m2 --backend rust
5
6#![allow(clippy::too_many_arguments)]
7
8// Which of these a module needs depends on its shapes; the modules that
9// have no span accessors would otherwise trip the unused-import lint.
10#[allow(unused_imports)]
11use crate::support::{BorrowedSlice, Bytes};
12
13#[repr(i32)]
14#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
15pub enum InterpolationType {
16    None = 0,
17    Linear = 1,
18    Bezier = 2,
19    Hermite = 3,
20}
21
22impl TryFrom<i32> for InterpolationType {
23    type Error = crate::Error;
24    fn try_from(v: i32) -> Result<Self, crate::Error> {
25        match v {
26            0 => Ok(InterpolationType::None),
27            1 => Ok(InterpolationType::Linear),
28            2 => Ok(InterpolationType::Bezier),
29            3 => Ok(InterpolationType::Hermite),
30            other => Err(crate::Error::UnknownEnum {
31                name: "InterpolationType",
32                value: other,
33            }),
34        }
35    }
36}
37
38/// Bit flags. Combine with `|`, test with [`GlobalFlag::contains`].
39#[derive(Clone, Copy, PartialEq, Eq, Hash, Default)]
40pub struct GlobalFlag(pub i32);
41
42impl GlobalFlag {
43    pub const NONE: Self = Self(0);
44    pub const TILT_X: Self = Self(1);
45    pub const TILT_Y: Self = Self(2);
46    pub const ADD_BACK_REFERENCES: Self = Self(4);
47    pub const USE_TEXTURE_COMBINER_COMBOS: Self = Self(8);
48    pub const IS_CAMERA: Self = Self(16);
49    pub const UNUSED: Self = Self(32);
50    pub const UNK_0X_80: Self = Self(128);
51    pub const LOAD_PHYSICS_DATA: Self = Self(256);
52    pub const NEW_PARTICLE_RECORD: Self = Self(512);
53    pub const UNK_0X_400: Self = Self(1024);
54    pub const TEXTURE_TRANSFORMS_USES_BONE_SEQUENCES: Self = Self(2048);
55    pub const UNK_0X_1000: Self = Self(4096);
56    pub const CHUNKED_ANIM_FILES: Self = Self(8192);
57    pub const UPGRADED_FORMAT: Self = Self(2097152);
58
59    #[inline]
60    pub const fn contains(self, other: Self) -> bool {
61        (self.0 & other.0) == other.0
62    }
63
64    #[inline]
65    pub const fn is_empty(self) -> bool {
66        self.0 == 0
67    }
68}
69
70impl core::ops::BitOr for GlobalFlag {
71    type Output = Self;
72    #[inline]
73    fn bitor(self, rhs: Self) -> Self {
74        Self(self.0 | rhs.0)
75    }
76}
77
78impl core::ops::BitAnd for GlobalFlag {
79    type Output = Self;
80    #[inline]
81    fn bitand(self, rhs: Self) -> Self {
82        Self(self.0 & rhs.0)
83    }
84}
85
86impl core::ops::Not for GlobalFlag {
87    type Output = Self;
88    #[inline]
89    fn not(self) -> Self {
90        Self(!self.0)
91    }
92}
93
94impl core::fmt::Debug for GlobalFlag {
95    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
96        write!(f, "GlobalFlag({:#x})", self.0)
97    }
98}
99
100/// Bit flags. Combine with `|`, test with [`SequenceFlag::contains`].
101#[derive(Clone, Copy, PartialEq, Eq, Hash, Default)]
102pub struct SequenceFlag(pub i32);
103
104impl SequenceFlag {
105    pub const NONE: Self = Self(0);
106    pub const TILT_IN: Self = Self(1);
107    pub const TILT_OUT: Self = Self(2);
108    pub const TILT_FIXED: Self = Self(4);
109    pub const LOOPING: Self = Self(32);
110    pub const IS_ALIAS: Self = Self(64);
111    pub const ANIMATED_SETUP: Self = Self(128);
112    pub const STORED_ANIMATED: Self = Self(256);
113    pub const ENABLE_COMPOSITE: Self = Self(512);
114
115    #[inline]
116    pub const fn contains(self, other: Self) -> bool {
117        (self.0 & other.0) == other.0
118    }
119
120    #[inline]
121    pub const fn is_empty(self) -> bool {
122        self.0 == 0
123    }
124}
125
126impl core::ops::BitOr for SequenceFlag {
127    type Output = Self;
128    #[inline]
129    fn bitor(self, rhs: Self) -> Self {
130        Self(self.0 | rhs.0)
131    }
132}
133
134impl core::ops::BitAnd for SequenceFlag {
135    type Output = Self;
136    #[inline]
137    fn bitand(self, rhs: Self) -> Self {
138        Self(self.0 & rhs.0)
139    }
140}
141
142impl core::ops::Not for SequenceFlag {
143    type Output = Self;
144    #[inline]
145    fn not(self) -> Self {
146        Self(!self.0)
147    }
148}
149
150impl core::fmt::Debug for SequenceFlag {
151    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
152        write!(f, "SequenceFlag({:#x})", self.0)
153    }
154}
155
156/// Bit flags. Combine with `|`, test with [`BoneFlag::contains`].
157#[derive(Clone, Copy, PartialEq, Eq, Hash, Default)]
158pub struct BoneFlag(pub i32);
159
160impl BoneFlag {
161    pub const NONE: Self = Self(0);
162    pub const IGNORE_PARENT_TRANSLATE: Self = Self(1);
163    pub const IGNORE_PARENT_SCALE: Self = Self(2);
164    pub const IGNORE_PARENT_ROTATION: Self = Self(4);
165    pub const SPHERICAL_BILLBOARD: Self = Self(8);
166    pub const CYLINDRICAL_BILLBOARD_X: Self = Self(16);
167    pub const CYLINDRICAL_BILLBOARD_Y: Self = Self(32);
168    pub const CYLINDRICAL_BILLBOARD_Z: Self = Self(64);
169    pub const TRANSFORMED: Self = Self(512);
170    pub const KINEMATIC: Self = Self(1024);
171    pub const HELMET_ANIM_SCALED: Self = Self(4096);
172
173    #[inline]
174    pub const fn contains(self, other: Self) -> bool {
175        (self.0 & other.0) == other.0
176    }
177
178    #[inline]
179    pub const fn is_empty(self) -> bool {
180        self.0 == 0
181    }
182}
183
184impl core::ops::BitOr for BoneFlag {
185    type Output = Self;
186    #[inline]
187    fn bitor(self, rhs: Self) -> Self {
188        Self(self.0 | rhs.0)
189    }
190}
191
192impl core::ops::BitAnd for BoneFlag {
193    type Output = Self;
194    #[inline]
195    fn bitand(self, rhs: Self) -> Self {
196        Self(self.0 & rhs.0)
197    }
198}
199
200impl core::ops::Not for BoneFlag {
201    type Output = Self;
202    #[inline]
203    fn not(self) -> Self {
204        Self(!self.0)
205    }
206}
207
208impl core::fmt::Debug for BoneFlag {
209    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
210        write!(f, "BoneFlag({:#x})", self.0)
211    }
212}
213
214/// Bit flags. Combine with `|`, test with [`MaterialFlag::contains`].
215#[derive(Clone, Copy, PartialEq, Eq, Hash, Default)]
216pub struct MaterialFlag(pub i32);
217
218impl MaterialFlag {
219    pub const NONE: Self = Self(0);
220    pub const UNLIT: Self = Self(1);
221    pub const UNFOGGED: Self = Self(2);
222    pub const TWO_SIDED: Self = Self(4);
223    pub const DEPTH_TEST: Self = Self(8);
224    pub const DEPTH_WRITE: Self = Self(16);
225    pub const NO_ALPHA_COMPOSITE: Self = Self(2048);
226
227    #[inline]
228    pub const fn contains(self, other: Self) -> bool {
229        (self.0 & other.0) == other.0
230    }
231
232    #[inline]
233    pub const fn is_empty(self) -> bool {
234        self.0 == 0
235    }
236}
237
238impl core::ops::BitOr for MaterialFlag {
239    type Output = Self;
240    #[inline]
241    fn bitor(self, rhs: Self) -> Self {
242        Self(self.0 | rhs.0)
243    }
244}
245
246impl core::ops::BitAnd for MaterialFlag {
247    type Output = Self;
248    #[inline]
249    fn bitand(self, rhs: Self) -> Self {
250        Self(self.0 & rhs.0)
251    }
252}
253
254impl core::ops::Not for MaterialFlag {
255    type Output = Self;
256    #[inline]
257    fn not(self) -> Self {
258        Self(!self.0)
259    }
260}
261
262impl core::fmt::Debug for MaterialFlag {
263    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
264        write!(f, "MaterialFlag({:#x})", self.0)
265    }
266}
267
268#[repr(i32)]
269#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
270pub enum ParticleEmitterType {
271    Plane = 1,
272    Sphere = 2,
273    Spline = 3,
274    Bone = 4,
275}
276
277impl TryFrom<i32> for ParticleEmitterType {
278    type Error = crate::Error;
279    fn try_from(v: i32) -> Result<Self, crate::Error> {
280        match v {
281            1 => Ok(ParticleEmitterType::Plane),
282            2 => Ok(ParticleEmitterType::Sphere),
283            3 => Ok(ParticleEmitterType::Spline),
284            4 => Ok(ParticleEmitterType::Bone),
285            other => Err(crate::Error::UnknownEnum {
286                name: "ParticleEmitterType",
287                value: other,
288            }),
289        }
290    }
291}
292
293#[repr(i32)]
294#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
295pub enum ParticleBlending {
296    Opaque = 0,
297    AlphaBlend = 1,
298    Additive = 2,
299    AlphaTest = 3,
300    AdditiveAlphaTest = 4,
301}
302
303impl TryFrom<i32> for ParticleBlending {
304    type Error = crate::Error;
305    fn try_from(v: i32) -> Result<Self, crate::Error> {
306        match v {
307            0 => Ok(ParticleBlending::Opaque),
308            1 => Ok(ParticleBlending::AlphaBlend),
309            2 => Ok(ParticleBlending::Additive),
310            3 => Ok(ParticleBlending::AlphaTest),
311            4 => Ok(ParticleBlending::AdditiveAlphaTest),
312            other => Err(crate::Error::UnknownEnum {
313                name: "ParticleBlending",
314                value: other,
315            }),
316        }
317    }
318}
319
320/// Bit flags. Combine with `|`, test with [`ParticleFlag::contains`].
321#[derive(Clone, Copy, PartialEq, Eq, Hash, Default)]
322pub struct ParticleFlag(pub i32);
323
324impl ParticleFlag {
325    pub const NONE: Self = Self(0);
326    pub const SHADED: Self = Self(1);
327    pub const SORT_PARTICLES: Self = Self(2);
328    pub const VELOCITY_ORIENT: Self = Self(4);
329    pub const UNSHADED: Self = Self(8);
330    pub const WORLD_SPACE: Self = Self(16);
331    pub const INHERIT_BONE_SCALE: Self = Self(32);
332    pub const INHERIT_VELOCITY: Self = Self(64);
333    pub const IMPLOSION_FILTER: Self = Self(128);
334    pub const HEMISPHERE_UP_DIRECTION: Self = Self(256);
335    pub const NEGATE_SPIN_RANDOM: Self = Self(512);
336    pub const CLAMP_TAIL_TO_AGE: Self = Self(1024);
337    pub const INHERIT_POSITION: Self = Self(2048);
338    pub const XY_QUAD: Self = Self(4096);
339    pub const PROJECT_PARTICLE: Self = Self(8192);
340    pub const FOLLOW_POSITION: Self = Self(16384);
341    pub const SQUIRT: Self = Self(32768);
342    pub const CHOOSE_RANDOM_TEXTURE: Self = Self(65536);
343    pub const HEAD_STYLE: Self = Self(131072);
344    pub const TAIL_STYLE: Self = Self(262144);
345    pub const UNSCALED_SIZE_VARIATION: Self = Self(524288);
346    pub const UNFOGGED: Self = Self(1048576);
347    pub const RAND_FLIPBOOK_START: Self = Self(2097152);
348    pub const UNK_0X_400000: Self = Self(4194304);
349    pub const COMPRESSED_GRAVITY: Self = Self(8388608);
350    pub const BONE_GENERATOR_BONE: Self = Self(16777216);
351    pub const NO_GLOBAL_VIEW_SCALE: Self = Self(33554432);
352    pub const LOD_IGNORE_DISTANCE: Self = Self(67108864);
353    pub const OFFSET_HEAD_BY_SPIN: Self = Self(134217728);
354    pub const MULTI_TEXTURE: Self = Self(268435456);
355    pub const MULTITEX_USE_MODX_4: Self = Self(536870912);
356    pub const MULTITEX_USE_3_COLORS: Self = Self(1073741824);
357    pub const DYNAMIC_WIND: Self = Self(-2147483648);
358
359    #[inline]
360    pub const fn contains(self, other: Self) -> bool {
361        (self.0 & other.0) == other.0
362    }
363
364    #[inline]
365    pub const fn is_empty(self) -> bool {
366        self.0 == 0
367    }
368}
369
370impl core::ops::BitOr for ParticleFlag {
371    type Output = Self;
372    #[inline]
373    fn bitor(self, rhs: Self) -> Self {
374        Self(self.0 | rhs.0)
375    }
376}
377
378impl core::ops::BitAnd for ParticleFlag {
379    type Output = Self;
380    #[inline]
381    fn bitand(self, rhs: Self) -> Self {
382        Self(self.0 & rhs.0)
383    }
384}
385
386impl core::ops::Not for ParticleFlag {
387    type Output = Self;
388    #[inline]
389    fn not(self) -> Self {
390        Self(!self.0)
391    }
392}
393
394impl core::fmt::Debug for ParticleFlag {
395    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
396        write!(f, "ParticleFlag({:#x})", self.0)
397    }
398}
399
400pub struct CompatQuaternion {
401    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2CompatQuaternion>,
402}
403
404impl Drop for CompatQuaternion {
405    fn drop(&mut self) {
406        // SAFETY: `raw` came from a native constructor and Drop runs once.
407        unsafe { ffi::whiteout_m2_M2CompatQuaternion_delete(self.raw.as_ptr()) }
408    }
409}
410
411impl CompatQuaternion {
412    /// # Safety
413    /// `raw` must be a live handle this value takes ownership of.
414    #[allow(dead_code)] // used by whichever methods return this type
415    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2CompatQuaternion) -> Option<Self> {
416        core::ptr::NonNull::new(raw).map(|raw| CompatQuaternion { raw })
417    }
418}
419
420// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
421// is deliberately NOT implemented — the C++ types make no documented
422// guarantee about concurrent use, and claiming one we haven't verified
423// would be unsound. See `@bind thread_safe` in the plan.
424unsafe impl Send for CompatQuaternion {}
425
426impl core::fmt::Debug for CompatQuaternion {
427    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
428        f.debug_struct("CompatQuaternion").finish_non_exhaustive()
429    }
430}
431
432impl CompatQuaternion {
433    /// # Panics
434    /// Panics if the native allocation fails.
435    pub fn new() -> Self {
436        // SAFETY: the native constructor returns a live handle; a null here
437        // means the library is unusable.
438        unsafe {
439            let raw = ffi::whiteout_m2_M2CompatQuaternion_new();
440            Self::from_raw(raw).expect("native CompatQuaternion allocation failed")
441        }
442    }
443}
444
445impl Default for CompatQuaternion {
446    fn default() -> Self {
447        Self::new()
448    }
449}
450
451pub struct ColorBGRA {
452    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2ColorBGRA>,
453}
454
455impl Drop for ColorBGRA {
456    fn drop(&mut self) {
457        // SAFETY: `raw` came from a native constructor and Drop runs once.
458        unsafe { ffi::whiteout_m2_M2ColorBGRA_delete(self.raw.as_ptr()) }
459    }
460}
461
462impl ColorBGRA {
463    /// # Safety
464    /// `raw` must be a live handle this value takes ownership of.
465    #[allow(dead_code)] // used by whichever methods return this type
466    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2ColorBGRA) -> Option<Self> {
467        core::ptr::NonNull::new(raw).map(|raw| ColorBGRA { raw })
468    }
469}
470
471// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
472// is deliberately NOT implemented — the C++ types make no documented
473// guarantee about concurrent use, and claiming one we haven't verified
474// would be unsound. See `@bind thread_safe` in the plan.
475unsafe impl Send for ColorBGRA {}
476
477impl core::fmt::Debug for ColorBGRA {
478    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
479        f.debug_struct("ColorBGRA").finish_non_exhaustive()
480    }
481}
482
483impl ColorBGRA {
484    /// # Panics
485    /// Panics if the native allocation fails.
486    pub fn new() -> Self {
487        // SAFETY: the native constructor returns a live handle; a null here
488        // means the library is unusable.
489        unsafe {
490            let raw = ffi::whiteout_m2_M2ColorBGRA_new();
491            Self::from_raw(raw).expect("native ColorBGRA allocation failed")
492        }
493    }
494}
495
496impl Default for ColorBGRA {
497    fn default() -> Self {
498        Self::new()
499    }
500}
501
502pub struct Extent {
503    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2Extent>,
504}
505
506impl Drop for Extent {
507    fn drop(&mut self) {
508        // SAFETY: `raw` came from a native constructor and Drop runs once.
509        unsafe { ffi::whiteout_m2_M2Extent_delete(self.raw.as_ptr()) }
510    }
511}
512
513impl Extent {
514    /// # Safety
515    /// `raw` must be a live handle this value takes ownership of.
516    #[allow(dead_code)] // used by whichever methods return this type
517    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2Extent) -> Option<Self> {
518        core::ptr::NonNull::new(raw).map(|raw| Extent { raw })
519    }
520}
521
522// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
523// is deliberately NOT implemented — the C++ types make no documented
524// guarantee about concurrent use, and claiming one we haven't verified
525// would be unsound. See `@bind thread_safe` in the plan.
526unsafe impl Send for Extent {}
527
528impl core::fmt::Debug for Extent {
529    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
530        f.debug_struct("Extent").finish_non_exhaustive()
531    }
532}
533
534impl Extent {
535    /// # Panics
536    /// Panics if the native allocation fails.
537    pub fn new() -> Self {
538        // SAFETY: the native constructor returns a live handle; a null here
539        // means the library is unusable.
540        unsafe {
541            let raw = ffi::whiteout_m2_M2Extent_new();
542            Self::from_raw(raw).expect("native Extent allocation failed")
543        }
544    }
545
546    pub fn minimum(&self) -> crate::math::Vector3f {
547        // SAFETY: the getter returns an interior pointer to a
548        // layout-identical POD; we copy it out immediately.
549        unsafe {
550            *(ffi::whiteout_m2_M2Extent_get_minimum(self.raw.as_ptr())
551                as *const crate::math::Vector3f)
552        }
553    }
554
555    pub fn set_minimum(&mut self, value: crate::math::Vector3f) {
556        // SAFETY: as above, in the other direction.
557        unsafe {
558            ffi::whiteout_m2_M2Extent_set_minimum(
559                self.raw.as_ptr(),
560                &value as *const crate::math::Vector3f as *const _,
561            )
562        }
563    }
564
565    pub fn maximum(&self) -> crate::math::Vector3f {
566        // SAFETY: the getter returns an interior pointer to a
567        // layout-identical POD; we copy it out immediately.
568        unsafe {
569            *(ffi::whiteout_m2_M2Extent_get_maximum(self.raw.as_ptr())
570                as *const crate::math::Vector3f)
571        }
572    }
573
574    pub fn set_maximum(&mut self, value: crate::math::Vector3f) {
575        // SAFETY: as above, in the other direction.
576        unsafe {
577            ffi::whiteout_m2_M2Extent_set_maximum(
578                self.raw.as_ptr(),
579                &value as *const crate::math::Vector3f as *const _,
580            )
581        }
582    }
583
584    pub fn sphere_radius(&self) -> f32 {
585        // SAFETY: plain scalar read through a live handle.
586        unsafe { ffi::whiteout_m2_M2Extent_get_sphereRadius(self.raw.as_ptr()) }
587    }
588
589    pub fn set_sphere_radius(&mut self, value: f32) {
590        // SAFETY: plain scalar write through a live handle.
591        unsafe { ffi::whiteout_m2_M2Extent_set_sphereRadius(self.raw.as_ptr(), value) }
592    }
593}
594
595impl Default for Extent {
596    fn default() -> Self {
597        Self::new()
598    }
599}
600
601pub struct AnimationTrackBase {
602    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2AnimationTrackBase>,
603}
604
605impl Drop for AnimationTrackBase {
606    fn drop(&mut self) {
607        // SAFETY: `raw` came from a native constructor and Drop runs once.
608        unsafe { ffi::whiteout_m2_M2AnimationTrackBase_delete(self.raw.as_ptr()) }
609    }
610}
611
612impl AnimationTrackBase {
613    /// # Safety
614    /// `raw` must be a live handle this value takes ownership of.
615    #[allow(dead_code)] // used by whichever methods return this type
616    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2AnimationTrackBase) -> Option<Self> {
617        core::ptr::NonNull::new(raw).map(|raw| AnimationTrackBase { raw })
618    }
619}
620
621// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
622// is deliberately NOT implemented — the C++ types make no documented
623// guarantee about concurrent use, and claiming one we haven't verified
624// would be unsound. See `@bind thread_safe` in the plan.
625unsafe impl Send for AnimationTrackBase {}
626
627impl core::fmt::Debug for AnimationTrackBase {
628    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
629        f.debug_struct("AnimationTrackBase").finish_non_exhaustive()
630    }
631}
632
633impl AnimationTrackBase {
634    /// # Panics
635    /// Panics if the native allocation fails.
636    pub fn new() -> Self {
637        // SAFETY: the native constructor returns a live handle; a null here
638        // means the library is unusable.
639        unsafe {
640            let raw = ffi::whiteout_m2_M2AnimationTrackBase_new();
641            Self::from_raw(raw).expect("native AnimationTrackBase allocation failed")
642        }
643    }
644
645    pub fn interpolation_type(&self) -> InterpolationType {
646        // SAFETY: scalar read; the discriminant is validated below.
647        unsafe { ffi::whiteout_m2_M2AnimationTrackBase_get_interpolationType(self.raw.as_ptr()) }
648            .try_into()
649            .expect("unknown enum discriminant from the native library")
650    }
651
652    pub fn set_interpolation_type(&mut self, value: InterpolationType) {
653        // SAFETY: scalar write through a live handle.
654        unsafe {
655            ffi::whiteout_m2_M2AnimationTrackBase_set_interpolationType(
656                self.raw.as_ptr(),
657                value as i32,
658            )
659        }
660    }
661
662    pub fn global_sequence_id(&self) -> u16 {
663        // SAFETY: plain scalar read through a live handle.
664        unsafe { ffi::whiteout_m2_M2AnimationTrackBase_get_globalSequenceId(self.raw.as_ptr()) }
665    }
666
667    pub fn set_global_sequence_id(&mut self, value: u16) {
668        // SAFETY: plain scalar write through a live handle.
669        unsafe {
670            ffi::whiteout_m2_M2AnimationTrackBase_set_globalSequenceId(self.raw.as_ptr(), value)
671        }
672    }
673
674    /// Number of inner sequences.
675    pub fn timestamps_len(&self) -> usize {
676        // SAFETY: scalar read through a live handle.
677        unsafe { ffi::whiteout_m2_M2AnimationTrackBase_get_timestamps_count(self.raw.as_ptr()) }
678    }
679
680    /// Zero-copy view of inner sequence `outer`. Empty when out of range.
681    ///
682    /// Each inner vector is contiguous on its own, but the outer one
683    /// is a vector of vectors — so this borrows per sequence rather
684    /// than handing back one flat slice.
685    pub fn timestamps(&self, outer: usize) -> &[u32] {
686        if outer >= self.timestamps_len() {
687            return &[];
688        }
689        // SAFETY: index checked; the pointer borrows `self`.
690        unsafe {
691            let n = ffi::whiteout_m2_M2AnimationTrackBase_get_timestamps_inner_count(
692                self.raw.as_ptr(),
693                outer,
694            );
695            let p = ffi::whiteout_m2_M2AnimationTrackBase_get_timestamps_inner_data(
696                self.raw.as_ptr(),
697                outer,
698            );
699            if p.is_null() || n == 0 {
700                &[]
701            } else {
702                core::slice::from_raw_parts(p, n)
703            }
704        }
705    }
706
707    pub fn timestamps_mut(&mut self, outer: usize) -> &mut [u32] {
708        if outer >= self.timestamps_len() {
709            return &mut [];
710        }
711        // SAFETY: as above; `&mut self` rules out aliasing.
712        unsafe {
713            let n = ffi::whiteout_m2_M2AnimationTrackBase_get_timestamps_inner_count(
714                self.raw.as_ptr(),
715                outer,
716            );
717            let p = ffi::whiteout_m2_M2AnimationTrackBase_get_timestamps_inner_data(
718                self.raw.as_ptr(),
719                outer,
720            ) as *mut u32;
721            if p.is_null() || n == 0 {
722                &mut []
723            } else {
724                core::slice::from_raw_parts_mut(p, n)
725            }
726        }
727    }
728
729    pub fn set_timestamps(&mut self, outer: usize, values: &[u32]) {
730        // SAFETY: the native side copies `values` before returning.
731        unsafe {
732            ffi::whiteout_m2_M2AnimationTrackBase_assign_timestamps_inner(
733                self.raw.as_ptr(),
734                outer,
735                values.as_ptr() as *const _,
736                values.len(),
737            )
738        }
739    }
740
741    /// Resize the outer sequence. Do this before taking any borrow.
742    pub fn resize_timestamps(&mut self, count: usize) {
743        // SAFETY: exclusive access, so no borrow is outstanding.
744        unsafe { ffi::whiteout_m2_M2AnimationTrackBase_resize_timestamps(self.raw.as_ptr(), count) }
745    }
746
747    pub fn resize_timestamps_inner(&mut self, outer: usize, count: usize) {
748        // SAFETY: as above.
749        unsafe {
750            ffi::whiteout_m2_M2AnimationTrackBase_resize_timestamps_inner(
751                self.raw.as_ptr(),
752                outer,
753                count,
754            )
755        }
756    }
757}
758
759impl Default for AnimationTrackBase {
760    fn default() -> Self {
761        Self::new()
762    }
763}
764
765pub struct ParticleEmitterExtension {
766    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2ParticleEmitterExtension>,
767}
768
769impl Drop for ParticleEmitterExtension {
770    fn drop(&mut self) {
771        // SAFETY: `raw` came from a native constructor and Drop runs once.
772        unsafe { ffi::whiteout_m2_M2ParticleEmitterExtension_delete(self.raw.as_ptr()) }
773    }
774}
775
776impl ParticleEmitterExtension {
777    /// # Safety
778    /// `raw` must be a live handle this value takes ownership of.
779    #[allow(dead_code)] // used by whichever methods return this type
780    pub(crate) unsafe fn from_raw(
781        raw: *mut ffi::whiteout_M2ParticleEmitterExtension,
782    ) -> Option<Self> {
783        core::ptr::NonNull::new(raw).map(|raw| ParticleEmitterExtension { raw })
784    }
785}
786
787// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
788// is deliberately NOT implemented — the C++ types make no documented
789// guarantee about concurrent use, and claiming one we haven't verified
790// would be unsound. See `@bind thread_safe` in the plan.
791unsafe impl Send for ParticleEmitterExtension {}
792
793impl core::fmt::Debug for ParticleEmitterExtension {
794    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
795        f.debug_struct("ParticleEmitterExtension")
796            .finish_non_exhaustive()
797    }
798}
799
800impl ParticleEmitterExtension {
801    /// # Panics
802    /// Panics if the native allocation fails.
803    pub fn new() -> Self {
804        // SAFETY: the native constructor returns a live handle; a null here
805        // means the library is unusable.
806        unsafe {
807            let raw = ffi::whiteout_m2_M2ParticleEmitterExtension_new();
808            Self::from_raw(raw).expect("native ParticleEmitterExtension allocation failed")
809        }
810    }
811
812    pub fn z_source(&self) -> f32 {
813        // SAFETY: plain scalar read through a live handle.
814        unsafe { ffi::whiteout_m2_M2ParticleEmitterExtension_get_zSource(self.raw.as_ptr()) }
815    }
816
817    pub fn set_z_source(&mut self, value: f32) {
818        // SAFETY: plain scalar write through a live handle.
819        unsafe { ffi::whiteout_m2_M2ParticleEmitterExtension_set_zSource(self.raw.as_ptr(), value) }
820    }
821
822    pub fn color_mult(&self) -> f32 {
823        // SAFETY: plain scalar read through a live handle.
824        unsafe { ffi::whiteout_m2_M2ParticleEmitterExtension_get_colorMult(self.raw.as_ptr()) }
825    }
826
827    pub fn set_color_mult(&mut self, value: f32) {
828        // SAFETY: plain scalar write through a live handle.
829        unsafe {
830            ffi::whiteout_m2_M2ParticleEmitterExtension_set_colorMult(self.raw.as_ptr(), value)
831        }
832    }
833
834    pub fn alpha_mult(&self) -> f32 {
835        // SAFETY: plain scalar read through a live handle.
836        unsafe { ffi::whiteout_m2_M2ParticleEmitterExtension_get_alphaMult(self.raw.as_ptr()) }
837    }
838
839    pub fn set_alpha_mult(&mut self, value: f32) {
840        // SAFETY: plain scalar write through a live handle.
841        unsafe {
842            ffi::whiteout_m2_M2ParticleEmitterExtension_set_alphaMult(self.raw.as_ptr(), value)
843        }
844    }
845}
846
847impl Default for ParticleEmitterExtension {
848    fn default() -> Self {
849        Self::new()
850    }
851}
852
853pub struct LodProfile {
854    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2LodProfile>,
855}
856
857impl Drop for LodProfile {
858    fn drop(&mut self) {
859        // SAFETY: `raw` came from a native constructor and Drop runs once.
860        unsafe { ffi::whiteout_m2_M2LodProfile_delete(self.raw.as_ptr()) }
861    }
862}
863
864impl LodProfile {
865    /// # Safety
866    /// `raw` must be a live handle this value takes ownership of.
867    #[allow(dead_code)] // used by whichever methods return this type
868    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2LodProfile) -> Option<Self> {
869        core::ptr::NonNull::new(raw).map(|raw| LodProfile { raw })
870    }
871}
872
873// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
874// is deliberately NOT implemented — the C++ types make no documented
875// guarantee about concurrent use, and claiming one we haven't verified
876// would be unsound. See `@bind thread_safe` in the plan.
877unsafe impl Send for LodProfile {}
878
879impl core::fmt::Debug for LodProfile {
880    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
881        f.debug_struct("LodProfile").finish_non_exhaustive()
882    }
883}
884
885impl LodProfile {
886    /// # Panics
887    /// Panics if the native allocation fails.
888    pub fn new() -> Self {
889        // SAFETY: the native constructor returns a live handle; a null here
890        // means the library is unusable.
891        unsafe {
892            let raw = ffi::whiteout_m2_M2LodProfile_new();
893            Self::from_raw(raw).expect("native LodProfile allocation failed")
894        }
895    }
896
897    pub fn flags(&self) -> u16 {
898        // SAFETY: plain scalar read through a live handle.
899        unsafe { ffi::whiteout_m2_M2LodProfile_get_flags(self.raw.as_ptr()) }
900    }
901
902    pub fn set_flags(&mut self, value: u16) {
903        // SAFETY: plain scalar write through a live handle.
904        unsafe { ffi::whiteout_m2_M2LodProfile_set_flags(self.raw.as_ptr(), value) }
905    }
906
907    pub fn num_lod_levels(&self) -> u16 {
908        // SAFETY: plain scalar read through a live handle.
909        unsafe { ffi::whiteout_m2_M2LodProfile_get_numLodLevels(self.raw.as_ptr()) }
910    }
911
912    pub fn set_num_lod_levels(&mut self, value: u16) {
913        // SAFETY: plain scalar write through a live handle.
914        unsafe { ffi::whiteout_m2_M2LodProfile_set_numLodLevels(self.raw.as_ptr(), value) }
915    }
916
917    pub fn lod_distance(&self) -> f32 {
918        // SAFETY: plain scalar read through a live handle.
919        unsafe { ffi::whiteout_m2_M2LodProfile_get_lodDistance(self.raw.as_ptr()) }
920    }
921
922    pub fn set_lod_distance(&mut self, value: f32) {
923        // SAFETY: plain scalar write through a live handle.
924        unsafe { ffi::whiteout_m2_M2LodProfile_set_lodDistance(self.raw.as_ptr(), value) }
925    }
926
927    pub fn particle_bone_lod_len() -> usize {
928        // SAFETY: a compile-time constant on the native side.
929        unsafe { ffi::whiteout_m2_M2LodProfile_particleBoneLod_size() }
930    }
931
932    pub fn particle_bone_lod(&self, index: usize) -> u8 {
933        // SAFETY: scalar read. The native side does not bounds-
934        // check, so callers stay within `particle_bone_lod_len()`.
935        unsafe { ffi::whiteout_m2_M2LodProfile_get_particleBoneLod_at(self.raw.as_ptr(), index) }
936    }
937
938    pub fn set_particle_bone_lod(&mut self, index: usize, value: u8) {
939        // SAFETY: as above.
940        unsafe {
941            ffi::whiteout_m2_M2LodProfile_set_particleBoneLod_at(self.raw.as_ptr(), index, value)
942        }
943    }
944
945    pub fn reserved_0(&self) -> u8 {
946        // SAFETY: plain scalar read through a live handle.
947        unsafe { ffi::whiteout_m2_M2LodProfile_get_reserved0(self.raw.as_ptr()) }
948    }
949
950    pub fn set_reserved_0(&mut self, value: u8) {
951        // SAFETY: plain scalar write through a live handle.
952        unsafe { ffi::whiteout_m2_M2LodProfile_set_reserved0(self.raw.as_ptr(), value) }
953    }
954
955    pub fn lod_flags(&self) -> u8 {
956        // SAFETY: plain scalar read through a live handle.
957        unsafe { ffi::whiteout_m2_M2LodProfile_get_lodFlags(self.raw.as_ptr()) }
958    }
959
960    pub fn set_lod_flags(&mut self, value: u8) {
961        // SAFETY: plain scalar write through a live handle.
962        unsafe { ffi::whiteout_m2_M2LodProfile_set_lodFlags(self.raw.as_ptr(), value) }
963    }
964
965    pub fn lod_batch_count(&self) -> u8 {
966        // SAFETY: plain scalar read through a live handle.
967        unsafe { ffi::whiteout_m2_M2LodProfile_get_lodBatchCount(self.raw.as_ptr()) }
968    }
969
970    pub fn set_lod_batch_count(&mut self, value: u8) {
971        // SAFETY: plain scalar write through a live handle.
972        unsafe { ffi::whiteout_m2_M2LodProfile_set_lodBatchCount(self.raw.as_ptr(), value) }
973    }
974
975    pub fn reserved_1(&self) -> u8 {
976        // SAFETY: plain scalar read through a live handle.
977        unsafe { ffi::whiteout_m2_M2LodProfile_get_reserved1(self.raw.as_ptr()) }
978    }
979
980    pub fn set_reserved_1(&mut self, value: u8) {
981        // SAFETY: plain scalar write through a live handle.
982        unsafe { ffi::whiteout_m2_M2LodProfile_set_reserved1(self.raw.as_ptr(), value) }
983    }
984}
985
986impl Default for LodProfile {
987    fn default() -> Self {
988        Self::new()
989    }
990}
991
992pub struct WaterfallData {
993    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2WaterfallData>,
994}
995
996impl Drop for WaterfallData {
997    fn drop(&mut self) {
998        // SAFETY: `raw` came from a native constructor and Drop runs once.
999        unsafe { ffi::whiteout_m2_M2WaterfallData_delete(self.raw.as_ptr()) }
1000    }
1001}
1002
1003impl WaterfallData {
1004    /// # Safety
1005    /// `raw` must be a live handle this value takes ownership of.
1006    #[allow(dead_code)] // used by whichever methods return this type
1007    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2WaterfallData) -> Option<Self> {
1008        core::ptr::NonNull::new(raw).map(|raw| WaterfallData { raw })
1009    }
1010}
1011
1012// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
1013// is deliberately NOT implemented — the C++ types make no documented
1014// guarantee about concurrent use, and claiming one we haven't verified
1015// would be unsound. See `@bind thread_safe` in the plan.
1016unsafe impl Send for WaterfallData {}
1017
1018impl core::fmt::Debug for WaterfallData {
1019    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1020        f.debug_struct("WaterfallData").finish_non_exhaustive()
1021    }
1022}
1023
1024impl WaterfallData {
1025    /// # Panics
1026    /// Panics if the native allocation fails.
1027    pub fn new() -> Self {
1028        // SAFETY: the native constructor returns a live handle; a null here
1029        // means the library is unusable.
1030        unsafe {
1031            let raw = ffi::whiteout_m2_M2WaterfallData_new();
1032            Self::from_raw(raw).expect("native WaterfallData allocation failed")
1033        }
1034    }
1035
1036    pub fn bump_scale(&self) -> f32 {
1037        // SAFETY: plain scalar read through a live handle.
1038        unsafe { ffi::whiteout_m2_M2WaterfallData_get_bumpScale(self.raw.as_ptr()) }
1039    }
1040
1041    pub fn set_bump_scale(&mut self, value: f32) {
1042        // SAFETY: plain scalar write through a live handle.
1043        unsafe { ffi::whiteout_m2_M2WaterfallData_set_bumpScale(self.raw.as_ptr(), value) }
1044    }
1045
1046    pub fn value_0x(&self) -> f32 {
1047        // SAFETY: plain scalar read through a live handle.
1048        unsafe { ffi::whiteout_m2_M2WaterfallData_get_value0_x(self.raw.as_ptr()) }
1049    }
1050
1051    pub fn set_value_0x(&mut self, value: f32) {
1052        // SAFETY: plain scalar write through a live handle.
1053        unsafe { ffi::whiteout_m2_M2WaterfallData_set_value0_x(self.raw.as_ptr(), value) }
1054    }
1055
1056    pub fn value_0y(&self) -> f32 {
1057        // SAFETY: plain scalar read through a live handle.
1058        unsafe { ffi::whiteout_m2_M2WaterfallData_get_value0_y(self.raw.as_ptr()) }
1059    }
1060
1061    pub fn set_value_0y(&mut self, value: f32) {
1062        // SAFETY: plain scalar write through a live handle.
1063        unsafe { ffi::whiteout_m2_M2WaterfallData_set_value0_y(self.raw.as_ptr(), value) }
1064    }
1065
1066    pub fn value_0z(&self) -> f32 {
1067        // SAFETY: plain scalar read through a live handle.
1068        unsafe { ffi::whiteout_m2_M2WaterfallData_get_value0_z(self.raw.as_ptr()) }
1069    }
1070
1071    pub fn set_value_0z(&mut self, value: f32) {
1072        // SAFETY: plain scalar write through a live handle.
1073        unsafe { ffi::whiteout_m2_M2WaterfallData_set_value0_z(self.raw.as_ptr(), value) }
1074    }
1075
1076    pub fn value_1w(&self) -> f32 {
1077        // SAFETY: plain scalar read through a live handle.
1078        unsafe { ffi::whiteout_m2_M2WaterfallData_get_value1_w(self.raw.as_ptr()) }
1079    }
1080
1081    pub fn set_value_1w(&mut self, value: f32) {
1082        // SAFETY: plain scalar write through a live handle.
1083        unsafe { ffi::whiteout_m2_M2WaterfallData_set_value1_w(self.raw.as_ptr(), value) }
1084    }
1085
1086    pub fn value_0w(&self) -> f32 {
1087        // SAFETY: plain scalar read through a live handle.
1088        unsafe { ffi::whiteout_m2_M2WaterfallData_get_value0_w(self.raw.as_ptr()) }
1089    }
1090
1091    pub fn set_value_0w(&mut self, value: f32) {
1092        // SAFETY: plain scalar write through a live handle.
1093        unsafe { ffi::whiteout_m2_M2WaterfallData_set_value0_w(self.raw.as_ptr(), value) }
1094    }
1095
1096    pub fn value_1x(&self) -> f32 {
1097        // SAFETY: plain scalar read through a live handle.
1098        unsafe { ffi::whiteout_m2_M2WaterfallData_get_value1_x(self.raw.as_ptr()) }
1099    }
1100
1101    pub fn set_value_1x(&mut self, value: f32) {
1102        // SAFETY: plain scalar write through a live handle.
1103        unsafe { ffi::whiteout_m2_M2WaterfallData_set_value1_x(self.raw.as_ptr(), value) }
1104    }
1105
1106    pub fn value_1y(&self) -> f32 {
1107        // SAFETY: plain scalar read through a live handle.
1108        unsafe { ffi::whiteout_m2_M2WaterfallData_get_value1_y(self.raw.as_ptr()) }
1109    }
1110
1111    pub fn set_value_1y(&mut self, value: f32) {
1112        // SAFETY: plain scalar write through a live handle.
1113        unsafe { ffi::whiteout_m2_M2WaterfallData_set_value1_y(self.raw.as_ptr(), value) }
1114    }
1115
1116    pub fn value_2w(&self) -> f32 {
1117        // SAFETY: plain scalar read through a live handle.
1118        unsafe { ffi::whiteout_m2_M2WaterfallData_get_value2_w(self.raw.as_ptr()) }
1119    }
1120
1121    pub fn set_value_2w(&mut self, value: f32) {
1122        // SAFETY: plain scalar write through a live handle.
1123        unsafe { ffi::whiteout_m2_M2WaterfallData_set_value2_w(self.raw.as_ptr(), value) }
1124    }
1125
1126    pub fn value_3y(&self) -> f32 {
1127        // SAFETY: plain scalar read through a live handle.
1128        unsafe { ffi::whiteout_m2_M2WaterfallData_get_value3_y(self.raw.as_ptr()) }
1129    }
1130
1131    pub fn set_value_3y(&mut self, value: f32) {
1132        // SAFETY: plain scalar write through a live handle.
1133        unsafe { ffi::whiteout_m2_M2WaterfallData_set_value3_y(self.raw.as_ptr(), value) }
1134    }
1135
1136    pub fn value_3x(&self) -> f32 {
1137        // SAFETY: plain scalar read through a live handle.
1138        unsafe { ffi::whiteout_m2_M2WaterfallData_get_value3_x(self.raw.as_ptr()) }
1139    }
1140
1141    pub fn set_value_3x(&mut self, value: f32) {
1142        // SAFETY: plain scalar write through a live handle.
1143        unsafe { ffi::whiteout_m2_M2WaterfallData_set_value3_x(self.raw.as_ptr(), value) }
1144    }
1145
1146    pub fn base_color(&self) -> crate::math::Vector4f {
1147        // SAFETY: the getter returns an interior pointer to a
1148        // layout-identical POD; we copy it out immediately.
1149        unsafe {
1150            *(ffi::whiteout_m2_M2WaterfallData_get_baseColor(self.raw.as_ptr())
1151                as *const crate::math::Vector4f)
1152        }
1153    }
1154
1155    pub fn set_base_color(&mut self, value: crate::math::Vector4f) {
1156        // SAFETY: as above, in the other direction.
1157        unsafe {
1158            ffi::whiteout_m2_M2WaterfallData_set_baseColor(
1159                self.raw.as_ptr(),
1160                &value as *const crate::math::Vector4f as *const _,
1161            )
1162        }
1163    }
1164
1165    pub fn flags(&self) -> u16 {
1166        // SAFETY: plain scalar read through a live handle.
1167        unsafe { ffi::whiteout_m2_M2WaterfallData_get_flags(self.raw.as_ptr()) }
1168    }
1169
1170    pub fn set_flags(&mut self, value: u16) {
1171        // SAFETY: plain scalar write through a live handle.
1172        unsafe { ffi::whiteout_m2_M2WaterfallData_set_flags(self.raw.as_ptr(), value) }
1173    }
1174
1175    pub fn unknown_0(&self) -> u16 {
1176        // SAFETY: plain scalar read through a live handle.
1177        unsafe { ffi::whiteout_m2_M2WaterfallData_get_unknown0(self.raw.as_ptr()) }
1178    }
1179
1180    pub fn set_unknown_0(&mut self, value: u16) {
1181        // SAFETY: plain scalar write through a live handle.
1182        unsafe { ffi::whiteout_m2_M2WaterfallData_set_unknown0(self.raw.as_ptr(), value) }
1183    }
1184
1185    pub fn value_3w(&self) -> f32 {
1186        // SAFETY: plain scalar read through a live handle.
1187        unsafe { ffi::whiteout_m2_M2WaterfallData_get_value3_w(self.raw.as_ptr()) }
1188    }
1189
1190    pub fn set_value_3w(&mut self, value: f32) {
1191        // SAFETY: plain scalar write through a live handle.
1192        unsafe { ffi::whiteout_m2_M2WaterfallData_set_value3_w(self.raw.as_ptr(), value) }
1193    }
1194
1195    pub fn value_3z(&self) -> f32 {
1196        // SAFETY: plain scalar read through a live handle.
1197        unsafe { ffi::whiteout_m2_M2WaterfallData_get_value3_z(self.raw.as_ptr()) }
1198    }
1199
1200    pub fn set_value_3z(&mut self, value: f32) {
1201        // SAFETY: plain scalar write through a live handle.
1202        unsafe { ffi::whiteout_m2_M2WaterfallData_set_value3_z(self.raw.as_ptr(), value) }
1203    }
1204
1205    pub fn value_4y(&self) -> f32 {
1206        // SAFETY: plain scalar read through a live handle.
1207        unsafe { ffi::whiteout_m2_M2WaterfallData_get_value4_y(self.raw.as_ptr()) }
1208    }
1209
1210    pub fn set_value_4y(&mut self, value: f32) {
1211        // SAFETY: plain scalar write through a live handle.
1212        unsafe { ffi::whiteout_m2_M2WaterfallData_set_value4_y(self.raw.as_ptr(), value) }
1213    }
1214
1215    pub fn unknown_1(&self) -> f32 {
1216        // SAFETY: plain scalar read through a live handle.
1217        unsafe { ffi::whiteout_m2_M2WaterfallData_get_unknown1(self.raw.as_ptr()) }
1218    }
1219
1220    pub fn set_unknown_1(&mut self, value: f32) {
1221        // SAFETY: plain scalar write through a live handle.
1222        unsafe { ffi::whiteout_m2_M2WaterfallData_set_unknown1(self.raw.as_ptr(), value) }
1223    }
1224
1225    pub fn unknown_2(&self) -> f32 {
1226        // SAFETY: plain scalar read through a live handle.
1227        unsafe { ffi::whiteout_m2_M2WaterfallData_get_unknown2(self.raw.as_ptr()) }
1228    }
1229
1230    pub fn set_unknown_2(&mut self, value: f32) {
1231        // SAFETY: plain scalar write through a live handle.
1232        unsafe { ffi::whiteout_m2_M2WaterfallData_set_unknown2(self.raw.as_ptr(), value) }
1233    }
1234
1235    pub fn unknown_3(&self) -> f32 {
1236        // SAFETY: plain scalar read through a live handle.
1237        unsafe { ffi::whiteout_m2_M2WaterfallData_get_unknown3(self.raw.as_ptr()) }
1238    }
1239
1240    pub fn set_unknown_3(&mut self, value: f32) {
1241        // SAFETY: plain scalar write through a live handle.
1242        unsafe { ffi::whiteout_m2_M2WaterfallData_set_unknown3(self.raw.as_ptr(), value) }
1243    }
1244
1245    pub fn unknown_4(&self) -> f32 {
1246        // SAFETY: plain scalar read through a live handle.
1247        unsafe { ffi::whiteout_m2_M2WaterfallData_get_unknown4(self.raw.as_ptr()) }
1248    }
1249
1250    pub fn set_unknown_4(&mut self, value: f32) {
1251        // SAFETY: plain scalar write through a live handle.
1252        unsafe { ffi::whiteout_m2_M2WaterfallData_set_unknown4(self.raw.as_ptr(), value) }
1253    }
1254}
1255
1256impl Default for WaterfallData {
1257    fn default() -> Self {
1258        Self::new()
1259    }
1260}
1261
1262pub struct ParticleGeosetData {
1263    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2ParticleGeosetData>,
1264}
1265
1266impl Drop for ParticleGeosetData {
1267    fn drop(&mut self) {
1268        // SAFETY: `raw` came from a native constructor and Drop runs once.
1269        unsafe { ffi::whiteout_m2_M2ParticleGeosetData_delete(self.raw.as_ptr()) }
1270    }
1271}
1272
1273impl ParticleGeosetData {
1274    /// # Safety
1275    /// `raw` must be a live handle this value takes ownership of.
1276    #[allow(dead_code)] // used by whichever methods return this type
1277    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2ParticleGeosetData) -> Option<Self> {
1278        core::ptr::NonNull::new(raw).map(|raw| ParticleGeosetData { raw })
1279    }
1280}
1281
1282// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
1283// is deliberately NOT implemented — the C++ types make no documented
1284// guarantee about concurrent use, and claiming one we haven't verified
1285// would be unsound. See `@bind thread_safe` in the plan.
1286unsafe impl Send for ParticleGeosetData {}
1287
1288impl core::fmt::Debug for ParticleGeosetData {
1289    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1290        f.debug_struct("ParticleGeosetData").finish_non_exhaustive()
1291    }
1292}
1293
1294impl ParticleGeosetData {
1295    /// # Panics
1296    /// Panics if the native allocation fails.
1297    pub fn new() -> Self {
1298        // SAFETY: the native constructor returns a live handle; a null here
1299        // means the library is unusable.
1300        unsafe {
1301            let raw = ffi::whiteout_m2_M2ParticleGeosetData_new();
1302            Self::from_raw(raw).expect("native ParticleGeosetData allocation failed")
1303        }
1304    }
1305
1306    pub fn geoset(&self) -> u16 {
1307        // SAFETY: plain scalar read through a live handle.
1308        unsafe { ffi::whiteout_m2_M2ParticleGeosetData_get_geoset(self.raw.as_ptr()) }
1309    }
1310
1311    pub fn set_geoset(&mut self, value: u16) {
1312        // SAFETY: plain scalar write through a live handle.
1313        unsafe { ffi::whiteout_m2_M2ParticleGeosetData_set_geoset(self.raw.as_ptr(), value) }
1314    }
1315}
1316
1317impl Default for ParticleGeosetData {
1318    fn default() -> Self {
1319        Self::new()
1320    }
1321}
1322
1323pub struct EdgeFadeData {
1324    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2EdgeFadeData>,
1325}
1326
1327impl Drop for EdgeFadeData {
1328    fn drop(&mut self) {
1329        // SAFETY: `raw` came from a native constructor and Drop runs once.
1330        unsafe { ffi::whiteout_m2_M2EdgeFadeData_delete(self.raw.as_ptr()) }
1331    }
1332}
1333
1334impl EdgeFadeData {
1335    /// # Safety
1336    /// `raw` must be a live handle this value takes ownership of.
1337    #[allow(dead_code)] // used by whichever methods return this type
1338    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2EdgeFadeData) -> Option<Self> {
1339        core::ptr::NonNull::new(raw).map(|raw| EdgeFadeData { raw })
1340    }
1341}
1342
1343// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
1344// is deliberately NOT implemented — the C++ types make no documented
1345// guarantee about concurrent use, and claiming one we haven't verified
1346// would be unsound. See `@bind thread_safe` in the plan.
1347unsafe impl Send for EdgeFadeData {}
1348
1349impl core::fmt::Debug for EdgeFadeData {
1350    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1351        f.debug_struct("EdgeFadeData").finish_non_exhaustive()
1352    }
1353}
1354
1355impl EdgeFadeData {
1356    /// # Panics
1357    /// Panics if the native allocation fails.
1358    pub fn new() -> Self {
1359        // SAFETY: the native constructor returns a live handle; a null here
1360        // means the library is unusable.
1361        unsafe {
1362            let raw = ffi::whiteout_m2_M2EdgeFadeData_new();
1363            Self::from_raw(raw).expect("native EdgeFadeData allocation failed")
1364        }
1365    }
1366
1367    pub fn value_0_len() -> usize {
1368        // SAFETY: a compile-time constant on the native side.
1369        unsafe { ffi::whiteout_m2_M2EdgeFadeData_value0_size() }
1370    }
1371
1372    pub fn value_0(&self, index: usize) -> f32 {
1373        // SAFETY: scalar read. The native side does not bounds-
1374        // check, so callers stay within `value_0_len()`.
1375        unsafe { ffi::whiteout_m2_M2EdgeFadeData_get_value0_at(self.raw.as_ptr(), index) }
1376    }
1377
1378    pub fn set_value_0(&mut self, index: usize, value: f32) {
1379        // SAFETY: as above.
1380        unsafe { ffi::whiteout_m2_M2EdgeFadeData_set_value0_at(self.raw.as_ptr(), index, value) }
1381    }
1382
1383    pub fn value_8(&self) -> f32 {
1384        // SAFETY: plain scalar read through a live handle.
1385        unsafe { ffi::whiteout_m2_M2EdgeFadeData_get_value8(self.raw.as_ptr()) }
1386    }
1387
1388    pub fn set_value_8(&mut self, value: f32) {
1389        // SAFETY: plain scalar write through a live handle.
1390        unsafe { ffi::whiteout_m2_M2EdgeFadeData_set_value8(self.raw.as_ptr(), value) }
1391    }
1392
1393    pub fn value_c_len() -> usize {
1394        // SAFETY: a compile-time constant on the native side.
1395        unsafe { ffi::whiteout_m2_M2EdgeFadeData_valueC_size() }
1396    }
1397
1398    pub fn value_c(&self, index: usize) -> u8 {
1399        // SAFETY: scalar read. The native side does not bounds-
1400        // check, so callers stay within `value_c_len()`.
1401        unsafe { ffi::whiteout_m2_M2EdgeFadeData_get_valueC_at(self.raw.as_ptr(), index) }
1402    }
1403
1404    pub fn set_value_c(&mut self, index: usize, value: u8) {
1405        // SAFETY: as above.
1406        unsafe { ffi::whiteout_m2_M2EdgeFadeData_set_valueC_at(self.raw.as_ptr(), index, value) }
1407    }
1408}
1409
1410impl Default for EdgeFadeData {
1411    fn default() -> Self {
1412        Self::new()
1413    }
1414}
1415
1416pub struct DistanceFadeData {
1417    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2DistanceFadeData>,
1418}
1419
1420impl Drop for DistanceFadeData {
1421    fn drop(&mut self) {
1422        // SAFETY: `raw` came from a native constructor and Drop runs once.
1423        unsafe { ffi::whiteout_m2_M2DistanceFadeData_delete(self.raw.as_ptr()) }
1424    }
1425}
1426
1427impl DistanceFadeData {
1428    /// # Safety
1429    /// `raw` must be a live handle this value takes ownership of.
1430    #[allow(dead_code)] // used by whichever methods return this type
1431    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2DistanceFadeData) -> Option<Self> {
1432        core::ptr::NonNull::new(raw).map(|raw| DistanceFadeData { raw })
1433    }
1434}
1435
1436// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
1437// is deliberately NOT implemented — the C++ types make no documented
1438// guarantee about concurrent use, and claiming one we haven't verified
1439// would be unsound. See `@bind thread_safe` in the plan.
1440unsafe impl Send for DistanceFadeData {}
1441
1442impl core::fmt::Debug for DistanceFadeData {
1443    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1444        f.debug_struct("DistanceFadeData").finish_non_exhaustive()
1445    }
1446}
1447
1448impl DistanceFadeData {
1449    /// # Panics
1450    /// Panics if the native allocation fails.
1451    pub fn new() -> Self {
1452        // SAFETY: the native constructor returns a live handle; a null here
1453        // means the library is unusable.
1454        unsafe {
1455            let raw = ffi::whiteout_m2_M2DistanceFadeData_new();
1456            Self::from_raw(raw).expect("native DistanceFadeData allocation failed")
1457        }
1458    }
1459
1460    pub fn squared_far_dist(&self) -> f32 {
1461        // SAFETY: plain scalar read through a live handle.
1462        unsafe { ffi::whiteout_m2_M2DistanceFadeData_get_squaredFarDist(self.raw.as_ptr()) }
1463    }
1464
1465    pub fn set_squared_far_dist(&mut self, value: f32) {
1466        // SAFETY: plain scalar write through a live handle.
1467        unsafe { ffi::whiteout_m2_M2DistanceFadeData_set_squaredFarDist(self.raw.as_ptr(), value) }
1468    }
1469
1470    pub fn squared_near_dist(&self) -> f32 {
1471        // SAFETY: plain scalar read through a live handle.
1472        unsafe { ffi::whiteout_m2_M2DistanceFadeData_get_squaredNearDist(self.raw.as_ptr()) }
1473    }
1474
1475    pub fn set_squared_near_dist(&mut self, value: f32) {
1476        // SAFETY: plain scalar write through a live handle.
1477        unsafe { ffi::whiteout_m2_M2DistanceFadeData_set_squaredNearDist(self.raw.as_ptr(), value) }
1478    }
1479
1480    pub fn reserved_len() -> usize {
1481        // SAFETY: a compile-time constant on the native side.
1482        unsafe { ffi::whiteout_m2_M2DistanceFadeData_reserved_size() }
1483    }
1484
1485    pub fn reserved(&self, index: usize) -> u32 {
1486        // SAFETY: scalar read. The native side does not bounds-
1487        // check, so callers stay within `reserved_len()`.
1488        unsafe { ffi::whiteout_m2_M2DistanceFadeData_get_reserved_at(self.raw.as_ptr(), index) }
1489    }
1490
1491    pub fn set_reserved(&mut self, index: usize, value: u32) {
1492        // SAFETY: as above.
1493        unsafe {
1494            ffi::whiteout_m2_M2DistanceFadeData_set_reserved_at(self.raw.as_ptr(), index, value)
1495        }
1496    }
1497}
1498
1499impl Default for DistanceFadeData {
1500    fn default() -> Self {
1501        Self::new()
1502    }
1503}
1504
1505pub struct DetailedLightData {
1506    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2DetailedLightData>,
1507}
1508
1509impl Drop for DetailedLightData {
1510    fn drop(&mut self) {
1511        // SAFETY: `raw` came from a native constructor and Drop runs once.
1512        unsafe { ffi::whiteout_m2_M2DetailedLightData_delete(self.raw.as_ptr()) }
1513    }
1514}
1515
1516impl DetailedLightData {
1517    /// # Safety
1518    /// `raw` must be a live handle this value takes ownership of.
1519    #[allow(dead_code)] // used by whichever methods return this type
1520    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2DetailedLightData) -> Option<Self> {
1521        core::ptr::NonNull::new(raw).map(|raw| DetailedLightData { raw })
1522    }
1523}
1524
1525// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
1526// is deliberately NOT implemented — the C++ types make no documented
1527// guarantee about concurrent use, and claiming one we haven't verified
1528// would be unsound. See `@bind thread_safe` in the plan.
1529unsafe impl Send for DetailedLightData {}
1530
1531impl core::fmt::Debug for DetailedLightData {
1532    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1533        f.debug_struct("DetailedLightData").finish_non_exhaustive()
1534    }
1535}
1536
1537impl DetailedLightData {
1538    /// # Panics
1539    /// Panics if the native allocation fails.
1540    pub fn new() -> Self {
1541        // SAFETY: the native constructor returns a live handle; a null here
1542        // means the library is unusable.
1543        unsafe {
1544            let raw = ffi::whiteout_m2_M2DetailedLightData_new();
1545            Self::from_raw(raw).expect("native DetailedLightData allocation failed")
1546        }
1547    }
1548
1549    pub fn flags(&self) -> u16 {
1550        // SAFETY: plain scalar read through a live handle.
1551        unsafe { ffi::whiteout_m2_M2DetailedLightData_get_flags(self.raw.as_ptr()) }
1552    }
1553
1554    pub fn set_flags(&mut self, value: u16) {
1555        // SAFETY: plain scalar write through a live handle.
1556        unsafe { ffi::whiteout_m2_M2DetailedLightData_set_flags(self.raw.as_ptr(), value) }
1557    }
1558
1559    pub fn unknown_0(&self) -> u16 {
1560        // SAFETY: plain scalar read through a live handle.
1561        unsafe { ffi::whiteout_m2_M2DetailedLightData_get_unknown0(self.raw.as_ptr()) }
1562    }
1563
1564    pub fn set_unknown_0(&mut self, value: u16) {
1565        // SAFETY: plain scalar write through a live handle.
1566        unsafe { ffi::whiteout_m2_M2DetailedLightData_set_unknown0(self.raw.as_ptr(), value) }
1567    }
1568
1569    pub fn unknown_1(&self) -> u32 {
1570        // SAFETY: plain scalar read through a live handle.
1571        unsafe { ffi::whiteout_m2_M2DetailedLightData_get_unknown1(self.raw.as_ptr()) }
1572    }
1573
1574    pub fn set_unknown_1(&mut self, value: u32) {
1575        // SAFETY: plain scalar write through a live handle.
1576        unsafe { ffi::whiteout_m2_M2DetailedLightData_set_unknown1(self.raw.as_ptr(), value) }
1577    }
1578}
1579
1580impl Default for DetailedLightData {
1581    fn default() -> Self {
1582        Self::new()
1583    }
1584}
1585
1586pub struct DebugOcclusionData {
1587    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2DebugOcclusionData>,
1588}
1589
1590impl Drop for DebugOcclusionData {
1591    fn drop(&mut self) {
1592        // SAFETY: `raw` came from a native constructor and Drop runs once.
1593        unsafe { ffi::whiteout_m2_M2DebugOcclusionData_delete(self.raw.as_ptr()) }
1594    }
1595}
1596
1597impl DebugOcclusionData {
1598    /// # Safety
1599    /// `raw` must be a live handle this value takes ownership of.
1600    #[allow(dead_code)] // used by whichever methods return this type
1601    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2DebugOcclusionData) -> Option<Self> {
1602        core::ptr::NonNull::new(raw).map(|raw| DebugOcclusionData { raw })
1603    }
1604}
1605
1606// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
1607// is deliberately NOT implemented — the C++ types make no documented
1608// guarantee about concurrent use, and claiming one we haven't verified
1609// would be unsound. See `@bind thread_safe` in the plan.
1610unsafe impl Send for DebugOcclusionData {}
1611
1612impl core::fmt::Debug for DebugOcclusionData {
1613    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1614        f.debug_struct("DebugOcclusionData").finish_non_exhaustive()
1615    }
1616}
1617
1618impl DebugOcclusionData {
1619    /// # Panics
1620    /// Panics if the native allocation fails.
1621    pub fn new() -> Self {
1622        // SAFETY: the native constructor returns a live handle; a null here
1623        // means the library is unusable.
1624        unsafe {
1625            let raw = ffi::whiteout_m2_M2DebugOcclusionData_new();
1626            Self::from_raw(raw).expect("native DebugOcclusionData allocation failed")
1627        }
1628    }
1629
1630    pub fn unknown_1_1(&self) -> f32 {
1631        // SAFETY: plain scalar read through a live handle.
1632        unsafe { ffi::whiteout_m2_M2DebugOcclusionData_get_unknown1_1(self.raw.as_ptr()) }
1633    }
1634
1635    pub fn set_unknown_1_1(&mut self, value: f32) {
1636        // SAFETY: plain scalar write through a live handle.
1637        unsafe { ffi::whiteout_m2_M2DebugOcclusionData_set_unknown1_1(self.raw.as_ptr(), value) }
1638    }
1639
1640    pub fn unknown_1_2(&self) -> f32 {
1641        // SAFETY: plain scalar read through a live handle.
1642        unsafe { ffi::whiteout_m2_M2DebugOcclusionData_get_unknown1_2(self.raw.as_ptr()) }
1643    }
1644
1645    pub fn set_unknown_1_2(&mut self, value: f32) {
1646        // SAFETY: plain scalar write through a live handle.
1647        unsafe { ffi::whiteout_m2_M2DebugOcclusionData_set_unknown1_2(self.raw.as_ptr(), value) }
1648    }
1649
1650    pub fn unknown_1_3(&self) -> u32 {
1651        // SAFETY: plain scalar read through a live handle.
1652        unsafe { ffi::whiteout_m2_M2DebugOcclusionData_get_unknown1_3(self.raw.as_ptr()) }
1653    }
1654
1655    pub fn set_unknown_1_3(&mut self, value: u32) {
1656        // SAFETY: plain scalar write through a live handle.
1657        unsafe { ffi::whiteout_m2_M2DebugOcclusionData_set_unknown1_3(self.raw.as_ptr(), value) }
1658    }
1659
1660    pub fn unknown_1_4(&self) -> u32 {
1661        // SAFETY: plain scalar read through a live handle.
1662        unsafe { ffi::whiteout_m2_M2DebugOcclusionData_get_unknown1_4(self.raw.as_ptr()) }
1663    }
1664
1665    pub fn set_unknown_1_4(&mut self, value: u32) {
1666        // SAFETY: plain scalar write through a live handle.
1667        unsafe { ffi::whiteout_m2_M2DebugOcclusionData_set_unknown1_4(self.raw.as_ptr(), value) }
1668    }
1669}
1670
1671impl Default for DebugOcclusionData {
1672    fn default() -> Self {
1673        Self::new()
1674    }
1675}
1676
1677pub struct TexturedLightData {
1678    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2TexturedLightData>,
1679}
1680
1681impl Drop for TexturedLightData {
1682    fn drop(&mut self) {
1683        // SAFETY: `raw` came from a native constructor and Drop runs once.
1684        unsafe { ffi::whiteout_m2_M2TexturedLightData_delete(self.raw.as_ptr()) }
1685    }
1686}
1687
1688impl TexturedLightData {
1689    /// # Safety
1690    /// `raw` must be a live handle this value takes ownership of.
1691    #[allow(dead_code)] // used by whichever methods return this type
1692    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2TexturedLightData) -> Option<Self> {
1693        core::ptr::NonNull::new(raw).map(|raw| TexturedLightData { raw })
1694    }
1695}
1696
1697// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
1698// is deliberately NOT implemented — the C++ types make no documented
1699// guarantee about concurrent use, and claiming one we haven't verified
1700// would be unsound. See `@bind thread_safe` in the plan.
1701unsafe impl Send for TexturedLightData {}
1702
1703impl core::fmt::Debug for TexturedLightData {
1704    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1705        f.debug_struct("TexturedLightData").finish_non_exhaustive()
1706    }
1707}
1708
1709impl TexturedLightData {
1710    /// # Panics
1711    /// Panics if the native allocation fails.
1712    pub fn new() -> Self {
1713        // SAFETY: the native constructor returns a live handle; a null here
1714        // means the library is unusable.
1715        unsafe {
1716            let raw = ffi::whiteout_m2_M2TexturedLightData_new();
1717            Self::from_raw(raw).expect("native TexturedLightData allocation failed")
1718        }
1719    }
1720
1721    pub fn unknown_0(&self) -> f32 {
1722        // SAFETY: plain scalar read through a live handle.
1723        unsafe { ffi::whiteout_m2_M2TexturedLightData_get_unknown0(self.raw.as_ptr()) }
1724    }
1725
1726    pub fn set_unknown_0(&mut self, value: f32) {
1727        // SAFETY: plain scalar write through a live handle.
1728        unsafe { ffi::whiteout_m2_M2TexturedLightData_set_unknown0(self.raw.as_ptr(), value) }
1729    }
1730
1731    pub fn unknown_1(&self) -> f32 {
1732        // SAFETY: plain scalar read through a live handle.
1733        unsafe { ffi::whiteout_m2_M2TexturedLightData_get_unknown1(self.raw.as_ptr()) }
1734    }
1735
1736    pub fn set_unknown_1(&mut self, value: f32) {
1737        // SAFETY: plain scalar write through a live handle.
1738        unsafe { ffi::whiteout_m2_M2TexturedLightData_set_unknown1(self.raw.as_ptr(), value) }
1739    }
1740
1741    pub fn texture_lookup(&self) -> i32 {
1742        // SAFETY: plain scalar read through a live handle.
1743        unsafe { ffi::whiteout_m2_M2TexturedLightData_get_textureLookup(self.raw.as_ptr()) }
1744    }
1745
1746    pub fn set_texture_lookup(&mut self, value: i32) {
1747        // SAFETY: plain scalar write through a live handle.
1748        unsafe { ffi::whiteout_m2_M2TexturedLightData_set_textureLookup(self.raw.as_ptr(), value) }
1749    }
1750
1751    pub fn unknown_2(&self) -> i32 {
1752        // SAFETY: plain scalar read through a live handle.
1753        unsafe { ffi::whiteout_m2_M2TexturedLightData_get_unknown2(self.raw.as_ptr()) }
1754    }
1755
1756    pub fn set_unknown_2(&mut self, value: i32) {
1757        // SAFETY: plain scalar write through a live handle.
1758        unsafe { ffi::whiteout_m2_M2TexturedLightData_set_unknown2(self.raw.as_ptr(), value) }
1759    }
1760}
1761
1762impl Default for TexturedLightData {
1763    fn default() -> Self {
1764        Self::new()
1765    }
1766}
1767
1768pub struct PhysicsCollision {
1769    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2PhysicsCollision>,
1770}
1771
1772impl Drop for PhysicsCollision {
1773    fn drop(&mut self) {
1774        // SAFETY: `raw` came from a native constructor and Drop runs once.
1775        unsafe { ffi::whiteout_m2_M2PhysicsCollision_delete(self.raw.as_ptr()) }
1776    }
1777}
1778
1779impl PhysicsCollision {
1780    /// # Safety
1781    /// `raw` must be a live handle this value takes ownership of.
1782    #[allow(dead_code)] // used by whichever methods return this type
1783    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2PhysicsCollision) -> Option<Self> {
1784        core::ptr::NonNull::new(raw).map(|raw| PhysicsCollision { raw })
1785    }
1786}
1787
1788// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
1789// is deliberately NOT implemented — the C++ types make no documented
1790// guarantee about concurrent use, and claiming one we haven't verified
1791// would be unsound. See `@bind thread_safe` in the plan.
1792unsafe impl Send for PhysicsCollision {}
1793
1794impl core::fmt::Debug for PhysicsCollision {
1795    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1796        f.debug_struct("PhysicsCollision").finish_non_exhaustive()
1797    }
1798}
1799
1800impl PhysicsCollision {
1801    /// # Panics
1802    /// Panics if the native allocation fails.
1803    pub fn new() -> Self {
1804        // SAFETY: the native constructor returns a live handle; a null here
1805        // means the library is unusable.
1806        unsafe {
1807            let raw = ffi::whiteout_m2_M2PhysicsCollision_new();
1808            Self::from_raw(raw).expect("native PhysicsCollision allocation failed")
1809        }
1810    }
1811
1812    /// Zero-copy view of the underlying `std::vector`.
1813    pub fn vertex_positions(&self) -> &[crate::math::Vector3f] {
1814        // SAFETY: `_data`/`_count` describe one contiguous C++
1815        // allocation, borrowed for as long as `self` is.
1816        unsafe {
1817            let n =
1818                ffi::whiteout_m2_M2PhysicsCollision_get_vertexPositions_count(self.raw.as_ptr());
1819            let p = ffi::whiteout_m2_M2PhysicsCollision_get_vertexPositions_data(self.raw.as_ptr())
1820                as *const crate::math::Vector3f;
1821            if p.is_null() || n == 0 {
1822                &[]
1823            } else {
1824                core::slice::from_raw_parts(p, n)
1825            }
1826        }
1827    }
1828
1829    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
1830    pub fn vertex_positions_mut(&mut self) -> &mut [crate::math::Vector3f] {
1831        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
1832        unsafe {
1833            let n =
1834                ffi::whiteout_m2_M2PhysicsCollision_get_vertexPositions_count(self.raw.as_ptr());
1835            let p = ffi::whiteout_m2_M2PhysicsCollision_get_vertexPositions_data(self.raw.as_ptr())
1836                as *const crate::math::Vector3f as *mut crate::math::Vector3f;
1837            if p.is_null() || n == 0 {
1838                &mut []
1839            } else {
1840                core::slice::from_raw_parts_mut(p, n)
1841            }
1842        }
1843    }
1844
1845    pub fn set_vertex_positions(&mut self, values: &[crate::math::Vector3f]) {
1846        // SAFETY: the native side copies `values` before returning.
1847        unsafe {
1848            ffi::whiteout_m2_M2PhysicsCollision_assign_vertexPositions(
1849                self.raw.as_ptr(),
1850                values.as_ptr() as *const _,
1851                values.len(),
1852            )
1853        }
1854    }
1855
1856    pub fn resize_vertex_positions(&mut self, count: usize) {
1857        // SAFETY: reallocation is safe here precisely because
1858        // `&mut self` means no slice borrow is outstanding.
1859        unsafe {
1860            ffi::whiteout_m2_M2PhysicsCollision_resize_vertexPositions(self.raw.as_ptr(), count)
1861        }
1862    }
1863
1864    /// Zero-copy view of the underlying `std::vector`.
1865    pub fn face_normals(&self) -> &[crate::math::Vector3f] {
1866        // SAFETY: `_data`/`_count` describe one contiguous C++
1867        // allocation, borrowed for as long as `self` is.
1868        unsafe {
1869            let n = ffi::whiteout_m2_M2PhysicsCollision_get_faceNormals_count(self.raw.as_ptr());
1870            let p = ffi::whiteout_m2_M2PhysicsCollision_get_faceNormals_data(self.raw.as_ptr())
1871                as *const crate::math::Vector3f;
1872            if p.is_null() || n == 0 {
1873                &[]
1874            } else {
1875                core::slice::from_raw_parts(p, n)
1876            }
1877        }
1878    }
1879
1880    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
1881    pub fn face_normals_mut(&mut self) -> &mut [crate::math::Vector3f] {
1882        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
1883        unsafe {
1884            let n = ffi::whiteout_m2_M2PhysicsCollision_get_faceNormals_count(self.raw.as_ptr());
1885            let p = ffi::whiteout_m2_M2PhysicsCollision_get_faceNormals_data(self.raw.as_ptr())
1886                as *const crate::math::Vector3f as *mut crate::math::Vector3f;
1887            if p.is_null() || n == 0 {
1888                &mut []
1889            } else {
1890                core::slice::from_raw_parts_mut(p, n)
1891            }
1892        }
1893    }
1894
1895    pub fn set_face_normals(&mut self, values: &[crate::math::Vector3f]) {
1896        // SAFETY: the native side copies `values` before returning.
1897        unsafe {
1898            ffi::whiteout_m2_M2PhysicsCollision_assign_faceNormals(
1899                self.raw.as_ptr(),
1900                values.as_ptr() as *const _,
1901                values.len(),
1902            )
1903        }
1904    }
1905
1906    pub fn resize_face_normals(&mut self, count: usize) {
1907        // SAFETY: reallocation is safe here precisely because
1908        // `&mut self` means no slice borrow is outstanding.
1909        unsafe { ffi::whiteout_m2_M2PhysicsCollision_resize_faceNormals(self.raw.as_ptr(), count) }
1910    }
1911
1912    /// Zero-copy view of the underlying `std::vector`.
1913    pub fn indices(&self) -> &[i16] {
1914        // SAFETY: `_data`/`_count` describe one contiguous C++
1915        // allocation, borrowed for as long as `self` is.
1916        unsafe {
1917            let n = ffi::whiteout_m2_M2PhysicsCollision_get_indices_count(self.raw.as_ptr());
1918            let p = ffi::whiteout_m2_M2PhysicsCollision_get_indices_data(self.raw.as_ptr());
1919            if p.is_null() || n == 0 {
1920                &[]
1921            } else {
1922                core::slice::from_raw_parts(p, n)
1923            }
1924        }
1925    }
1926
1927    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
1928    pub fn indices_mut(&mut self) -> &mut [i16] {
1929        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
1930        unsafe {
1931            let n = ffi::whiteout_m2_M2PhysicsCollision_get_indices_count(self.raw.as_ptr());
1932            let p =
1933                ffi::whiteout_m2_M2PhysicsCollision_get_indices_data(self.raw.as_ptr()) as *mut i16;
1934            if p.is_null() || n == 0 {
1935                &mut []
1936            } else {
1937                core::slice::from_raw_parts_mut(p, n)
1938            }
1939        }
1940    }
1941
1942    pub fn set_indices(&mut self, values: &[i16]) {
1943        // SAFETY: the native side copies `values` before returning.
1944        unsafe {
1945            ffi::whiteout_m2_M2PhysicsCollision_assign_indices(
1946                self.raw.as_ptr(),
1947                values.as_ptr() as *const _,
1948                values.len(),
1949            )
1950        }
1951    }
1952
1953    pub fn resize_indices(&mut self, count: usize) {
1954        // SAFETY: reallocation is safe here precisely because
1955        // `&mut self` means no slice borrow is outstanding.
1956        unsafe { ffi::whiteout_m2_M2PhysicsCollision_resize_indices(self.raw.as_ptr(), count) }
1957    }
1958
1959    /// Zero-copy view of the underlying `std::vector`.
1960    pub fn flags(&self) -> &[i16] {
1961        // SAFETY: `_data`/`_count` describe one contiguous C++
1962        // allocation, borrowed for as long as `self` is.
1963        unsafe {
1964            let n = ffi::whiteout_m2_M2PhysicsCollision_get_flags_count(self.raw.as_ptr());
1965            let p = ffi::whiteout_m2_M2PhysicsCollision_get_flags_data(self.raw.as_ptr());
1966            if p.is_null() || n == 0 {
1967                &[]
1968            } else {
1969                core::slice::from_raw_parts(p, n)
1970            }
1971        }
1972    }
1973
1974    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
1975    pub fn flags_mut(&mut self) -> &mut [i16] {
1976        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
1977        unsafe {
1978            let n = ffi::whiteout_m2_M2PhysicsCollision_get_flags_count(self.raw.as_ptr());
1979            let p =
1980                ffi::whiteout_m2_M2PhysicsCollision_get_flags_data(self.raw.as_ptr()) as *mut i16;
1981            if p.is_null() || n == 0 {
1982                &mut []
1983            } else {
1984                core::slice::from_raw_parts_mut(p, n)
1985            }
1986        }
1987    }
1988
1989    pub fn set_flags(&mut self, values: &[i16]) {
1990        // SAFETY: the native side copies `values` before returning.
1991        unsafe {
1992            ffi::whiteout_m2_M2PhysicsCollision_assign_flags(
1993                self.raw.as_ptr(),
1994                values.as_ptr() as *const _,
1995                values.len(),
1996            )
1997        }
1998    }
1999
2000    pub fn resize_flags(&mut self, count: usize) {
2001        // SAFETY: reallocation is safe here precisely because
2002        // `&mut self` means no slice borrow is outstanding.
2003        unsafe { ffi::whiteout_m2_M2PhysicsCollision_resize_flags(self.raw.as_ptr(), count) }
2004    }
2005}
2006
2007impl Default for PhysicsCollision {
2008    fn default() -> Self {
2009        Self::new()
2010    }
2011}
2012
2013pub struct SkinSection {
2014    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2SkinSection>,
2015}
2016
2017impl Drop for SkinSection {
2018    fn drop(&mut self) {
2019        // SAFETY: `raw` came from a native constructor and Drop runs once.
2020        unsafe { ffi::whiteout_m2_M2SkinSection_delete(self.raw.as_ptr()) }
2021    }
2022}
2023
2024impl SkinSection {
2025    /// # Safety
2026    /// `raw` must be a live handle this value takes ownership of.
2027    #[allow(dead_code)] // used by whichever methods return this type
2028    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2SkinSection) -> Option<Self> {
2029        core::ptr::NonNull::new(raw).map(|raw| SkinSection { raw })
2030    }
2031}
2032
2033// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
2034// is deliberately NOT implemented — the C++ types make no documented
2035// guarantee about concurrent use, and claiming one we haven't verified
2036// would be unsound. See `@bind thread_safe` in the plan.
2037unsafe impl Send for SkinSection {}
2038
2039impl core::fmt::Debug for SkinSection {
2040    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2041        f.debug_struct("SkinSection").finish_non_exhaustive()
2042    }
2043}
2044
2045impl SkinSection {
2046    /// # Panics
2047    /// Panics if the native allocation fails.
2048    pub fn new() -> Self {
2049        // SAFETY: the native constructor returns a live handle; a null here
2050        // means the library is unusable.
2051        unsafe {
2052            let raw = ffi::whiteout_m2_M2SkinSection_new();
2053            Self::from_raw(raw).expect("native SkinSection allocation failed")
2054        }
2055    }
2056
2057    pub fn skin_section_id(&self) -> u16 {
2058        // SAFETY: plain scalar read through a live handle.
2059        unsafe { ffi::whiteout_m2_M2SkinSection_get_skinSectionId(self.raw.as_ptr()) }
2060    }
2061
2062    pub fn set_skin_section_id(&mut self, value: u16) {
2063        // SAFETY: plain scalar write through a live handle.
2064        unsafe { ffi::whiteout_m2_M2SkinSection_set_skinSectionId(self.raw.as_ptr(), value) }
2065    }
2066
2067    pub fn level(&self) -> u16 {
2068        // SAFETY: plain scalar read through a live handle.
2069        unsafe { ffi::whiteout_m2_M2SkinSection_get_level(self.raw.as_ptr()) }
2070    }
2071
2072    pub fn set_level(&mut self, value: u16) {
2073        // SAFETY: plain scalar write through a live handle.
2074        unsafe { ffi::whiteout_m2_M2SkinSection_set_level(self.raw.as_ptr(), value) }
2075    }
2076
2077    pub fn vertex_start(&self) -> u16 {
2078        // SAFETY: plain scalar read through a live handle.
2079        unsafe { ffi::whiteout_m2_M2SkinSection_get_vertexStart(self.raw.as_ptr()) }
2080    }
2081
2082    pub fn set_vertex_start(&mut self, value: u16) {
2083        // SAFETY: plain scalar write through a live handle.
2084        unsafe { ffi::whiteout_m2_M2SkinSection_set_vertexStart(self.raw.as_ptr(), value) }
2085    }
2086
2087    pub fn vertex_count(&self) -> u16 {
2088        // SAFETY: plain scalar read through a live handle.
2089        unsafe { ffi::whiteout_m2_M2SkinSection_get_vertexCount(self.raw.as_ptr()) }
2090    }
2091
2092    pub fn set_vertex_count(&mut self, value: u16) {
2093        // SAFETY: plain scalar write through a live handle.
2094        unsafe { ffi::whiteout_m2_M2SkinSection_set_vertexCount(self.raw.as_ptr(), value) }
2095    }
2096
2097    pub fn index_start(&self) -> u16 {
2098        // SAFETY: plain scalar read through a live handle.
2099        unsafe { ffi::whiteout_m2_M2SkinSection_get_indexStart(self.raw.as_ptr()) }
2100    }
2101
2102    pub fn set_index_start(&mut self, value: u16) {
2103        // SAFETY: plain scalar write through a live handle.
2104        unsafe { ffi::whiteout_m2_M2SkinSection_set_indexStart(self.raw.as_ptr(), value) }
2105    }
2106
2107    pub fn index_count(&self) -> u16 {
2108        // SAFETY: plain scalar read through a live handle.
2109        unsafe { ffi::whiteout_m2_M2SkinSection_get_indexCount(self.raw.as_ptr()) }
2110    }
2111
2112    pub fn set_index_count(&mut self, value: u16) {
2113        // SAFETY: plain scalar write through a live handle.
2114        unsafe { ffi::whiteout_m2_M2SkinSection_set_indexCount(self.raw.as_ptr(), value) }
2115    }
2116
2117    pub fn bone_count(&self) -> u16 {
2118        // SAFETY: plain scalar read through a live handle.
2119        unsafe { ffi::whiteout_m2_M2SkinSection_get_boneCount(self.raw.as_ptr()) }
2120    }
2121
2122    pub fn set_bone_count(&mut self, value: u16) {
2123        // SAFETY: plain scalar write through a live handle.
2124        unsafe { ffi::whiteout_m2_M2SkinSection_set_boneCount(self.raw.as_ptr(), value) }
2125    }
2126
2127    pub fn bone_combo_index(&self) -> u16 {
2128        // SAFETY: plain scalar read through a live handle.
2129        unsafe { ffi::whiteout_m2_M2SkinSection_get_boneComboIndex(self.raw.as_ptr()) }
2130    }
2131
2132    pub fn set_bone_combo_index(&mut self, value: u16) {
2133        // SAFETY: plain scalar write through a live handle.
2134        unsafe { ffi::whiteout_m2_M2SkinSection_set_boneComboIndex(self.raw.as_ptr(), value) }
2135    }
2136
2137    pub fn bone_influences(&self) -> u16 {
2138        // SAFETY: plain scalar read through a live handle.
2139        unsafe { ffi::whiteout_m2_M2SkinSection_get_boneInfluences(self.raw.as_ptr()) }
2140    }
2141
2142    pub fn set_bone_influences(&mut self, value: u16) {
2143        // SAFETY: plain scalar write through a live handle.
2144        unsafe { ffi::whiteout_m2_M2SkinSection_set_boneInfluences(self.raw.as_ptr(), value) }
2145    }
2146
2147    pub fn center_bone_index(&self) -> u16 {
2148        // SAFETY: plain scalar read through a live handle.
2149        unsafe { ffi::whiteout_m2_M2SkinSection_get_centerBoneIndex(self.raw.as_ptr()) }
2150    }
2151
2152    pub fn set_center_bone_index(&mut self, value: u16) {
2153        // SAFETY: plain scalar write through a live handle.
2154        unsafe { ffi::whiteout_m2_M2SkinSection_set_centerBoneIndex(self.raw.as_ptr(), value) }
2155    }
2156
2157    pub fn center_position(&self) -> crate::math::Vector3f {
2158        // SAFETY: the getter returns an interior pointer to a
2159        // layout-identical POD; we copy it out immediately.
2160        unsafe {
2161            *(ffi::whiteout_m2_M2SkinSection_get_centerPosition(self.raw.as_ptr())
2162                as *const crate::math::Vector3f)
2163        }
2164    }
2165
2166    pub fn set_center_position(&mut self, value: crate::math::Vector3f) {
2167        // SAFETY: as above, in the other direction.
2168        unsafe {
2169            ffi::whiteout_m2_M2SkinSection_set_centerPosition(
2170                self.raw.as_ptr(),
2171                &value as *const crate::math::Vector3f as *const _,
2172            )
2173        }
2174    }
2175
2176    pub fn sort_center_position(&self) -> crate::math::Vector3f {
2177        // SAFETY: the getter returns an interior pointer to a
2178        // layout-identical POD; we copy it out immediately.
2179        unsafe {
2180            *(ffi::whiteout_m2_M2SkinSection_get_sortCenterPosition(self.raw.as_ptr())
2181                as *const crate::math::Vector3f)
2182        }
2183    }
2184
2185    pub fn set_sort_center_position(&mut self, value: crate::math::Vector3f) {
2186        // SAFETY: as above, in the other direction.
2187        unsafe {
2188            ffi::whiteout_m2_M2SkinSection_set_sortCenterPosition(
2189                self.raw.as_ptr(),
2190                &value as *const crate::math::Vector3f as *const _,
2191            )
2192        }
2193    }
2194
2195    pub fn sort_radius(&self) -> f32 {
2196        // SAFETY: plain scalar read through a live handle.
2197        unsafe { ffi::whiteout_m2_M2SkinSection_get_sortRadius(self.raw.as_ptr()) }
2198    }
2199
2200    pub fn set_sort_radius(&mut self, value: f32) {
2201        // SAFETY: plain scalar write through a live handle.
2202        unsafe { ffi::whiteout_m2_M2SkinSection_set_sortRadius(self.raw.as_ptr(), value) }
2203    }
2204}
2205
2206impl Default for SkinSection {
2207    fn default() -> Self {
2208        Self::new()
2209    }
2210}
2211
2212pub struct Batch {
2213    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2Batch>,
2214}
2215
2216impl Drop for Batch {
2217    fn drop(&mut self) {
2218        // SAFETY: `raw` came from a native constructor and Drop runs once.
2219        unsafe { ffi::whiteout_m2_M2Batch_delete(self.raw.as_ptr()) }
2220    }
2221}
2222
2223impl Batch {
2224    /// # Safety
2225    /// `raw` must be a live handle this value takes ownership of.
2226    #[allow(dead_code)] // used by whichever methods return this type
2227    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2Batch) -> Option<Self> {
2228        core::ptr::NonNull::new(raw).map(|raw| Batch { raw })
2229    }
2230}
2231
2232// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
2233// is deliberately NOT implemented — the C++ types make no documented
2234// guarantee about concurrent use, and claiming one we haven't verified
2235// would be unsound. See `@bind thread_safe` in the plan.
2236unsafe impl Send for Batch {}
2237
2238impl core::fmt::Debug for Batch {
2239    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2240        f.debug_struct("Batch").finish_non_exhaustive()
2241    }
2242}
2243
2244impl Batch {
2245    /// # Panics
2246    /// Panics if the native allocation fails.
2247    pub fn new() -> Self {
2248        // SAFETY: the native constructor returns a live handle; a null here
2249        // means the library is unusable.
2250        unsafe {
2251            let raw = ffi::whiteout_m2_M2Batch_new();
2252            Self::from_raw(raw).expect("native Batch allocation failed")
2253        }
2254    }
2255
2256    pub fn flags(&self) -> u8 {
2257        // SAFETY: plain scalar read through a live handle.
2258        unsafe { ffi::whiteout_m2_M2Batch_get_flags(self.raw.as_ptr()) }
2259    }
2260
2261    pub fn set_flags(&mut self, value: u8) {
2262        // SAFETY: plain scalar write through a live handle.
2263        unsafe { ffi::whiteout_m2_M2Batch_set_flags(self.raw.as_ptr(), value) }
2264    }
2265
2266    pub fn priority_plane(&self) -> i8 {
2267        // SAFETY: plain scalar read through a live handle.
2268        unsafe { ffi::whiteout_m2_M2Batch_get_priorityPlane(self.raw.as_ptr()) }
2269    }
2270
2271    pub fn set_priority_plane(&mut self, value: i8) {
2272        // SAFETY: plain scalar write through a live handle.
2273        unsafe { ffi::whiteout_m2_M2Batch_set_priorityPlane(self.raw.as_ptr(), value) }
2274    }
2275
2276    pub fn shader_id(&self) -> u16 {
2277        // SAFETY: plain scalar read through a live handle.
2278        unsafe { ffi::whiteout_m2_M2Batch_get_shaderId(self.raw.as_ptr()) }
2279    }
2280
2281    pub fn set_shader_id(&mut self, value: u16) {
2282        // SAFETY: plain scalar write through a live handle.
2283        unsafe { ffi::whiteout_m2_M2Batch_set_shaderId(self.raw.as_ptr(), value) }
2284    }
2285
2286    pub fn skin_section_index(&self) -> u16 {
2287        // SAFETY: plain scalar read through a live handle.
2288        unsafe { ffi::whiteout_m2_M2Batch_get_skinSectionIndex(self.raw.as_ptr()) }
2289    }
2290
2291    pub fn set_skin_section_index(&mut self, value: u16) {
2292        // SAFETY: plain scalar write through a live handle.
2293        unsafe { ffi::whiteout_m2_M2Batch_set_skinSectionIndex(self.raw.as_ptr(), value) }
2294    }
2295
2296    pub fn geoset_index(&self) -> u16 {
2297        // SAFETY: plain scalar read through a live handle.
2298        unsafe { ffi::whiteout_m2_M2Batch_get_geosetIndex(self.raw.as_ptr()) }
2299    }
2300
2301    pub fn set_geoset_index(&mut self, value: u16) {
2302        // SAFETY: plain scalar write through a live handle.
2303        unsafe { ffi::whiteout_m2_M2Batch_set_geosetIndex(self.raw.as_ptr(), value) }
2304    }
2305
2306    pub fn color_index(&self) -> i16 {
2307        // SAFETY: plain scalar read through a live handle.
2308        unsafe { ffi::whiteout_m2_M2Batch_get_colorIndex(self.raw.as_ptr()) }
2309    }
2310
2311    pub fn set_color_index(&mut self, value: i16) {
2312        // SAFETY: plain scalar write through a live handle.
2313        unsafe { ffi::whiteout_m2_M2Batch_set_colorIndex(self.raw.as_ptr(), value) }
2314    }
2315
2316    pub fn material_index(&self) -> u16 {
2317        // SAFETY: plain scalar read through a live handle.
2318        unsafe { ffi::whiteout_m2_M2Batch_get_materialIndex(self.raw.as_ptr()) }
2319    }
2320
2321    pub fn set_material_index(&mut self, value: u16) {
2322        // SAFETY: plain scalar write through a live handle.
2323        unsafe { ffi::whiteout_m2_M2Batch_set_materialIndex(self.raw.as_ptr(), value) }
2324    }
2325
2326    pub fn material_layer(&self) -> u16 {
2327        // SAFETY: plain scalar read through a live handle.
2328        unsafe { ffi::whiteout_m2_M2Batch_get_materialLayer(self.raw.as_ptr()) }
2329    }
2330
2331    pub fn set_material_layer(&mut self, value: u16) {
2332        // SAFETY: plain scalar write through a live handle.
2333        unsafe { ffi::whiteout_m2_M2Batch_set_materialLayer(self.raw.as_ptr(), value) }
2334    }
2335
2336    pub fn texture_count(&self) -> u16 {
2337        // SAFETY: plain scalar read through a live handle.
2338        unsafe { ffi::whiteout_m2_M2Batch_get_textureCount(self.raw.as_ptr()) }
2339    }
2340
2341    pub fn set_texture_count(&mut self, value: u16) {
2342        // SAFETY: plain scalar write through a live handle.
2343        unsafe { ffi::whiteout_m2_M2Batch_set_textureCount(self.raw.as_ptr(), value) }
2344    }
2345
2346    pub fn texture_combo_index(&self) -> u16 {
2347        // SAFETY: plain scalar read through a live handle.
2348        unsafe { ffi::whiteout_m2_M2Batch_get_textureComboIndex(self.raw.as_ptr()) }
2349    }
2350
2351    pub fn set_texture_combo_index(&mut self, value: u16) {
2352        // SAFETY: plain scalar write through a live handle.
2353        unsafe { ffi::whiteout_m2_M2Batch_set_textureComboIndex(self.raw.as_ptr(), value) }
2354    }
2355
2356    pub fn texture_coord_combo_index(&self) -> u16 {
2357        // SAFETY: plain scalar read through a live handle.
2358        unsafe { ffi::whiteout_m2_M2Batch_get_textureCoordComboIndex(self.raw.as_ptr()) }
2359    }
2360
2361    pub fn set_texture_coord_combo_index(&mut self, value: u16) {
2362        // SAFETY: plain scalar write through a live handle.
2363        unsafe { ffi::whiteout_m2_M2Batch_set_textureCoordComboIndex(self.raw.as_ptr(), value) }
2364    }
2365
2366    pub fn texture_weight_combo_index(&self) -> u16 {
2367        // SAFETY: plain scalar read through a live handle.
2368        unsafe { ffi::whiteout_m2_M2Batch_get_textureWeightComboIndex(self.raw.as_ptr()) }
2369    }
2370
2371    pub fn set_texture_weight_combo_index(&mut self, value: u16) {
2372        // SAFETY: plain scalar write through a live handle.
2373        unsafe { ffi::whiteout_m2_M2Batch_set_textureWeightComboIndex(self.raw.as_ptr(), value) }
2374    }
2375
2376    pub fn texture_transform_combo_index(&self) -> u16 {
2377        // SAFETY: plain scalar read through a live handle.
2378        unsafe { ffi::whiteout_m2_M2Batch_get_textureTransformComboIndex(self.raw.as_ptr()) }
2379    }
2380
2381    pub fn set_texture_transform_combo_index(&mut self, value: u16) {
2382        // SAFETY: plain scalar write through a live handle.
2383        unsafe { ffi::whiteout_m2_M2Batch_set_textureTransformComboIndex(self.raw.as_ptr(), value) }
2384    }
2385}
2386
2387impl Default for Batch {
2388    fn default() -> Self {
2389        Self::new()
2390    }
2391}
2392
2393pub struct ShadowBatch {
2394    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2ShadowBatch>,
2395}
2396
2397impl Drop for ShadowBatch {
2398    fn drop(&mut self) {
2399        // SAFETY: `raw` came from a native constructor and Drop runs once.
2400        unsafe { ffi::whiteout_m2_M2ShadowBatch_delete(self.raw.as_ptr()) }
2401    }
2402}
2403
2404impl ShadowBatch {
2405    /// # Safety
2406    /// `raw` must be a live handle this value takes ownership of.
2407    #[allow(dead_code)] // used by whichever methods return this type
2408    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2ShadowBatch) -> Option<Self> {
2409        core::ptr::NonNull::new(raw).map(|raw| ShadowBatch { raw })
2410    }
2411}
2412
2413// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
2414// is deliberately NOT implemented — the C++ types make no documented
2415// guarantee about concurrent use, and claiming one we haven't verified
2416// would be unsound. See `@bind thread_safe` in the plan.
2417unsafe impl Send for ShadowBatch {}
2418
2419impl core::fmt::Debug for ShadowBatch {
2420    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2421        f.debug_struct("ShadowBatch").finish_non_exhaustive()
2422    }
2423}
2424
2425impl ShadowBatch {
2426    /// # Panics
2427    /// Panics if the native allocation fails.
2428    pub fn new() -> Self {
2429        // SAFETY: the native constructor returns a live handle; a null here
2430        // means the library is unusable.
2431        unsafe {
2432            let raw = ffi::whiteout_m2_M2ShadowBatch_new();
2433            Self::from_raw(raw).expect("native ShadowBatch allocation failed")
2434        }
2435    }
2436
2437    pub fn flags(&self) -> u8 {
2438        // SAFETY: plain scalar read through a live handle.
2439        unsafe { ffi::whiteout_m2_M2ShadowBatch_get_flags(self.raw.as_ptr()) }
2440    }
2441
2442    pub fn set_flags(&mut self, value: u8) {
2443        // SAFETY: plain scalar write through a live handle.
2444        unsafe { ffi::whiteout_m2_M2ShadowBatch_set_flags(self.raw.as_ptr(), value) }
2445    }
2446
2447    pub fn flags_2(&self) -> u8 {
2448        // SAFETY: plain scalar read through a live handle.
2449        unsafe { ffi::whiteout_m2_M2ShadowBatch_get_flags2(self.raw.as_ptr()) }
2450    }
2451
2452    pub fn set_flags_2(&mut self, value: u8) {
2453        // SAFETY: plain scalar write through a live handle.
2454        unsafe { ffi::whiteout_m2_M2ShadowBatch_set_flags2(self.raw.as_ptr(), value) }
2455    }
2456
2457    pub fn unknown_0(&self) -> u16 {
2458        // SAFETY: plain scalar read through a live handle.
2459        unsafe { ffi::whiteout_m2_M2ShadowBatch_get_unknown0(self.raw.as_ptr()) }
2460    }
2461
2462    pub fn set_unknown_0(&mut self, value: u16) {
2463        // SAFETY: plain scalar write through a live handle.
2464        unsafe { ffi::whiteout_m2_M2ShadowBatch_set_unknown0(self.raw.as_ptr(), value) }
2465    }
2466
2467    pub fn submesh_id(&self) -> u16 {
2468        // SAFETY: plain scalar read through a live handle.
2469        unsafe { ffi::whiteout_m2_M2ShadowBatch_get_submeshId(self.raw.as_ptr()) }
2470    }
2471
2472    pub fn set_submesh_id(&mut self, value: u16) {
2473        // SAFETY: plain scalar write through a live handle.
2474        unsafe { ffi::whiteout_m2_M2ShadowBatch_set_submeshId(self.raw.as_ptr(), value) }
2475    }
2476
2477    pub fn texture_id(&self) -> u16 {
2478        // SAFETY: plain scalar read through a live handle.
2479        unsafe { ffi::whiteout_m2_M2ShadowBatch_get_textureId(self.raw.as_ptr()) }
2480    }
2481
2482    pub fn set_texture_id(&mut self, value: u16) {
2483        // SAFETY: plain scalar write through a live handle.
2484        unsafe { ffi::whiteout_m2_M2ShadowBatch_set_textureId(self.raw.as_ptr(), value) }
2485    }
2486
2487    pub fn color_id(&self) -> u16 {
2488        // SAFETY: plain scalar read through a live handle.
2489        unsafe { ffi::whiteout_m2_M2ShadowBatch_get_colorId(self.raw.as_ptr()) }
2490    }
2491
2492    pub fn set_color_id(&mut self, value: u16) {
2493        // SAFETY: plain scalar write through a live handle.
2494        unsafe { ffi::whiteout_m2_M2ShadowBatch_set_colorId(self.raw.as_ptr(), value) }
2495    }
2496
2497    pub fn transparency_id(&self) -> u16 {
2498        // SAFETY: plain scalar read through a live handle.
2499        unsafe { ffi::whiteout_m2_M2ShadowBatch_get_transparencyId(self.raw.as_ptr()) }
2500    }
2501
2502    pub fn set_transparency_id(&mut self, value: u16) {
2503        // SAFETY: plain scalar write through a live handle.
2504        unsafe { ffi::whiteout_m2_M2ShadowBatch_set_transparencyId(self.raw.as_ptr(), value) }
2505    }
2506}
2507
2508impl Default for ShadowBatch {
2509    fn default() -> Self {
2510        Self::new()
2511    }
2512}
2513
2514pub struct SkinProfile {
2515    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2SkinProfile>,
2516}
2517
2518impl Drop for SkinProfile {
2519    fn drop(&mut self) {
2520        // SAFETY: `raw` came from a native constructor and Drop runs once.
2521        unsafe { ffi::whiteout_m2_M2SkinProfile_delete(self.raw.as_ptr()) }
2522    }
2523}
2524
2525impl SkinProfile {
2526    /// # Safety
2527    /// `raw` must be a live handle this value takes ownership of.
2528    #[allow(dead_code)] // used by whichever methods return this type
2529    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2SkinProfile) -> Option<Self> {
2530        core::ptr::NonNull::new(raw).map(|raw| SkinProfile { raw })
2531    }
2532}
2533
2534// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
2535// is deliberately NOT implemented — the C++ types make no documented
2536// guarantee about concurrent use, and claiming one we haven't verified
2537// would be unsound. See `@bind thread_safe` in the plan.
2538unsafe impl Send for SkinProfile {}
2539
2540impl core::fmt::Debug for SkinProfile {
2541    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2542        f.debug_struct("SkinProfile").finish_non_exhaustive()
2543    }
2544}
2545
2546impl SkinProfile {
2547    /// # Panics
2548    /// Panics if the native allocation fails.
2549    pub fn new() -> Self {
2550        // SAFETY: the native constructor returns a live handle; a null here
2551        // means the library is unusable.
2552        unsafe {
2553            let raw = ffi::whiteout_m2_M2SkinProfile_new();
2554            Self::from_raw(raw).expect("native SkinProfile allocation failed")
2555        }
2556    }
2557
2558    /// Zero-copy view of the underlying `std::vector`.
2559    pub fn vertices(&self) -> &[u16] {
2560        // SAFETY: `_data`/`_count` describe one contiguous C++
2561        // allocation, borrowed for as long as `self` is.
2562        unsafe {
2563            let n = ffi::whiteout_m2_M2SkinProfile_get_vertices_count(self.raw.as_ptr());
2564            let p = ffi::whiteout_m2_M2SkinProfile_get_vertices_data(self.raw.as_ptr());
2565            if p.is_null() || n == 0 {
2566                &[]
2567            } else {
2568                core::slice::from_raw_parts(p, n)
2569            }
2570        }
2571    }
2572
2573    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
2574    pub fn vertices_mut(&mut self) -> &mut [u16] {
2575        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
2576        unsafe {
2577            let n = ffi::whiteout_m2_M2SkinProfile_get_vertices_count(self.raw.as_ptr());
2578            let p = ffi::whiteout_m2_M2SkinProfile_get_vertices_data(self.raw.as_ptr()) as *mut u16;
2579            if p.is_null() || n == 0 {
2580                &mut []
2581            } else {
2582                core::slice::from_raw_parts_mut(p, n)
2583            }
2584        }
2585    }
2586
2587    pub fn set_vertices(&mut self, values: &[u16]) {
2588        // SAFETY: the native side copies `values` before returning.
2589        unsafe {
2590            ffi::whiteout_m2_M2SkinProfile_assign_vertices(
2591                self.raw.as_ptr(),
2592                values.as_ptr() as *const _,
2593                values.len(),
2594            )
2595        }
2596    }
2597
2598    pub fn resize_vertices(&mut self, count: usize) {
2599        // SAFETY: reallocation is safe here precisely because
2600        // `&mut self` means no slice borrow is outstanding.
2601        unsafe { ffi::whiteout_m2_M2SkinProfile_resize_vertices(self.raw.as_ptr(), count) }
2602    }
2603
2604    /// Zero-copy view of the underlying `std::vector`.
2605    pub fn indices(&self) -> &[u16] {
2606        // SAFETY: `_data`/`_count` describe one contiguous C++
2607        // allocation, borrowed for as long as `self` is.
2608        unsafe {
2609            let n = ffi::whiteout_m2_M2SkinProfile_get_indices_count(self.raw.as_ptr());
2610            let p = ffi::whiteout_m2_M2SkinProfile_get_indices_data(self.raw.as_ptr());
2611            if p.is_null() || n == 0 {
2612                &[]
2613            } else {
2614                core::slice::from_raw_parts(p, n)
2615            }
2616        }
2617    }
2618
2619    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
2620    pub fn indices_mut(&mut self) -> &mut [u16] {
2621        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
2622        unsafe {
2623            let n = ffi::whiteout_m2_M2SkinProfile_get_indices_count(self.raw.as_ptr());
2624            let p = ffi::whiteout_m2_M2SkinProfile_get_indices_data(self.raw.as_ptr()) as *mut u16;
2625            if p.is_null() || n == 0 {
2626                &mut []
2627            } else {
2628                core::slice::from_raw_parts_mut(p, n)
2629            }
2630        }
2631    }
2632
2633    pub fn set_indices(&mut self, values: &[u16]) {
2634        // SAFETY: the native side copies `values` before returning.
2635        unsafe {
2636            ffi::whiteout_m2_M2SkinProfile_assign_indices(
2637                self.raw.as_ptr(),
2638                values.as_ptr() as *const _,
2639                values.len(),
2640            )
2641        }
2642    }
2643
2644    pub fn resize_indices(&mut self, count: usize) {
2645        // SAFETY: reallocation is safe here precisely because
2646        // `&mut self` means no slice borrow is outstanding.
2647        unsafe { ffi::whiteout_m2_M2SkinProfile_resize_indices(self.raw.as_ptr(), count) }
2648    }
2649
2650    pub fn submeshes_len(&self) -> usize {
2651        // SAFETY: scalar read through a live handle.
2652        unsafe { ffi::whiteout_m2_M2SkinProfile_get_submeshes_count(self.raw.as_ptr()) }
2653    }
2654
2655    /// Borrows element `index` in place. `None` when out of range.
2656    pub fn submeshes(&self, index: usize) -> Option<crate::support::Ref<'_, SkinSection>> {
2657        if index >= self.submeshes_len() {
2658            return None;
2659        }
2660        // SAFETY: index checked above; the pointer is interior to `self`.
2661        unsafe {
2662            Some(crate::support::Ref::new(SkinSection {
2663                raw: core::ptr::NonNull::new_unchecked(
2664                    ffi::whiteout_m2_M2SkinProfile_get_submeshes_at(self.raw.as_ptr(), index),
2665                ),
2666            }))
2667        }
2668    }
2669
2670    pub fn submeshes_mut(
2671        &mut self,
2672        index: usize,
2673    ) -> Option<crate::support::RefMut<'_, SkinSection>> {
2674        if index >= self.submeshes_len() {
2675            return None;
2676        }
2677        // SAFETY: as above; `&mut self` guarantees exclusivity.
2678        unsafe {
2679            Some(crate::support::RefMut::new(SkinSection {
2680                raw: core::ptr::NonNull::new_unchecked(
2681                    ffi::whiteout_m2_M2SkinProfile_get_submeshes_at(self.raw.as_ptr(), index),
2682                ),
2683            }))
2684        }
2685    }
2686
2687    /// Iterate the elements, borrowing each in turn.
2688    pub fn submeshes_iter(
2689        &self,
2690    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, SkinSection>> {
2691        (0..self.submeshes_len()).map(move |i| self.submeshes(i).expect("index below len"))
2692    }
2693
2694    pub fn resize_submeshes(&mut self, count: usize) {
2695        // SAFETY: exclusive access, so no borrow is outstanding.
2696        unsafe { ffi::whiteout_m2_M2SkinProfile_resize_submeshes(self.raw.as_ptr(), count) }
2697    }
2698
2699    pub fn batches_len(&self) -> usize {
2700        // SAFETY: scalar read through a live handle.
2701        unsafe { ffi::whiteout_m2_M2SkinProfile_get_batches_count(self.raw.as_ptr()) }
2702    }
2703
2704    /// Borrows element `index` in place. `None` when out of range.
2705    pub fn batches(&self, index: usize) -> Option<crate::support::Ref<'_, Batch>> {
2706        if index >= self.batches_len() {
2707            return None;
2708        }
2709        // SAFETY: index checked above; the pointer is interior to `self`.
2710        unsafe {
2711            Some(crate::support::Ref::new(Batch {
2712                raw: core::ptr::NonNull::new_unchecked(
2713                    ffi::whiteout_m2_M2SkinProfile_get_batches_at(self.raw.as_ptr(), index),
2714                ),
2715            }))
2716        }
2717    }
2718
2719    pub fn batches_mut(&mut self, index: usize) -> Option<crate::support::RefMut<'_, Batch>> {
2720        if index >= self.batches_len() {
2721            return None;
2722        }
2723        // SAFETY: as above; `&mut self` guarantees exclusivity.
2724        unsafe {
2725            Some(crate::support::RefMut::new(Batch {
2726                raw: core::ptr::NonNull::new_unchecked(
2727                    ffi::whiteout_m2_M2SkinProfile_get_batches_at(self.raw.as_ptr(), index),
2728                ),
2729            }))
2730        }
2731    }
2732
2733    /// Iterate the elements, borrowing each in turn.
2734    pub fn batches_iter(&self) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, Batch>> {
2735        (0..self.batches_len()).map(move |i| self.batches(i).expect("index below len"))
2736    }
2737
2738    pub fn resize_batches(&mut self, count: usize) {
2739        // SAFETY: exclusive access, so no borrow is outstanding.
2740        unsafe { ffi::whiteout_m2_M2SkinProfile_resize_batches(self.raw.as_ptr(), count) }
2741    }
2742
2743    pub fn lod_vertex_base(&self) -> u32 {
2744        // SAFETY: plain scalar read through a live handle.
2745        unsafe { ffi::whiteout_m2_M2SkinProfile_get_lodVertexBase(self.raw.as_ptr()) }
2746    }
2747
2748    pub fn set_lod_vertex_base(&mut self, value: u32) {
2749        // SAFETY: plain scalar write through a live handle.
2750        unsafe { ffi::whiteout_m2_M2SkinProfile_set_lodVertexBase(self.raw.as_ptr(), value) }
2751    }
2752
2753    pub fn shadow_batches_len(&self) -> usize {
2754        // SAFETY: scalar read through a live handle.
2755        unsafe { ffi::whiteout_m2_M2SkinProfile_get_shadowBatches_count(self.raw.as_ptr()) }
2756    }
2757
2758    /// Borrows element `index` in place. `None` when out of range.
2759    pub fn shadow_batches(&self, index: usize) -> Option<crate::support::Ref<'_, ShadowBatch>> {
2760        if index >= self.shadow_batches_len() {
2761            return None;
2762        }
2763        // SAFETY: index checked above; the pointer is interior to `self`.
2764        unsafe {
2765            Some(crate::support::Ref::new(ShadowBatch {
2766                raw: core::ptr::NonNull::new_unchecked(
2767                    ffi::whiteout_m2_M2SkinProfile_get_shadowBatches_at(self.raw.as_ptr(), index),
2768                ),
2769            }))
2770        }
2771    }
2772
2773    pub fn shadow_batches_mut(
2774        &mut self,
2775        index: usize,
2776    ) -> Option<crate::support::RefMut<'_, ShadowBatch>> {
2777        if index >= self.shadow_batches_len() {
2778            return None;
2779        }
2780        // SAFETY: as above; `&mut self` guarantees exclusivity.
2781        unsafe {
2782            Some(crate::support::RefMut::new(ShadowBatch {
2783                raw: core::ptr::NonNull::new_unchecked(
2784                    ffi::whiteout_m2_M2SkinProfile_get_shadowBatches_at(self.raw.as_ptr(), index),
2785                ),
2786            }))
2787        }
2788    }
2789
2790    /// Iterate the elements, borrowing each in turn.
2791    pub fn shadow_batches_iter(
2792        &self,
2793    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, ShadowBatch>> {
2794        (0..self.shadow_batches_len())
2795            .map(move |i| self.shadow_batches(i).expect("index below len"))
2796    }
2797
2798    pub fn resize_shadow_batches(&mut self, count: usize) {
2799        // SAFETY: exclusive access, so no borrow is outstanding.
2800        unsafe { ffi::whiteout_m2_M2SkinProfile_resize_shadowBatches(self.raw.as_ptr(), count) }
2801    }
2802}
2803
2804impl Default for SkinProfile {
2805    fn default() -> Self {
2806        Self::new()
2807    }
2808}
2809
2810pub struct GlobalFlags {
2811    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2GlobalFlags>,
2812}
2813
2814impl Drop for GlobalFlags {
2815    fn drop(&mut self) {
2816        // SAFETY: `raw` came from a native constructor and Drop runs once.
2817        unsafe { ffi::whiteout_m2_M2GlobalFlags_delete(self.raw.as_ptr()) }
2818    }
2819}
2820
2821impl GlobalFlags {
2822    /// # Safety
2823    /// `raw` must be a live handle this value takes ownership of.
2824    #[allow(dead_code)] // used by whichever methods return this type
2825    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2GlobalFlags) -> Option<Self> {
2826        core::ptr::NonNull::new(raw).map(|raw| GlobalFlags { raw })
2827    }
2828}
2829
2830// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
2831// is deliberately NOT implemented — the C++ types make no documented
2832// guarantee about concurrent use, and claiming one we haven't verified
2833// would be unsound. See `@bind thread_safe` in the plan.
2834unsafe impl Send for GlobalFlags {}
2835
2836impl core::fmt::Debug for GlobalFlags {
2837    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2838        f.debug_struct("GlobalFlags").finish_non_exhaustive()
2839    }
2840}
2841
2842impl GlobalFlags {
2843    /// # Panics
2844    /// Panics if the native allocation fails.
2845    pub fn new() -> Self {
2846        // SAFETY: the native constructor returns a live handle; a null here
2847        // means the library is unusable.
2848        unsafe {
2849            let raw = ffi::whiteout_m2_M2GlobalFlags_new();
2850            Self::from_raw(raw).expect("native GlobalFlags allocation failed")
2851        }
2852    }
2853
2854    pub fn value(&self) -> GlobalFlag {
2855        // SAFETY: scalar read; a flag set accepts any bits.
2856        GlobalFlag(unsafe { ffi::whiteout_m2_M2GlobalFlags_get_value(self.raw.as_ptr()) })
2857    }
2858
2859    pub fn set_value(&mut self, value: GlobalFlag) {
2860        // SAFETY: scalar write through a live handle.
2861        unsafe { ffi::whiteout_m2_M2GlobalFlags_set_value(self.raw.as_ptr(), value.0) }
2862    }
2863}
2864
2865impl Default for GlobalFlags {
2866    fn default() -> Self {
2867        Self::new()
2868    }
2869}
2870
2871pub struct GlobalSequence {
2872    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2GlobalSequence>,
2873}
2874
2875impl Drop for GlobalSequence {
2876    fn drop(&mut self) {
2877        // SAFETY: `raw` came from a native constructor and Drop runs once.
2878        unsafe { ffi::whiteout_m2_M2GlobalSequence_delete(self.raw.as_ptr()) }
2879    }
2880}
2881
2882impl GlobalSequence {
2883    /// # Safety
2884    /// `raw` must be a live handle this value takes ownership of.
2885    #[allow(dead_code)] // used by whichever methods return this type
2886    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2GlobalSequence) -> Option<Self> {
2887        core::ptr::NonNull::new(raw).map(|raw| GlobalSequence { raw })
2888    }
2889}
2890
2891// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
2892// is deliberately NOT implemented — the C++ types make no documented
2893// guarantee about concurrent use, and claiming one we haven't verified
2894// would be unsound. See `@bind thread_safe` in the plan.
2895unsafe impl Send for GlobalSequence {}
2896
2897impl core::fmt::Debug for GlobalSequence {
2898    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2899        f.debug_struct("GlobalSequence").finish_non_exhaustive()
2900    }
2901}
2902
2903impl GlobalSequence {
2904    /// # Panics
2905    /// Panics if the native allocation fails.
2906    pub fn new() -> Self {
2907        // SAFETY: the native constructor returns a live handle; a null here
2908        // means the library is unusable.
2909        unsafe {
2910            let raw = ffi::whiteout_m2_M2GlobalSequence_new();
2911            Self::from_raw(raw).expect("native GlobalSequence allocation failed")
2912        }
2913    }
2914
2915    pub fn timestamp(&self) -> u32 {
2916        // SAFETY: plain scalar read through a live handle.
2917        unsafe { ffi::whiteout_m2_M2GlobalSequence_get_timestamp(self.raw.as_ptr()) }
2918    }
2919
2920    pub fn set_timestamp(&mut self, value: u32) {
2921        // SAFETY: plain scalar write through a live handle.
2922        unsafe { ffi::whiteout_m2_M2GlobalSequence_set_timestamp(self.raw.as_ptr(), value) }
2923    }
2924}
2925
2926impl Default for GlobalSequence {
2927    fn default() -> Self {
2928        Self::new()
2929    }
2930}
2931
2932pub struct Sequence {
2933    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2Sequence>,
2934}
2935
2936impl Drop for Sequence {
2937    fn drop(&mut self) {
2938        // SAFETY: `raw` came from a native constructor and Drop runs once.
2939        unsafe { ffi::whiteout_m2_M2Sequence_delete(self.raw.as_ptr()) }
2940    }
2941}
2942
2943impl Sequence {
2944    /// # Safety
2945    /// `raw` must be a live handle this value takes ownership of.
2946    #[allow(dead_code)] // used by whichever methods return this type
2947    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2Sequence) -> Option<Self> {
2948        core::ptr::NonNull::new(raw).map(|raw| Sequence { raw })
2949    }
2950}
2951
2952// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
2953// is deliberately NOT implemented — the C++ types make no documented
2954// guarantee about concurrent use, and claiming one we haven't verified
2955// would be unsound. See `@bind thread_safe` in the plan.
2956unsafe impl Send for Sequence {}
2957
2958impl core::fmt::Debug for Sequence {
2959    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2960        f.debug_struct("Sequence").finish_non_exhaustive()
2961    }
2962}
2963
2964impl Sequence {
2965    /// # Panics
2966    /// Panics if the native allocation fails.
2967    pub fn new() -> Self {
2968        // SAFETY: the native constructor returns a live handle; a null here
2969        // means the library is unusable.
2970        unsafe {
2971            let raw = ffi::whiteout_m2_M2Sequence_new();
2972            Self::from_raw(raw).expect("native Sequence allocation failed")
2973        }
2974    }
2975
2976    pub fn id(&self) -> u16 {
2977        // SAFETY: plain scalar read through a live handle.
2978        unsafe { ffi::whiteout_m2_M2Sequence_get_id(self.raw.as_ptr()) }
2979    }
2980
2981    pub fn set_id(&mut self, value: u16) {
2982        // SAFETY: plain scalar write through a live handle.
2983        unsafe { ffi::whiteout_m2_M2Sequence_set_id(self.raw.as_ptr(), value) }
2984    }
2985
2986    pub fn variation_index(&self) -> u16 {
2987        // SAFETY: plain scalar read through a live handle.
2988        unsafe { ffi::whiteout_m2_M2Sequence_get_variationIndex(self.raw.as_ptr()) }
2989    }
2990
2991    pub fn set_variation_index(&mut self, value: u16) {
2992        // SAFETY: plain scalar write through a live handle.
2993        unsafe { ffi::whiteout_m2_M2Sequence_set_variationIndex(self.raw.as_ptr(), value) }
2994    }
2995
2996    pub fn duration(&self) -> u32 {
2997        // SAFETY: plain scalar read through a live handle.
2998        unsafe { ffi::whiteout_m2_M2Sequence_get_duration(self.raw.as_ptr()) }
2999    }
3000
3001    pub fn set_duration(&mut self, value: u32) {
3002        // SAFETY: plain scalar write through a live handle.
3003        unsafe { ffi::whiteout_m2_M2Sequence_set_duration(self.raw.as_ptr(), value) }
3004    }
3005
3006    pub fn movespeed(&self) -> f32 {
3007        // SAFETY: plain scalar read through a live handle.
3008        unsafe { ffi::whiteout_m2_M2Sequence_get_movespeed(self.raw.as_ptr()) }
3009    }
3010
3011    pub fn set_movespeed(&mut self, value: f32) {
3012        // SAFETY: plain scalar write through a live handle.
3013        unsafe { ffi::whiteout_m2_M2Sequence_set_movespeed(self.raw.as_ptr(), value) }
3014    }
3015
3016    pub fn flags(&self) -> SequenceFlag {
3017        // SAFETY: scalar read; a flag set accepts any bits.
3018        SequenceFlag(unsafe { ffi::whiteout_m2_M2Sequence_get_flags(self.raw.as_ptr()) })
3019    }
3020
3021    pub fn set_flags(&mut self, value: SequenceFlag) {
3022        // SAFETY: scalar write through a live handle.
3023        unsafe { ffi::whiteout_m2_M2Sequence_set_flags(self.raw.as_ptr(), value.0) }
3024    }
3025
3026    pub fn frequency(&self) -> i16 {
3027        // SAFETY: plain scalar read through a live handle.
3028        unsafe { ffi::whiteout_m2_M2Sequence_get_frequency(self.raw.as_ptr()) }
3029    }
3030
3031    pub fn set_frequency(&mut self, value: i16) {
3032        // SAFETY: plain scalar write through a live handle.
3033        unsafe { ffi::whiteout_m2_M2Sequence_set_frequency(self.raw.as_ptr(), value) }
3034    }
3035
3036    pub fn padding(&self) -> u16 {
3037        // SAFETY: plain scalar read through a live handle.
3038        unsafe { ffi::whiteout_m2_M2Sequence_get_padding(self.raw.as_ptr()) }
3039    }
3040
3041    pub fn set_padding(&mut self, value: u16) {
3042        // SAFETY: plain scalar write through a live handle.
3043        unsafe { ffi::whiteout_m2_M2Sequence_set_padding(self.raw.as_ptr(), value) }
3044    }
3045
3046    pub fn replay_min(&self) -> u32 {
3047        // SAFETY: plain scalar read through a live handle.
3048        unsafe { ffi::whiteout_m2_M2Sequence_get_replayMin(self.raw.as_ptr()) }
3049    }
3050
3051    pub fn set_replay_min(&mut self, value: u32) {
3052        // SAFETY: plain scalar write through a live handle.
3053        unsafe { ffi::whiteout_m2_M2Sequence_set_replayMin(self.raw.as_ptr(), value) }
3054    }
3055
3056    pub fn replay_max(&self) -> u32 {
3057        // SAFETY: plain scalar read through a live handle.
3058        unsafe { ffi::whiteout_m2_M2Sequence_get_replayMax(self.raw.as_ptr()) }
3059    }
3060
3061    pub fn set_replay_max(&mut self, value: u32) {
3062        // SAFETY: plain scalar write through a live handle.
3063        unsafe { ffi::whiteout_m2_M2Sequence_set_replayMax(self.raw.as_ptr(), value) }
3064    }
3065
3066    pub fn blend_time_in(&self) -> u16 {
3067        // SAFETY: plain scalar read through a live handle.
3068        unsafe { ffi::whiteout_m2_M2Sequence_get_blendTimeIn(self.raw.as_ptr()) }
3069    }
3070
3071    pub fn set_blend_time_in(&mut self, value: u16) {
3072        // SAFETY: plain scalar write through a live handle.
3073        unsafe { ffi::whiteout_m2_M2Sequence_set_blendTimeIn(self.raw.as_ptr(), value) }
3074    }
3075
3076    pub fn blend_time_out(&self) -> u16 {
3077        // SAFETY: plain scalar read through a live handle.
3078        unsafe { ffi::whiteout_m2_M2Sequence_get_blendTimeOut(self.raw.as_ptr()) }
3079    }
3080
3081    pub fn set_blend_time_out(&mut self, value: u16) {
3082        // SAFETY: plain scalar write through a live handle.
3083        unsafe { ffi::whiteout_m2_M2Sequence_set_blendTimeOut(self.raw.as_ptr(), value) }
3084    }
3085
3086    /// Borrows the field in place — no copy, no allocation.
3087    pub fn bounding(&self) -> crate::support::Ref<'_, Extent> {
3088        // SAFETY: an interior pointer into `self`, valid for this
3089        // borrow and never freed by the `Ref`.
3090        unsafe {
3091            crate::support::Ref::new(Extent {
3092                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Sequence_get_bounding(
3093                    self.raw.as_ptr(),
3094                )),
3095            })
3096        }
3097    }
3098
3099    pub fn bounding_mut(&mut self) -> crate::support::RefMut<'_, Extent> {
3100        // SAFETY: as above; `&mut self` guarantees exclusivity.
3101        unsafe {
3102            crate::support::RefMut::new(Extent {
3103                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Sequence_get_bounding(
3104                    self.raw.as_ptr(),
3105                )),
3106            })
3107        }
3108    }
3109
3110    pub fn variation_next(&self) -> i16 {
3111        // SAFETY: plain scalar read through a live handle.
3112        unsafe { ffi::whiteout_m2_M2Sequence_get_variationNext(self.raw.as_ptr()) }
3113    }
3114
3115    pub fn set_variation_next(&mut self, value: i16) {
3116        // SAFETY: plain scalar write through a live handle.
3117        unsafe { ffi::whiteout_m2_M2Sequence_set_variationNext(self.raw.as_ptr(), value) }
3118    }
3119
3120    pub fn alias_next(&self) -> u16 {
3121        // SAFETY: plain scalar read through a live handle.
3122        unsafe { ffi::whiteout_m2_M2Sequence_get_aliasNext(self.raw.as_ptr()) }
3123    }
3124
3125    pub fn set_alias_next(&mut self, value: u16) {
3126        // SAFETY: plain scalar write through a live handle.
3127        unsafe { ffi::whiteout_m2_M2Sequence_set_aliasNext(self.raw.as_ptr(), value) }
3128    }
3129}
3130
3131impl Default for Sequence {
3132    fn default() -> Self {
3133        Self::new()
3134    }
3135}
3136
3137pub struct Vertex {
3138    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2Vertex>,
3139}
3140
3141impl Drop for Vertex {
3142    fn drop(&mut self) {
3143        // SAFETY: `raw` came from a native constructor and Drop runs once.
3144        unsafe { ffi::whiteout_m2_M2Vertex_delete(self.raw.as_ptr()) }
3145    }
3146}
3147
3148impl Vertex {
3149    /// # Safety
3150    /// `raw` must be a live handle this value takes ownership of.
3151    #[allow(dead_code)] // used by whichever methods return this type
3152    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2Vertex) -> Option<Self> {
3153        core::ptr::NonNull::new(raw).map(|raw| Vertex { raw })
3154    }
3155}
3156
3157// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
3158// is deliberately NOT implemented — the C++ types make no documented
3159// guarantee about concurrent use, and claiming one we haven't verified
3160// would be unsound. See `@bind thread_safe` in the plan.
3161unsafe impl Send for Vertex {}
3162
3163impl core::fmt::Debug for Vertex {
3164    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3165        f.debug_struct("Vertex").finish_non_exhaustive()
3166    }
3167}
3168
3169impl Vertex {
3170    /// # Panics
3171    /// Panics if the native allocation fails.
3172    pub fn new() -> Self {
3173        // SAFETY: the native constructor returns a live handle; a null here
3174        // means the library is unusable.
3175        unsafe {
3176            let raw = ffi::whiteout_m2_M2Vertex_new();
3177            Self::from_raw(raw).expect("native Vertex allocation failed")
3178        }
3179    }
3180
3181    pub fn position(&self) -> crate::math::Vector3f {
3182        // SAFETY: the getter returns an interior pointer to a
3183        // layout-identical POD; we copy it out immediately.
3184        unsafe {
3185            *(ffi::whiteout_m2_M2Vertex_get_position(self.raw.as_ptr())
3186                as *const crate::math::Vector3f)
3187        }
3188    }
3189
3190    pub fn set_position(&mut self, value: crate::math::Vector3f) {
3191        // SAFETY: as above, in the other direction.
3192        unsafe {
3193            ffi::whiteout_m2_M2Vertex_set_position(
3194                self.raw.as_ptr(),
3195                &value as *const crate::math::Vector3f as *const _,
3196            )
3197        }
3198    }
3199
3200    pub fn bone_weights_len() -> usize {
3201        // SAFETY: a compile-time constant on the native side.
3202        unsafe { ffi::whiteout_m2_M2Vertex_boneWeights_size() }
3203    }
3204
3205    pub fn bone_weights(&self, index: usize) -> u8 {
3206        // SAFETY: scalar read. The native side does not bounds-
3207        // check, so callers stay within `bone_weights_len()`.
3208        unsafe { ffi::whiteout_m2_M2Vertex_get_boneWeights_at(self.raw.as_ptr(), index) }
3209    }
3210
3211    pub fn set_bone_weights(&mut self, index: usize, value: u8) {
3212        // SAFETY: as above.
3213        unsafe { ffi::whiteout_m2_M2Vertex_set_boneWeights_at(self.raw.as_ptr(), index, value) }
3214    }
3215
3216    pub fn bone_indices_len() -> usize {
3217        // SAFETY: a compile-time constant on the native side.
3218        unsafe { ffi::whiteout_m2_M2Vertex_boneIndices_size() }
3219    }
3220
3221    pub fn bone_indices(&self, index: usize) -> u8 {
3222        // SAFETY: scalar read. The native side does not bounds-
3223        // check, so callers stay within `bone_indices_len()`.
3224        unsafe { ffi::whiteout_m2_M2Vertex_get_boneIndices_at(self.raw.as_ptr(), index) }
3225    }
3226
3227    pub fn set_bone_indices(&mut self, index: usize, value: u8) {
3228        // SAFETY: as above.
3229        unsafe { ffi::whiteout_m2_M2Vertex_set_boneIndices_at(self.raw.as_ptr(), index, value) }
3230    }
3231
3232    pub fn normal(&self) -> crate::math::Vector3f {
3233        // SAFETY: the getter returns an interior pointer to a
3234        // layout-identical POD; we copy it out immediately.
3235        unsafe {
3236            *(ffi::whiteout_m2_M2Vertex_get_normal(self.raw.as_ptr())
3237                as *const crate::math::Vector3f)
3238        }
3239    }
3240
3241    pub fn set_normal(&mut self, value: crate::math::Vector3f) {
3242        // SAFETY: as above, in the other direction.
3243        unsafe {
3244            ffi::whiteout_m2_M2Vertex_set_normal(
3245                self.raw.as_ptr(),
3246                &value as *const crate::math::Vector3f as *const _,
3247            )
3248        }
3249    }
3250
3251    pub fn tex_coords_len() -> usize {
3252        // SAFETY: a compile-time constant on the native side.
3253        unsafe { ffi::whiteout_m2_M2Vertex_texCoords_size() }
3254    }
3255
3256    pub fn tex_coords(&self, index: usize) -> crate::math::Vector2f {
3257        // SAFETY: the getter returns an interior pointer to a
3258        // layout-identical POD, copied out immediately. The
3259        // native side does not bounds-check, so callers stay
3260        // within `tex_coords_len()`.
3261        unsafe {
3262            *(ffi::whiteout_m2_M2Vertex_get_texCoords_at(self.raw.as_ptr(), index)
3263                as *const crate::math::Vector2f)
3264        }
3265    }
3266}
3267
3268impl Default for Vertex {
3269    fn default() -> Self {
3270        Self::new()
3271    }
3272}
3273
3274pub struct Bone {
3275    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2Bone>,
3276}
3277
3278impl Drop for Bone {
3279    fn drop(&mut self) {
3280        // SAFETY: `raw` came from a native constructor and Drop runs once.
3281        unsafe { ffi::whiteout_m2_M2Bone_delete(self.raw.as_ptr()) }
3282    }
3283}
3284
3285impl Bone {
3286    /// # Safety
3287    /// `raw` must be a live handle this value takes ownership of.
3288    #[allow(dead_code)] // used by whichever methods return this type
3289    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2Bone) -> Option<Self> {
3290        core::ptr::NonNull::new(raw).map(|raw| Bone { raw })
3291    }
3292}
3293
3294// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
3295// is deliberately NOT implemented — the C++ types make no documented
3296// guarantee about concurrent use, and claiming one we haven't verified
3297// would be unsound. See `@bind thread_safe` in the plan.
3298unsafe impl Send for Bone {}
3299
3300impl core::fmt::Debug for Bone {
3301    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3302        f.debug_struct("Bone").finish_non_exhaustive()
3303    }
3304}
3305
3306impl Bone {
3307    /// # Panics
3308    /// Panics if the native allocation fails.
3309    pub fn new() -> Self {
3310        // SAFETY: the native constructor returns a live handle; a null here
3311        // means the library is unusable.
3312        unsafe {
3313            let raw = ffi::whiteout_m2_M2Bone_new();
3314            Self::from_raw(raw).expect("native Bone allocation failed")
3315        }
3316    }
3317
3318    pub fn key_bone_id(&self) -> i32 {
3319        // SAFETY: plain scalar read through a live handle.
3320        unsafe { ffi::whiteout_m2_M2Bone_get_keyBoneId(self.raw.as_ptr()) }
3321    }
3322
3323    pub fn set_key_bone_id(&mut self, value: i32) {
3324        // SAFETY: plain scalar write through a live handle.
3325        unsafe { ffi::whiteout_m2_M2Bone_set_keyBoneId(self.raw.as_ptr(), value) }
3326    }
3327
3328    pub fn flags(&self) -> u32 {
3329        // SAFETY: plain scalar read through a live handle.
3330        unsafe { ffi::whiteout_m2_M2Bone_get_flags(self.raw.as_ptr()) }
3331    }
3332
3333    pub fn set_flags(&mut self, value: u32) {
3334        // SAFETY: plain scalar write through a live handle.
3335        unsafe { ffi::whiteout_m2_M2Bone_set_flags(self.raw.as_ptr(), value) }
3336    }
3337
3338    pub fn parent_bone_id(&self) -> i16 {
3339        // SAFETY: plain scalar read through a live handle.
3340        unsafe { ffi::whiteout_m2_M2Bone_get_parentBoneId(self.raw.as_ptr()) }
3341    }
3342
3343    pub fn set_parent_bone_id(&mut self, value: i16) {
3344        // SAFETY: plain scalar write through a live handle.
3345        unsafe { ffi::whiteout_m2_M2Bone_set_parentBoneId(self.raw.as_ptr(), value) }
3346    }
3347
3348    pub fn submesh_id(&self) -> u16 {
3349        // SAFETY: plain scalar read through a live handle.
3350        unsafe { ffi::whiteout_m2_M2Bone_get_submeshId(self.raw.as_ptr()) }
3351    }
3352
3353    pub fn set_submesh_id(&mut self, value: u16) {
3354        // SAFETY: plain scalar write through a live handle.
3355        unsafe { ffi::whiteout_m2_M2Bone_set_submeshId(self.raw.as_ptr(), value) }
3356    }
3357
3358    pub fn bone_name_crc(&self) -> u32 {
3359        // SAFETY: plain scalar read through a live handle.
3360        unsafe { ffi::whiteout_m2_M2Bone_get_boneNameCRC(self.raw.as_ptr()) }
3361    }
3362
3363    pub fn set_bone_name_crc(&mut self, value: u32) {
3364        // SAFETY: plain scalar write through a live handle.
3365        unsafe { ffi::whiteout_m2_M2Bone_set_boneNameCRC(self.raw.as_ptr(), value) }
3366    }
3367
3368    /// Borrows the field in place — no copy, no allocation.
3369    pub fn translation(&self) -> crate::support::Ref<'_, AnimationTrackVector3f> {
3370        // SAFETY: an interior pointer into `self`, valid for this
3371        // borrow and never freed by the `Ref`.
3372        unsafe {
3373            crate::support::Ref::new(AnimationTrackVector3f {
3374                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Bone_get_translation(
3375                    self.raw.as_ptr(),
3376                )),
3377            })
3378        }
3379    }
3380
3381    pub fn translation_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackVector3f> {
3382        // SAFETY: as above; `&mut self` guarantees exclusivity.
3383        unsafe {
3384            crate::support::RefMut::new(AnimationTrackVector3f {
3385                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Bone_get_translation(
3386                    self.raw.as_ptr(),
3387                )),
3388            })
3389        }
3390    }
3391
3392    /// Borrows the field in place — no copy, no allocation.
3393    pub fn rotation(&self) -> crate::support::Ref<'_, AnimationTrackM2CompatQuaternion> {
3394        // SAFETY: an interior pointer into `self`, valid for this
3395        // borrow and never freed by the `Ref`.
3396        unsafe {
3397            crate::support::Ref::new(AnimationTrackM2CompatQuaternion {
3398                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Bone_get_rotation(
3399                    self.raw.as_ptr(),
3400                )),
3401            })
3402        }
3403    }
3404
3405    pub fn rotation_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackM2CompatQuaternion> {
3406        // SAFETY: as above; `&mut self` guarantees exclusivity.
3407        unsafe {
3408            crate::support::RefMut::new(AnimationTrackM2CompatQuaternion {
3409                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Bone_get_rotation(
3410                    self.raw.as_ptr(),
3411                )),
3412            })
3413        }
3414    }
3415
3416    /// Borrows the field in place — no copy, no allocation.
3417    pub fn scale(&self) -> crate::support::Ref<'_, AnimationTrackVector3f> {
3418        // SAFETY: an interior pointer into `self`, valid for this
3419        // borrow and never freed by the `Ref`.
3420        unsafe {
3421            crate::support::Ref::new(AnimationTrackVector3f {
3422                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Bone_get_scale(
3423                    self.raw.as_ptr(),
3424                )),
3425            })
3426        }
3427    }
3428
3429    pub fn scale_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackVector3f> {
3430        // SAFETY: as above; `&mut self` guarantees exclusivity.
3431        unsafe {
3432            crate::support::RefMut::new(AnimationTrackVector3f {
3433                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Bone_get_scale(
3434                    self.raw.as_ptr(),
3435                )),
3436            })
3437        }
3438    }
3439
3440    pub fn pivot(&self) -> crate::math::Vector3f {
3441        // SAFETY: the getter returns an interior pointer to a
3442        // layout-identical POD; we copy it out immediately.
3443        unsafe {
3444            *(ffi::whiteout_m2_M2Bone_get_pivot(self.raw.as_ptr()) as *const crate::math::Vector3f)
3445        }
3446    }
3447
3448    pub fn set_pivot(&mut self, value: crate::math::Vector3f) {
3449        // SAFETY: as above, in the other direction.
3450        unsafe {
3451            ffi::whiteout_m2_M2Bone_set_pivot(
3452                self.raw.as_ptr(),
3453                &value as *const crate::math::Vector3f as *const _,
3454            )
3455        }
3456    }
3457}
3458
3459impl Default for Bone {
3460    fn default() -> Self {
3461        Self::new()
3462    }
3463}
3464
3465pub struct Texture {
3466    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2Texture>,
3467}
3468
3469impl Drop for Texture {
3470    fn drop(&mut self) {
3471        // SAFETY: `raw` came from a native constructor and Drop runs once.
3472        unsafe { ffi::whiteout_m2_M2Texture_delete(self.raw.as_ptr()) }
3473    }
3474}
3475
3476impl Texture {
3477    /// # Safety
3478    /// `raw` must be a live handle this value takes ownership of.
3479    #[allow(dead_code)] // used by whichever methods return this type
3480    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2Texture) -> Option<Self> {
3481        core::ptr::NonNull::new(raw).map(|raw| Texture { raw })
3482    }
3483}
3484
3485// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
3486// is deliberately NOT implemented — the C++ types make no documented
3487// guarantee about concurrent use, and claiming one we haven't verified
3488// would be unsound. See `@bind thread_safe` in the plan.
3489unsafe impl Send for Texture {}
3490
3491impl core::fmt::Debug for Texture {
3492    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3493        f.debug_struct("Texture").finish_non_exhaustive()
3494    }
3495}
3496
3497impl Texture {
3498    /// # Panics
3499    /// Panics if the native allocation fails.
3500    pub fn new() -> Self {
3501        // SAFETY: the native constructor returns a live handle; a null here
3502        // means the library is unusable.
3503        unsafe {
3504            let raw = ffi::whiteout_m2_M2Texture_new();
3505            Self::from_raw(raw).expect("native Texture allocation failed")
3506        }
3507    }
3508
3509    pub fn type_(&self) -> u32 {
3510        // SAFETY: plain scalar read through a live handle.
3511        unsafe { ffi::whiteout_m2_M2Texture_get_type(self.raw.as_ptr()) }
3512    }
3513
3514    pub fn set_type_(&mut self, value: u32) {
3515        // SAFETY: plain scalar write through a live handle.
3516        unsafe { ffi::whiteout_m2_M2Texture_set_type(self.raw.as_ptr(), value) }
3517    }
3518
3519    pub fn flags(&self) -> u32 {
3520        // SAFETY: plain scalar read through a live handle.
3521        unsafe { ffi::whiteout_m2_M2Texture_get_flags(self.raw.as_ptr()) }
3522    }
3523
3524    pub fn set_flags(&mut self, value: u32) {
3525        // SAFETY: plain scalar write through a live handle.
3526        unsafe { ffi::whiteout_m2_M2Texture_set_flags(self.raw.as_ptr(), value) }
3527    }
3528
3529    pub fn filename(&self) -> String {
3530        // SAFETY: the native side hands over an owned CString.
3531        unsafe {
3532            crate::support::take_string(ffi::whiteout_m2_M2Texture_get_filename(self.raw.as_ptr()))
3533        }
3534    }
3535
3536    pub fn set_filename(&mut self, value: &str) {
3537        let value = std::ffi::CString::new(value).unwrap_or_default();
3538        // SAFETY: the pointer outlives the call.
3539        unsafe { ffi::whiteout_m2_M2Texture_set_filename(self.raw.as_ptr(), value.as_ptr()) }
3540    }
3541}
3542
3543impl Default for Texture {
3544    fn default() -> Self {
3545        Self::new()
3546    }
3547}
3548
3549pub struct Material {
3550    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2Material>,
3551}
3552
3553impl Drop for Material {
3554    fn drop(&mut self) {
3555        // SAFETY: `raw` came from a native constructor and Drop runs once.
3556        unsafe { ffi::whiteout_m2_M2Material_delete(self.raw.as_ptr()) }
3557    }
3558}
3559
3560impl Material {
3561    /// # Safety
3562    /// `raw` must be a live handle this value takes ownership of.
3563    #[allow(dead_code)] // used by whichever methods return this type
3564    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2Material) -> Option<Self> {
3565        core::ptr::NonNull::new(raw).map(|raw| Material { raw })
3566    }
3567}
3568
3569// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
3570// is deliberately NOT implemented — the C++ types make no documented
3571// guarantee about concurrent use, and claiming one we haven't verified
3572// would be unsound. See `@bind thread_safe` in the plan.
3573unsafe impl Send for Material {}
3574
3575impl core::fmt::Debug for Material {
3576    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3577        f.debug_struct("Material").finish_non_exhaustive()
3578    }
3579}
3580
3581impl Material {
3582    /// # Panics
3583    /// Panics if the native allocation fails.
3584    pub fn new() -> Self {
3585        // SAFETY: the native constructor returns a live handle; a null here
3586        // means the library is unusable.
3587        unsafe {
3588            let raw = ffi::whiteout_m2_M2Material_new();
3589            Self::from_raw(raw).expect("native Material allocation failed")
3590        }
3591    }
3592
3593    pub fn flags(&self) -> u16 {
3594        // SAFETY: plain scalar read through a live handle.
3595        unsafe { ffi::whiteout_m2_M2Material_get_flags(self.raw.as_ptr()) }
3596    }
3597
3598    pub fn set_flags(&mut self, value: u16) {
3599        // SAFETY: plain scalar write through a live handle.
3600        unsafe { ffi::whiteout_m2_M2Material_set_flags(self.raw.as_ptr(), value) }
3601    }
3602
3603    pub fn blending_mode(&self) -> u16 {
3604        // SAFETY: plain scalar read through a live handle.
3605        unsafe { ffi::whiteout_m2_M2Material_get_blendingMode(self.raw.as_ptr()) }
3606    }
3607
3608    pub fn set_blending_mode(&mut self, value: u16) {
3609        // SAFETY: plain scalar write through a live handle.
3610        unsafe { ffi::whiteout_m2_M2Material_set_blendingMode(self.raw.as_ptr(), value) }
3611    }
3612}
3613
3614impl Default for Material {
3615    fn default() -> Self {
3616        Self::new()
3617    }
3618}
3619
3620pub struct TextureWeight {
3621    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2TextureWeight>,
3622}
3623
3624impl Drop for TextureWeight {
3625    fn drop(&mut self) {
3626        // SAFETY: `raw` came from a native constructor and Drop runs once.
3627        unsafe { ffi::whiteout_m2_M2TextureWeight_delete(self.raw.as_ptr()) }
3628    }
3629}
3630
3631impl TextureWeight {
3632    /// # Safety
3633    /// `raw` must be a live handle this value takes ownership of.
3634    #[allow(dead_code)] // used by whichever methods return this type
3635    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2TextureWeight) -> Option<Self> {
3636        core::ptr::NonNull::new(raw).map(|raw| TextureWeight { raw })
3637    }
3638}
3639
3640// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
3641// is deliberately NOT implemented — the C++ types make no documented
3642// guarantee about concurrent use, and claiming one we haven't verified
3643// would be unsound. See `@bind thread_safe` in the plan.
3644unsafe impl Send for TextureWeight {}
3645
3646impl core::fmt::Debug for TextureWeight {
3647    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3648        f.debug_struct("TextureWeight").finish_non_exhaustive()
3649    }
3650}
3651
3652impl TextureWeight {
3653    /// # Panics
3654    /// Panics if the native allocation fails.
3655    pub fn new() -> Self {
3656        // SAFETY: the native constructor returns a live handle; a null here
3657        // means the library is unusable.
3658        unsafe {
3659            let raw = ffi::whiteout_m2_M2TextureWeight_new();
3660            Self::from_raw(raw).expect("native TextureWeight allocation failed")
3661        }
3662    }
3663
3664    /// Borrows the field in place — no copy, no allocation.
3665    pub fn weight(&self) -> crate::support::Ref<'_, AnimationTrackI16> {
3666        // SAFETY: an interior pointer into `self`, valid for this
3667        // borrow and never freed by the `Ref`.
3668        unsafe {
3669            crate::support::Ref::new(AnimationTrackI16 {
3670                raw: core::ptr::NonNull::new_unchecked(
3671                    ffi::whiteout_m2_M2TextureWeight_get_weight(self.raw.as_ptr()),
3672                ),
3673            })
3674        }
3675    }
3676
3677    pub fn weight_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackI16> {
3678        // SAFETY: as above; `&mut self` guarantees exclusivity.
3679        unsafe {
3680            crate::support::RefMut::new(AnimationTrackI16 {
3681                raw: core::ptr::NonNull::new_unchecked(
3682                    ffi::whiteout_m2_M2TextureWeight_get_weight(self.raw.as_ptr()),
3683                ),
3684            })
3685        }
3686    }
3687}
3688
3689impl Default for TextureWeight {
3690    fn default() -> Self {
3691        Self::new()
3692    }
3693}
3694
3695pub struct TextureTransform {
3696    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2TextureTransform>,
3697}
3698
3699impl Drop for TextureTransform {
3700    fn drop(&mut self) {
3701        // SAFETY: `raw` came from a native constructor and Drop runs once.
3702        unsafe { ffi::whiteout_m2_M2TextureTransform_delete(self.raw.as_ptr()) }
3703    }
3704}
3705
3706impl TextureTransform {
3707    /// # Safety
3708    /// `raw` must be a live handle this value takes ownership of.
3709    #[allow(dead_code)] // used by whichever methods return this type
3710    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2TextureTransform) -> Option<Self> {
3711        core::ptr::NonNull::new(raw).map(|raw| TextureTransform { raw })
3712    }
3713}
3714
3715// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
3716// is deliberately NOT implemented — the C++ types make no documented
3717// guarantee about concurrent use, and claiming one we haven't verified
3718// would be unsound. See `@bind thread_safe` in the plan.
3719unsafe impl Send for TextureTransform {}
3720
3721impl core::fmt::Debug for TextureTransform {
3722    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3723        f.debug_struct("TextureTransform").finish_non_exhaustive()
3724    }
3725}
3726
3727impl TextureTransform {
3728    /// # Panics
3729    /// Panics if the native allocation fails.
3730    pub fn new() -> Self {
3731        // SAFETY: the native constructor returns a live handle; a null here
3732        // means the library is unusable.
3733        unsafe {
3734            let raw = ffi::whiteout_m2_M2TextureTransform_new();
3735            Self::from_raw(raw).expect("native TextureTransform allocation failed")
3736        }
3737    }
3738
3739    /// Borrows the field in place — no copy, no allocation.
3740    pub fn translation(&self) -> crate::support::Ref<'_, AnimationTrackVector3f> {
3741        // SAFETY: an interior pointer into `self`, valid for this
3742        // borrow and never freed by the `Ref`.
3743        unsafe {
3744            crate::support::Ref::new(AnimationTrackVector3f {
3745                raw: core::ptr::NonNull::new_unchecked(
3746                    ffi::whiteout_m2_M2TextureTransform_get_translation(self.raw.as_ptr()),
3747                ),
3748            })
3749        }
3750    }
3751
3752    pub fn translation_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackVector3f> {
3753        // SAFETY: as above; `&mut self` guarantees exclusivity.
3754        unsafe {
3755            crate::support::RefMut::new(AnimationTrackVector3f {
3756                raw: core::ptr::NonNull::new_unchecked(
3757                    ffi::whiteout_m2_M2TextureTransform_get_translation(self.raw.as_ptr()),
3758                ),
3759            })
3760        }
3761    }
3762
3763    /// Borrows the field in place — no copy, no allocation.
3764    pub fn rotation(&self) -> crate::support::Ref<'_, AnimationTrackM2CompatQuaternion> {
3765        // SAFETY: an interior pointer into `self`, valid for this
3766        // borrow and never freed by the `Ref`.
3767        unsafe {
3768            crate::support::Ref::new(AnimationTrackM2CompatQuaternion {
3769                raw: core::ptr::NonNull::new_unchecked(
3770                    ffi::whiteout_m2_M2TextureTransform_get_rotation(self.raw.as_ptr()),
3771                ),
3772            })
3773        }
3774    }
3775
3776    pub fn rotation_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackM2CompatQuaternion> {
3777        // SAFETY: as above; `&mut self` guarantees exclusivity.
3778        unsafe {
3779            crate::support::RefMut::new(AnimationTrackM2CompatQuaternion {
3780                raw: core::ptr::NonNull::new_unchecked(
3781                    ffi::whiteout_m2_M2TextureTransform_get_rotation(self.raw.as_ptr()),
3782                ),
3783            })
3784        }
3785    }
3786
3787    /// Borrows the field in place — no copy, no allocation.
3788    pub fn scaling(&self) -> crate::support::Ref<'_, AnimationTrackVector3f> {
3789        // SAFETY: an interior pointer into `self`, valid for this
3790        // borrow and never freed by the `Ref`.
3791        unsafe {
3792            crate::support::Ref::new(AnimationTrackVector3f {
3793                raw: core::ptr::NonNull::new_unchecked(
3794                    ffi::whiteout_m2_M2TextureTransform_get_scaling(self.raw.as_ptr()),
3795                ),
3796            })
3797        }
3798    }
3799
3800    pub fn scaling_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackVector3f> {
3801        // SAFETY: as above; `&mut self` guarantees exclusivity.
3802        unsafe {
3803            crate::support::RefMut::new(AnimationTrackVector3f {
3804                raw: core::ptr::NonNull::new_unchecked(
3805                    ffi::whiteout_m2_M2TextureTransform_get_scaling(self.raw.as_ptr()),
3806                ),
3807            })
3808        }
3809    }
3810}
3811
3812impl Default for TextureTransform {
3813    fn default() -> Self {
3814        Self::new()
3815    }
3816}
3817
3818pub struct ColorAnimation {
3819    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2ColorAnimation>,
3820}
3821
3822impl Drop for ColorAnimation {
3823    fn drop(&mut self) {
3824        // SAFETY: `raw` came from a native constructor and Drop runs once.
3825        unsafe { ffi::whiteout_m2_M2ColorAnimation_delete(self.raw.as_ptr()) }
3826    }
3827}
3828
3829impl ColorAnimation {
3830    /// # Safety
3831    /// `raw` must be a live handle this value takes ownership of.
3832    #[allow(dead_code)] // used by whichever methods return this type
3833    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2ColorAnimation) -> Option<Self> {
3834        core::ptr::NonNull::new(raw).map(|raw| ColorAnimation { raw })
3835    }
3836}
3837
3838// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
3839// is deliberately NOT implemented — the C++ types make no documented
3840// guarantee about concurrent use, and claiming one we haven't verified
3841// would be unsound. See `@bind thread_safe` in the plan.
3842unsafe impl Send for ColorAnimation {}
3843
3844impl core::fmt::Debug for ColorAnimation {
3845    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3846        f.debug_struct("ColorAnimation").finish_non_exhaustive()
3847    }
3848}
3849
3850impl ColorAnimation {
3851    /// # Panics
3852    /// Panics if the native allocation fails.
3853    pub fn new() -> Self {
3854        // SAFETY: the native constructor returns a live handle; a null here
3855        // means the library is unusable.
3856        unsafe {
3857            let raw = ffi::whiteout_m2_M2ColorAnimation_new();
3858            Self::from_raw(raw).expect("native ColorAnimation allocation failed")
3859        }
3860    }
3861
3862    /// Borrows the field in place — no copy, no allocation.
3863    pub fn color(&self) -> crate::support::Ref<'_, AnimationTrackVector3f> {
3864        // SAFETY: an interior pointer into `self`, valid for this
3865        // borrow and never freed by the `Ref`.
3866        unsafe {
3867            crate::support::Ref::new(AnimationTrackVector3f {
3868                raw: core::ptr::NonNull::new_unchecked(
3869                    ffi::whiteout_m2_M2ColorAnimation_get_color(self.raw.as_ptr()),
3870                ),
3871            })
3872        }
3873    }
3874
3875    pub fn color_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackVector3f> {
3876        // SAFETY: as above; `&mut self` guarantees exclusivity.
3877        unsafe {
3878            crate::support::RefMut::new(AnimationTrackVector3f {
3879                raw: core::ptr::NonNull::new_unchecked(
3880                    ffi::whiteout_m2_M2ColorAnimation_get_color(self.raw.as_ptr()),
3881                ),
3882            })
3883        }
3884    }
3885
3886    /// Borrows the field in place — no copy, no allocation.
3887    pub fn alpha(&self) -> crate::support::Ref<'_, AnimationTrackI16> {
3888        // SAFETY: an interior pointer into `self`, valid for this
3889        // borrow and never freed by the `Ref`.
3890        unsafe {
3891            crate::support::Ref::new(AnimationTrackI16 {
3892                raw: core::ptr::NonNull::new_unchecked(
3893                    ffi::whiteout_m2_M2ColorAnimation_get_alpha(self.raw.as_ptr()),
3894                ),
3895            })
3896        }
3897    }
3898
3899    pub fn alpha_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackI16> {
3900        // SAFETY: as above; `&mut self` guarantees exclusivity.
3901        unsafe {
3902            crate::support::RefMut::new(AnimationTrackI16 {
3903                raw: core::ptr::NonNull::new_unchecked(
3904                    ffi::whiteout_m2_M2ColorAnimation_get_alpha(self.raw.as_ptr()),
3905                ),
3906            })
3907        }
3908    }
3909}
3910
3911impl Default for ColorAnimation {
3912    fn default() -> Self {
3913        Self::new()
3914    }
3915}
3916
3917pub struct Light {
3918    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2Light>,
3919}
3920
3921impl Drop for Light {
3922    fn drop(&mut self) {
3923        // SAFETY: `raw` came from a native constructor and Drop runs once.
3924        unsafe { ffi::whiteout_m2_M2Light_delete(self.raw.as_ptr()) }
3925    }
3926}
3927
3928impl Light {
3929    /// # Safety
3930    /// `raw` must be a live handle this value takes ownership of.
3931    #[allow(dead_code)] // used by whichever methods return this type
3932    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2Light) -> Option<Self> {
3933        core::ptr::NonNull::new(raw).map(|raw| Light { raw })
3934    }
3935}
3936
3937// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
3938// is deliberately NOT implemented — the C++ types make no documented
3939// guarantee about concurrent use, and claiming one we haven't verified
3940// would be unsound. See `@bind thread_safe` in the plan.
3941unsafe impl Send for Light {}
3942
3943impl core::fmt::Debug for Light {
3944    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3945        f.debug_struct("Light").finish_non_exhaustive()
3946    }
3947}
3948
3949impl Light {
3950    /// # Panics
3951    /// Panics if the native allocation fails.
3952    pub fn new() -> Self {
3953        // SAFETY: the native constructor returns a live handle; a null here
3954        // means the library is unusable.
3955        unsafe {
3956            let raw = ffi::whiteout_m2_M2Light_new();
3957            Self::from_raw(raw).expect("native Light allocation failed")
3958        }
3959    }
3960
3961    pub fn type_(&self) -> u16 {
3962        // SAFETY: plain scalar read through a live handle.
3963        unsafe { ffi::whiteout_m2_M2Light_get_type(self.raw.as_ptr()) }
3964    }
3965
3966    pub fn set_type_(&mut self, value: u16) {
3967        // SAFETY: plain scalar write through a live handle.
3968        unsafe { ffi::whiteout_m2_M2Light_set_type(self.raw.as_ptr(), value) }
3969    }
3970
3971    pub fn bone_id(&self) -> i16 {
3972        // SAFETY: plain scalar read through a live handle.
3973        unsafe { ffi::whiteout_m2_M2Light_get_boneId(self.raw.as_ptr()) }
3974    }
3975
3976    pub fn set_bone_id(&mut self, value: i16) {
3977        // SAFETY: plain scalar write through a live handle.
3978        unsafe { ffi::whiteout_m2_M2Light_set_boneId(self.raw.as_ptr(), value) }
3979    }
3980
3981    pub fn position(&self) -> crate::math::Vector3f {
3982        // SAFETY: the getter returns an interior pointer to a
3983        // layout-identical POD; we copy it out immediately.
3984        unsafe {
3985            *(ffi::whiteout_m2_M2Light_get_position(self.raw.as_ptr())
3986                as *const crate::math::Vector3f)
3987        }
3988    }
3989
3990    pub fn set_position(&mut self, value: crate::math::Vector3f) {
3991        // SAFETY: as above, in the other direction.
3992        unsafe {
3993            ffi::whiteout_m2_M2Light_set_position(
3994                self.raw.as_ptr(),
3995                &value as *const crate::math::Vector3f as *const _,
3996            )
3997        }
3998    }
3999
4000    /// Borrows the field in place — no copy, no allocation.
4001    pub fn ambient_color(&self) -> crate::support::Ref<'_, AnimationTrackVector3f> {
4002        // SAFETY: an interior pointer into `self`, valid for this
4003        // borrow and never freed by the `Ref`.
4004        unsafe {
4005            crate::support::Ref::new(AnimationTrackVector3f {
4006                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Light_get_ambientColor(
4007                    self.raw.as_ptr(),
4008                )),
4009            })
4010        }
4011    }
4012
4013    pub fn ambient_color_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackVector3f> {
4014        // SAFETY: as above; `&mut self` guarantees exclusivity.
4015        unsafe {
4016            crate::support::RefMut::new(AnimationTrackVector3f {
4017                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Light_get_ambientColor(
4018                    self.raw.as_ptr(),
4019                )),
4020            })
4021        }
4022    }
4023
4024    /// Borrows the field in place — no copy, no allocation.
4025    pub fn ambient_intensity(&self) -> crate::support::Ref<'_, AnimationTrackF32> {
4026        // SAFETY: an interior pointer into `self`, valid for this
4027        // borrow and never freed by the `Ref`.
4028        unsafe {
4029            crate::support::Ref::new(AnimationTrackF32 {
4030                raw: core::ptr::NonNull::new_unchecked(
4031                    ffi::whiteout_m2_M2Light_get_ambientIntensity(self.raw.as_ptr()),
4032                ),
4033            })
4034        }
4035    }
4036
4037    pub fn ambient_intensity_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackF32> {
4038        // SAFETY: as above; `&mut self` guarantees exclusivity.
4039        unsafe {
4040            crate::support::RefMut::new(AnimationTrackF32 {
4041                raw: core::ptr::NonNull::new_unchecked(
4042                    ffi::whiteout_m2_M2Light_get_ambientIntensity(self.raw.as_ptr()),
4043                ),
4044            })
4045        }
4046    }
4047
4048    /// Borrows the field in place — no copy, no allocation.
4049    pub fn diffuse_color(&self) -> crate::support::Ref<'_, AnimationTrackVector3f> {
4050        // SAFETY: an interior pointer into `self`, valid for this
4051        // borrow and never freed by the `Ref`.
4052        unsafe {
4053            crate::support::Ref::new(AnimationTrackVector3f {
4054                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Light_get_diffuseColor(
4055                    self.raw.as_ptr(),
4056                )),
4057            })
4058        }
4059    }
4060
4061    pub fn diffuse_color_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackVector3f> {
4062        // SAFETY: as above; `&mut self` guarantees exclusivity.
4063        unsafe {
4064            crate::support::RefMut::new(AnimationTrackVector3f {
4065                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Light_get_diffuseColor(
4066                    self.raw.as_ptr(),
4067                )),
4068            })
4069        }
4070    }
4071
4072    /// Borrows the field in place — no copy, no allocation.
4073    pub fn diffuse_intensity(&self) -> crate::support::Ref<'_, AnimationTrackF32> {
4074        // SAFETY: an interior pointer into `self`, valid for this
4075        // borrow and never freed by the `Ref`.
4076        unsafe {
4077            crate::support::Ref::new(AnimationTrackF32 {
4078                raw: core::ptr::NonNull::new_unchecked(
4079                    ffi::whiteout_m2_M2Light_get_diffuseIntensity(self.raw.as_ptr()),
4080                ),
4081            })
4082        }
4083    }
4084
4085    pub fn diffuse_intensity_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackF32> {
4086        // SAFETY: as above; `&mut self` guarantees exclusivity.
4087        unsafe {
4088            crate::support::RefMut::new(AnimationTrackF32 {
4089                raw: core::ptr::NonNull::new_unchecked(
4090                    ffi::whiteout_m2_M2Light_get_diffuseIntensity(self.raw.as_ptr()),
4091                ),
4092            })
4093        }
4094    }
4095
4096    /// Borrows the field in place — no copy, no allocation.
4097    pub fn attenuation_start(&self) -> crate::support::Ref<'_, AnimationTrackF32> {
4098        // SAFETY: an interior pointer into `self`, valid for this
4099        // borrow and never freed by the `Ref`.
4100        unsafe {
4101            crate::support::Ref::new(AnimationTrackF32 {
4102                raw: core::ptr::NonNull::new_unchecked(
4103                    ffi::whiteout_m2_M2Light_get_attenuationStart(self.raw.as_ptr()),
4104                ),
4105            })
4106        }
4107    }
4108
4109    pub fn attenuation_start_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackF32> {
4110        // SAFETY: as above; `&mut self` guarantees exclusivity.
4111        unsafe {
4112            crate::support::RefMut::new(AnimationTrackF32 {
4113                raw: core::ptr::NonNull::new_unchecked(
4114                    ffi::whiteout_m2_M2Light_get_attenuationStart(self.raw.as_ptr()),
4115                ),
4116            })
4117        }
4118    }
4119
4120    /// Borrows the field in place — no copy, no allocation.
4121    pub fn attenuation_end(&self) -> crate::support::Ref<'_, AnimationTrackF32> {
4122        // SAFETY: an interior pointer into `self`, valid for this
4123        // borrow and never freed by the `Ref`.
4124        unsafe {
4125            crate::support::Ref::new(AnimationTrackF32 {
4126                raw: core::ptr::NonNull::new_unchecked(
4127                    ffi::whiteout_m2_M2Light_get_attenuationEnd(self.raw.as_ptr()),
4128                ),
4129            })
4130        }
4131    }
4132
4133    pub fn attenuation_end_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackF32> {
4134        // SAFETY: as above; `&mut self` guarantees exclusivity.
4135        unsafe {
4136            crate::support::RefMut::new(AnimationTrackF32 {
4137                raw: core::ptr::NonNull::new_unchecked(
4138                    ffi::whiteout_m2_M2Light_get_attenuationEnd(self.raw.as_ptr()),
4139                ),
4140            })
4141        }
4142    }
4143
4144    /// Borrows the field in place — no copy, no allocation.
4145    pub fn visibility(&self) -> crate::support::Ref<'_, AnimationTrackU8> {
4146        // SAFETY: an interior pointer into `self`, valid for this
4147        // borrow and never freed by the `Ref`.
4148        unsafe {
4149            crate::support::Ref::new(AnimationTrackU8 {
4150                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Light_get_visibility(
4151                    self.raw.as_ptr(),
4152                )),
4153            })
4154        }
4155    }
4156
4157    pub fn visibility_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackU8> {
4158        // SAFETY: as above; `&mut self` guarantees exclusivity.
4159        unsafe {
4160            crate::support::RefMut::new(AnimationTrackU8 {
4161                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Light_get_visibility(
4162                    self.raw.as_ptr(),
4163                )),
4164            })
4165        }
4166    }
4167}
4168
4169impl Default for Light {
4170    fn default() -> Self {
4171        Self::new()
4172    }
4173}
4174
4175pub struct CameraSpline {
4176    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2CameraSpline>,
4177}
4178
4179impl Drop for CameraSpline {
4180    fn drop(&mut self) {
4181        // SAFETY: `raw` came from a native constructor and Drop runs once.
4182        unsafe { ffi::whiteout_m2_M2CameraSpline_delete(self.raw.as_ptr()) }
4183    }
4184}
4185
4186impl CameraSpline {
4187    /// # Safety
4188    /// `raw` must be a live handle this value takes ownership of.
4189    #[allow(dead_code)] // used by whichever methods return this type
4190    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2CameraSpline) -> Option<Self> {
4191        core::ptr::NonNull::new(raw).map(|raw| CameraSpline { raw })
4192    }
4193}
4194
4195// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
4196// is deliberately NOT implemented — the C++ types make no documented
4197// guarantee about concurrent use, and claiming one we haven't verified
4198// would be unsound. See `@bind thread_safe` in the plan.
4199unsafe impl Send for CameraSpline {}
4200
4201impl core::fmt::Debug for CameraSpline {
4202    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
4203        f.debug_struct("CameraSpline").finish_non_exhaustive()
4204    }
4205}
4206
4207impl CameraSpline {
4208    /// # Panics
4209    /// Panics if the native allocation fails.
4210    pub fn new() -> Self {
4211        // SAFETY: the native constructor returns a live handle; a null here
4212        // means the library is unusable.
4213        unsafe {
4214            let raw = ffi::whiteout_m2_M2CameraSpline_new();
4215            Self::from_raw(raw).expect("native CameraSpline allocation failed")
4216        }
4217    }
4218
4219    pub fn value(&self) -> crate::math::Vector3f {
4220        // SAFETY: the getter returns an interior pointer to a
4221        // layout-identical POD; we copy it out immediately.
4222        unsafe {
4223            *(ffi::whiteout_m2_M2CameraSpline_get_value(self.raw.as_ptr())
4224                as *const crate::math::Vector3f)
4225        }
4226    }
4227
4228    pub fn set_value(&mut self, value: crate::math::Vector3f) {
4229        // SAFETY: as above, in the other direction.
4230        unsafe {
4231            ffi::whiteout_m2_M2CameraSpline_set_value(
4232                self.raw.as_ptr(),
4233                &value as *const crate::math::Vector3f as *const _,
4234            )
4235        }
4236    }
4237
4238    pub fn in_tangent(&self) -> crate::math::Vector3f {
4239        // SAFETY: the getter returns an interior pointer to a
4240        // layout-identical POD; we copy it out immediately.
4241        unsafe {
4242            *(ffi::whiteout_m2_M2CameraSpline_get_inTangent(self.raw.as_ptr())
4243                as *const crate::math::Vector3f)
4244        }
4245    }
4246
4247    pub fn set_in_tangent(&mut self, value: crate::math::Vector3f) {
4248        // SAFETY: as above, in the other direction.
4249        unsafe {
4250            ffi::whiteout_m2_M2CameraSpline_set_inTangent(
4251                self.raw.as_ptr(),
4252                &value as *const crate::math::Vector3f as *const _,
4253            )
4254        }
4255    }
4256
4257    pub fn out_tangent(&self) -> crate::math::Vector3f {
4258        // SAFETY: the getter returns an interior pointer to a
4259        // layout-identical POD; we copy it out immediately.
4260        unsafe {
4261            *(ffi::whiteout_m2_M2CameraSpline_get_outTangent(self.raw.as_ptr())
4262                as *const crate::math::Vector3f)
4263        }
4264    }
4265
4266    pub fn set_out_tangent(&mut self, value: crate::math::Vector3f) {
4267        // SAFETY: as above, in the other direction.
4268        unsafe {
4269            ffi::whiteout_m2_M2CameraSpline_set_outTangent(
4270                self.raw.as_ptr(),
4271                &value as *const crate::math::Vector3f as *const _,
4272            )
4273        }
4274    }
4275}
4276
4277impl Default for CameraSpline {
4278    fn default() -> Self {
4279        Self::new()
4280    }
4281}
4282
4283pub struct Camera {
4284    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2Camera>,
4285}
4286
4287impl Drop for Camera {
4288    fn drop(&mut self) {
4289        // SAFETY: `raw` came from a native constructor and Drop runs once.
4290        unsafe { ffi::whiteout_m2_M2Camera_delete(self.raw.as_ptr()) }
4291    }
4292}
4293
4294impl Camera {
4295    /// # Safety
4296    /// `raw` must be a live handle this value takes ownership of.
4297    #[allow(dead_code)] // used by whichever methods return this type
4298    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2Camera) -> Option<Self> {
4299        core::ptr::NonNull::new(raw).map(|raw| Camera { raw })
4300    }
4301}
4302
4303// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
4304// is deliberately NOT implemented — the C++ types make no documented
4305// guarantee about concurrent use, and claiming one we haven't verified
4306// would be unsound. See `@bind thread_safe` in the plan.
4307unsafe impl Send for Camera {}
4308
4309impl core::fmt::Debug for Camera {
4310    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
4311        f.debug_struct("Camera").finish_non_exhaustive()
4312    }
4313}
4314
4315impl Camera {
4316    /// # Panics
4317    /// Panics if the native allocation fails.
4318    pub fn new() -> Self {
4319        // SAFETY: the native constructor returns a live handle; a null here
4320        // means the library is unusable.
4321        unsafe {
4322            let raw = ffi::whiteout_m2_M2Camera_new();
4323            Self::from_raw(raw).expect("native Camera allocation failed")
4324        }
4325    }
4326
4327    pub fn type_(&self) -> u32 {
4328        // SAFETY: plain scalar read through a live handle.
4329        unsafe { ffi::whiteout_m2_M2Camera_get_type(self.raw.as_ptr()) }
4330    }
4331
4332    pub fn set_type_(&mut self, value: u32) {
4333        // SAFETY: plain scalar write through a live handle.
4334        unsafe { ffi::whiteout_m2_M2Camera_set_type(self.raw.as_ptr(), value) }
4335    }
4336
4337    pub fn field_of_view(&self) -> f32 {
4338        // SAFETY: plain scalar read through a live handle.
4339        unsafe { ffi::whiteout_m2_M2Camera_get_fieldOfView(self.raw.as_ptr()) }
4340    }
4341
4342    pub fn set_field_of_view(&mut self, value: f32) {
4343        // SAFETY: plain scalar write through a live handle.
4344        unsafe { ffi::whiteout_m2_M2Camera_set_fieldOfView(self.raw.as_ptr(), value) }
4345    }
4346
4347    pub fn far_clip(&self) -> f32 {
4348        // SAFETY: plain scalar read through a live handle.
4349        unsafe { ffi::whiteout_m2_M2Camera_get_farClip(self.raw.as_ptr()) }
4350    }
4351
4352    pub fn set_far_clip(&mut self, value: f32) {
4353        // SAFETY: plain scalar write through a live handle.
4354        unsafe { ffi::whiteout_m2_M2Camera_set_farClip(self.raw.as_ptr(), value) }
4355    }
4356
4357    pub fn near_clip(&self) -> f32 {
4358        // SAFETY: plain scalar read through a live handle.
4359        unsafe { ffi::whiteout_m2_M2Camera_get_nearClip(self.raw.as_ptr()) }
4360    }
4361
4362    pub fn set_near_clip(&mut self, value: f32) {
4363        // SAFETY: plain scalar write through a live handle.
4364        unsafe { ffi::whiteout_m2_M2Camera_set_nearClip(self.raw.as_ptr(), value) }
4365    }
4366
4367    /// Borrows the field in place — no copy, no allocation.
4368    pub fn positions(&self) -> crate::support::Ref<'_, AnimationTrackM2CameraSpline> {
4369        // SAFETY: an interior pointer into `self`, valid for this
4370        // borrow and never freed by the `Ref`.
4371        unsafe {
4372            crate::support::Ref::new(AnimationTrackM2CameraSpline {
4373                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Camera_get_positions(
4374                    self.raw.as_ptr(),
4375                )),
4376            })
4377        }
4378    }
4379
4380    pub fn positions_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackM2CameraSpline> {
4381        // SAFETY: as above; `&mut self` guarantees exclusivity.
4382        unsafe {
4383            crate::support::RefMut::new(AnimationTrackM2CameraSpline {
4384                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Camera_get_positions(
4385                    self.raw.as_ptr(),
4386                )),
4387            })
4388        }
4389    }
4390
4391    pub fn position_base(&self) -> crate::math::Vector3f {
4392        // SAFETY: the getter returns an interior pointer to a
4393        // layout-identical POD; we copy it out immediately.
4394        unsafe {
4395            *(ffi::whiteout_m2_M2Camera_get_positionBase(self.raw.as_ptr())
4396                as *const crate::math::Vector3f)
4397        }
4398    }
4399
4400    pub fn set_position_base(&mut self, value: crate::math::Vector3f) {
4401        // SAFETY: as above, in the other direction.
4402        unsafe {
4403            ffi::whiteout_m2_M2Camera_set_positionBase(
4404                self.raw.as_ptr(),
4405                &value as *const crate::math::Vector3f as *const _,
4406            )
4407        }
4408    }
4409
4410    /// Borrows the field in place — no copy, no allocation.
4411    pub fn target_positions(&self) -> crate::support::Ref<'_, AnimationTrackM2CameraSpline> {
4412        // SAFETY: an interior pointer into `self`, valid for this
4413        // borrow and never freed by the `Ref`.
4414        unsafe {
4415            crate::support::Ref::new(AnimationTrackM2CameraSpline {
4416                raw: core::ptr::NonNull::new_unchecked(
4417                    ffi::whiteout_m2_M2Camera_get_targetPositions(self.raw.as_ptr()),
4418                ),
4419            })
4420        }
4421    }
4422
4423    pub fn target_positions_mut(
4424        &mut self,
4425    ) -> crate::support::RefMut<'_, AnimationTrackM2CameraSpline> {
4426        // SAFETY: as above; `&mut self` guarantees exclusivity.
4427        unsafe {
4428            crate::support::RefMut::new(AnimationTrackM2CameraSpline {
4429                raw: core::ptr::NonNull::new_unchecked(
4430                    ffi::whiteout_m2_M2Camera_get_targetPositions(self.raw.as_ptr()),
4431                ),
4432            })
4433        }
4434    }
4435
4436    pub fn target_position_base(&self) -> crate::math::Vector3f {
4437        // SAFETY: the getter returns an interior pointer to a
4438        // layout-identical POD; we copy it out immediately.
4439        unsafe {
4440            *(ffi::whiteout_m2_M2Camera_get_targetPositionBase(self.raw.as_ptr())
4441                as *const crate::math::Vector3f)
4442        }
4443    }
4444
4445    pub fn set_target_position_base(&mut self, value: crate::math::Vector3f) {
4446        // SAFETY: as above, in the other direction.
4447        unsafe {
4448            ffi::whiteout_m2_M2Camera_set_targetPositionBase(
4449                self.raw.as_ptr(),
4450                &value as *const crate::math::Vector3f as *const _,
4451            )
4452        }
4453    }
4454
4455    /// Borrows the field in place — no copy, no allocation.
4456    pub fn roll(&self) -> crate::support::Ref<'_, AnimationTrackF32> {
4457        // SAFETY: an interior pointer into `self`, valid for this
4458        // borrow and never freed by the `Ref`.
4459        unsafe {
4460            crate::support::Ref::new(AnimationTrackF32 {
4461                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Camera_get_roll(
4462                    self.raw.as_ptr(),
4463                )),
4464            })
4465        }
4466    }
4467
4468    pub fn roll_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackF32> {
4469        // SAFETY: as above; `&mut self` guarantees exclusivity.
4470        unsafe {
4471            crate::support::RefMut::new(AnimationTrackF32 {
4472                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Camera_get_roll(
4473                    self.raw.as_ptr(),
4474                )),
4475            })
4476        }
4477    }
4478
4479    /// Borrows the field in place — no copy, no allocation.
4480    pub fn field_of_view_track(&self) -> crate::support::Ref<'_, AnimationTrackF32> {
4481        // SAFETY: an interior pointer into `self`, valid for this
4482        // borrow and never freed by the `Ref`.
4483        unsafe {
4484            crate::support::Ref::new(AnimationTrackF32 {
4485                raw: core::ptr::NonNull::new_unchecked(
4486                    ffi::whiteout_m2_M2Camera_get_fieldOfViewTrack(self.raw.as_ptr()),
4487                ),
4488            })
4489        }
4490    }
4491
4492    pub fn field_of_view_track_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackF32> {
4493        // SAFETY: as above; `&mut self` guarantees exclusivity.
4494        unsafe {
4495            crate::support::RefMut::new(AnimationTrackF32 {
4496                raw: core::ptr::NonNull::new_unchecked(
4497                    ffi::whiteout_m2_M2Camera_get_fieldOfViewTrack(self.raw.as_ptr()),
4498                ),
4499            })
4500        }
4501    }
4502}
4503
4504impl Default for Camera {
4505    fn default() -> Self {
4506        Self::new()
4507    }
4508}
4509
4510pub struct Attachment {
4511    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2Attachment>,
4512}
4513
4514impl Drop for Attachment {
4515    fn drop(&mut self) {
4516        // SAFETY: `raw` came from a native constructor and Drop runs once.
4517        unsafe { ffi::whiteout_m2_M2Attachment_delete(self.raw.as_ptr()) }
4518    }
4519}
4520
4521impl Attachment {
4522    /// # Safety
4523    /// `raw` must be a live handle this value takes ownership of.
4524    #[allow(dead_code)] // used by whichever methods return this type
4525    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2Attachment) -> Option<Self> {
4526        core::ptr::NonNull::new(raw).map(|raw| Attachment { raw })
4527    }
4528}
4529
4530// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
4531// is deliberately NOT implemented — the C++ types make no documented
4532// guarantee about concurrent use, and claiming one we haven't verified
4533// would be unsound. See `@bind thread_safe` in the plan.
4534unsafe impl Send for Attachment {}
4535
4536impl core::fmt::Debug for Attachment {
4537    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
4538        f.debug_struct("Attachment").finish_non_exhaustive()
4539    }
4540}
4541
4542impl Attachment {
4543    /// # Panics
4544    /// Panics if the native allocation fails.
4545    pub fn new() -> Self {
4546        // SAFETY: the native constructor returns a live handle; a null here
4547        // means the library is unusable.
4548        unsafe {
4549            let raw = ffi::whiteout_m2_M2Attachment_new();
4550            Self::from_raw(raw).expect("native Attachment allocation failed")
4551        }
4552    }
4553
4554    pub fn id(&self) -> u32 {
4555        // SAFETY: plain scalar read through a live handle.
4556        unsafe { ffi::whiteout_m2_M2Attachment_get_id(self.raw.as_ptr()) }
4557    }
4558
4559    pub fn set_id(&mut self, value: u32) {
4560        // SAFETY: plain scalar write through a live handle.
4561        unsafe { ffi::whiteout_m2_M2Attachment_set_id(self.raw.as_ptr(), value) }
4562    }
4563
4564    pub fn bone_id(&self) -> u16 {
4565        // SAFETY: plain scalar read through a live handle.
4566        unsafe { ffi::whiteout_m2_M2Attachment_get_boneId(self.raw.as_ptr()) }
4567    }
4568
4569    pub fn set_bone_id(&mut self, value: u16) {
4570        // SAFETY: plain scalar write through a live handle.
4571        unsafe { ffi::whiteout_m2_M2Attachment_set_boneId(self.raw.as_ptr(), value) }
4572    }
4573
4574    pub fn unknown(&self) -> u16 {
4575        // SAFETY: plain scalar read through a live handle.
4576        unsafe { ffi::whiteout_m2_M2Attachment_get_unknown(self.raw.as_ptr()) }
4577    }
4578
4579    pub fn set_unknown(&mut self, value: u16) {
4580        // SAFETY: plain scalar write through a live handle.
4581        unsafe { ffi::whiteout_m2_M2Attachment_set_unknown(self.raw.as_ptr(), value) }
4582    }
4583
4584    pub fn position(&self) -> crate::math::Vector3f {
4585        // SAFETY: the getter returns an interior pointer to a
4586        // layout-identical POD; we copy it out immediately.
4587        unsafe {
4588            *(ffi::whiteout_m2_M2Attachment_get_position(self.raw.as_ptr())
4589                as *const crate::math::Vector3f)
4590        }
4591    }
4592
4593    pub fn set_position(&mut self, value: crate::math::Vector3f) {
4594        // SAFETY: as above, in the other direction.
4595        unsafe {
4596            ffi::whiteout_m2_M2Attachment_set_position(
4597                self.raw.as_ptr(),
4598                &value as *const crate::math::Vector3f as *const _,
4599            )
4600        }
4601    }
4602
4603    /// Borrows the field in place — no copy, no allocation.
4604    pub fn animate(&self) -> crate::support::Ref<'_, AnimationTrackU8> {
4605        // SAFETY: an interior pointer into `self`, valid for this
4606        // borrow and never freed by the `Ref`.
4607        unsafe {
4608            crate::support::Ref::new(AnimationTrackU8 {
4609                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Attachment_get_animate(
4610                    self.raw.as_ptr(),
4611                )),
4612            })
4613        }
4614    }
4615
4616    pub fn animate_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackU8> {
4617        // SAFETY: as above; `&mut self` guarantees exclusivity.
4618        unsafe {
4619            crate::support::RefMut::new(AnimationTrackU8 {
4620                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Attachment_get_animate(
4621                    self.raw.as_ptr(),
4622                )),
4623            })
4624        }
4625    }
4626}
4627
4628impl Default for Attachment {
4629    fn default() -> Self {
4630        Self::new()
4631    }
4632}
4633
4634pub struct RibbonEmitter {
4635    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2RibbonEmitter>,
4636}
4637
4638impl Drop for RibbonEmitter {
4639    fn drop(&mut self) {
4640        // SAFETY: `raw` came from a native constructor and Drop runs once.
4641        unsafe { ffi::whiteout_m2_M2RibbonEmitter_delete(self.raw.as_ptr()) }
4642    }
4643}
4644
4645impl RibbonEmitter {
4646    /// # Safety
4647    /// `raw` must be a live handle this value takes ownership of.
4648    #[allow(dead_code)] // used by whichever methods return this type
4649    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2RibbonEmitter) -> Option<Self> {
4650        core::ptr::NonNull::new(raw).map(|raw| RibbonEmitter { raw })
4651    }
4652}
4653
4654// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
4655// is deliberately NOT implemented — the C++ types make no documented
4656// guarantee about concurrent use, and claiming one we haven't verified
4657// would be unsound. See `@bind thread_safe` in the plan.
4658unsafe impl Send for RibbonEmitter {}
4659
4660impl core::fmt::Debug for RibbonEmitter {
4661    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
4662        f.debug_struct("RibbonEmitter").finish_non_exhaustive()
4663    }
4664}
4665
4666impl RibbonEmitter {
4667    /// # Panics
4668    /// Panics if the native allocation fails.
4669    pub fn new() -> Self {
4670        // SAFETY: the native constructor returns a live handle; a null here
4671        // means the library is unusable.
4672        unsafe {
4673            let raw = ffi::whiteout_m2_M2RibbonEmitter_new();
4674            Self::from_raw(raw).expect("native RibbonEmitter allocation failed")
4675        }
4676    }
4677
4678    pub fn ribbon_id(&self) -> u32 {
4679        // SAFETY: plain scalar read through a live handle.
4680        unsafe { ffi::whiteout_m2_M2RibbonEmitter_get_ribbonId(self.raw.as_ptr()) }
4681    }
4682
4683    pub fn set_ribbon_id(&mut self, value: u32) {
4684        // SAFETY: plain scalar write through a live handle.
4685        unsafe { ffi::whiteout_m2_M2RibbonEmitter_set_ribbonId(self.raw.as_ptr(), value) }
4686    }
4687
4688    pub fn bone_id(&self) -> u32 {
4689        // SAFETY: plain scalar read through a live handle.
4690        unsafe { ffi::whiteout_m2_M2RibbonEmitter_get_boneId(self.raw.as_ptr()) }
4691    }
4692
4693    pub fn set_bone_id(&mut self, value: u32) {
4694        // SAFETY: plain scalar write through a live handle.
4695        unsafe { ffi::whiteout_m2_M2RibbonEmitter_set_boneId(self.raw.as_ptr(), value) }
4696    }
4697
4698    pub fn position(&self) -> crate::math::Vector3f {
4699        // SAFETY: the getter returns an interior pointer to a
4700        // layout-identical POD; we copy it out immediately.
4701        unsafe {
4702            *(ffi::whiteout_m2_M2RibbonEmitter_get_position(self.raw.as_ptr())
4703                as *const crate::math::Vector3f)
4704        }
4705    }
4706
4707    pub fn set_position(&mut self, value: crate::math::Vector3f) {
4708        // SAFETY: as above, in the other direction.
4709        unsafe {
4710            ffi::whiteout_m2_M2RibbonEmitter_set_position(
4711                self.raw.as_ptr(),
4712                &value as *const crate::math::Vector3f as *const _,
4713            )
4714        }
4715    }
4716
4717    /// Zero-copy view of the underlying `std::vector`.
4718    pub fn texture_indices(&self) -> &[u16] {
4719        // SAFETY: `_data`/`_count` describe one contiguous C++
4720        // allocation, borrowed for as long as `self` is.
4721        unsafe {
4722            let n = ffi::whiteout_m2_M2RibbonEmitter_get_textureIndices_count(self.raw.as_ptr());
4723            let p = ffi::whiteout_m2_M2RibbonEmitter_get_textureIndices_data(self.raw.as_ptr());
4724            if p.is_null() || n == 0 {
4725                &[]
4726            } else {
4727                core::slice::from_raw_parts(p, n)
4728            }
4729        }
4730    }
4731
4732    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
4733    pub fn texture_indices_mut(&mut self) -> &mut [u16] {
4734        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
4735        unsafe {
4736            let n = ffi::whiteout_m2_M2RibbonEmitter_get_textureIndices_count(self.raw.as_ptr());
4737            let p = ffi::whiteout_m2_M2RibbonEmitter_get_textureIndices_data(self.raw.as_ptr())
4738                as *mut u16;
4739            if p.is_null() || n == 0 {
4740                &mut []
4741            } else {
4742                core::slice::from_raw_parts_mut(p, n)
4743            }
4744        }
4745    }
4746
4747    pub fn set_texture_indices(&mut self, values: &[u16]) {
4748        // SAFETY: the native side copies `values` before returning.
4749        unsafe {
4750            ffi::whiteout_m2_M2RibbonEmitter_assign_textureIndices(
4751                self.raw.as_ptr(),
4752                values.as_ptr() as *const _,
4753                values.len(),
4754            )
4755        }
4756    }
4757
4758    pub fn resize_texture_indices(&mut self, count: usize) {
4759        // SAFETY: reallocation is safe here precisely because
4760        // `&mut self` means no slice borrow is outstanding.
4761        unsafe { ffi::whiteout_m2_M2RibbonEmitter_resize_textureIndices(self.raw.as_ptr(), count) }
4762    }
4763
4764    /// Zero-copy view of the underlying `std::vector`.
4765    pub fn material_indices(&self) -> &[u16] {
4766        // SAFETY: `_data`/`_count` describe one contiguous C++
4767        // allocation, borrowed for as long as `self` is.
4768        unsafe {
4769            let n = ffi::whiteout_m2_M2RibbonEmitter_get_materialIndices_count(self.raw.as_ptr());
4770            let p = ffi::whiteout_m2_M2RibbonEmitter_get_materialIndices_data(self.raw.as_ptr());
4771            if p.is_null() || n == 0 {
4772                &[]
4773            } else {
4774                core::slice::from_raw_parts(p, n)
4775            }
4776        }
4777    }
4778
4779    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
4780    pub fn material_indices_mut(&mut self) -> &mut [u16] {
4781        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
4782        unsafe {
4783            let n = ffi::whiteout_m2_M2RibbonEmitter_get_materialIndices_count(self.raw.as_ptr());
4784            let p = ffi::whiteout_m2_M2RibbonEmitter_get_materialIndices_data(self.raw.as_ptr())
4785                as *mut u16;
4786            if p.is_null() || n == 0 {
4787                &mut []
4788            } else {
4789                core::slice::from_raw_parts_mut(p, n)
4790            }
4791        }
4792    }
4793
4794    pub fn set_material_indices(&mut self, values: &[u16]) {
4795        // SAFETY: the native side copies `values` before returning.
4796        unsafe {
4797            ffi::whiteout_m2_M2RibbonEmitter_assign_materialIndices(
4798                self.raw.as_ptr(),
4799                values.as_ptr() as *const _,
4800                values.len(),
4801            )
4802        }
4803    }
4804
4805    pub fn resize_material_indices(&mut self, count: usize) {
4806        // SAFETY: reallocation is safe here precisely because
4807        // `&mut self` means no slice borrow is outstanding.
4808        unsafe { ffi::whiteout_m2_M2RibbonEmitter_resize_materialIndices(self.raw.as_ptr(), count) }
4809    }
4810
4811    /// Borrows the field in place — no copy, no allocation.
4812    pub fn color_track(&self) -> crate::support::Ref<'_, AnimationTrackVector3f> {
4813        // SAFETY: an interior pointer into `self`, valid for this
4814        // borrow and never freed by the `Ref`.
4815        unsafe {
4816            crate::support::Ref::new(AnimationTrackVector3f {
4817                raw: core::ptr::NonNull::new_unchecked(
4818                    ffi::whiteout_m2_M2RibbonEmitter_get_colorTrack(self.raw.as_ptr()),
4819                ),
4820            })
4821        }
4822    }
4823
4824    pub fn color_track_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackVector3f> {
4825        // SAFETY: as above; `&mut self` guarantees exclusivity.
4826        unsafe {
4827            crate::support::RefMut::new(AnimationTrackVector3f {
4828                raw: core::ptr::NonNull::new_unchecked(
4829                    ffi::whiteout_m2_M2RibbonEmitter_get_colorTrack(self.raw.as_ptr()),
4830                ),
4831            })
4832        }
4833    }
4834
4835    /// Borrows the field in place — no copy, no allocation.
4836    pub fn alpha_track(&self) -> crate::support::Ref<'_, AnimationTrackI16> {
4837        // SAFETY: an interior pointer into `self`, valid for this
4838        // borrow and never freed by the `Ref`.
4839        unsafe {
4840            crate::support::Ref::new(AnimationTrackI16 {
4841                raw: core::ptr::NonNull::new_unchecked(
4842                    ffi::whiteout_m2_M2RibbonEmitter_get_alphaTrack(self.raw.as_ptr()),
4843                ),
4844            })
4845        }
4846    }
4847
4848    pub fn alpha_track_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackI16> {
4849        // SAFETY: as above; `&mut self` guarantees exclusivity.
4850        unsafe {
4851            crate::support::RefMut::new(AnimationTrackI16 {
4852                raw: core::ptr::NonNull::new_unchecked(
4853                    ffi::whiteout_m2_M2RibbonEmitter_get_alphaTrack(self.raw.as_ptr()),
4854                ),
4855            })
4856        }
4857    }
4858
4859    /// Borrows the field in place — no copy, no allocation.
4860    pub fn height_above(&self) -> crate::support::Ref<'_, AnimationTrackF32> {
4861        // SAFETY: an interior pointer into `self`, valid for this
4862        // borrow and never freed by the `Ref`.
4863        unsafe {
4864            crate::support::Ref::new(AnimationTrackF32 {
4865                raw: core::ptr::NonNull::new_unchecked(
4866                    ffi::whiteout_m2_M2RibbonEmitter_get_heightAbove(self.raw.as_ptr()),
4867                ),
4868            })
4869        }
4870    }
4871
4872    pub fn height_above_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackF32> {
4873        // SAFETY: as above; `&mut self` guarantees exclusivity.
4874        unsafe {
4875            crate::support::RefMut::new(AnimationTrackF32 {
4876                raw: core::ptr::NonNull::new_unchecked(
4877                    ffi::whiteout_m2_M2RibbonEmitter_get_heightAbove(self.raw.as_ptr()),
4878                ),
4879            })
4880        }
4881    }
4882
4883    /// Borrows the field in place — no copy, no allocation.
4884    pub fn height_below(&self) -> crate::support::Ref<'_, AnimationTrackF32> {
4885        // SAFETY: an interior pointer into `self`, valid for this
4886        // borrow and never freed by the `Ref`.
4887        unsafe {
4888            crate::support::Ref::new(AnimationTrackF32 {
4889                raw: core::ptr::NonNull::new_unchecked(
4890                    ffi::whiteout_m2_M2RibbonEmitter_get_heightBelow(self.raw.as_ptr()),
4891                ),
4892            })
4893        }
4894    }
4895
4896    pub fn height_below_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackF32> {
4897        // SAFETY: as above; `&mut self` guarantees exclusivity.
4898        unsafe {
4899            crate::support::RefMut::new(AnimationTrackF32 {
4900                raw: core::ptr::NonNull::new_unchecked(
4901                    ffi::whiteout_m2_M2RibbonEmitter_get_heightBelow(self.raw.as_ptr()),
4902                ),
4903            })
4904        }
4905    }
4906
4907    pub fn edges_per_second(&self) -> f32 {
4908        // SAFETY: plain scalar read through a live handle.
4909        unsafe { ffi::whiteout_m2_M2RibbonEmitter_get_edgesPerSecond(self.raw.as_ptr()) }
4910    }
4911
4912    pub fn set_edges_per_second(&mut self, value: f32) {
4913        // SAFETY: plain scalar write through a live handle.
4914        unsafe { ffi::whiteout_m2_M2RibbonEmitter_set_edgesPerSecond(self.raw.as_ptr(), value) }
4915    }
4916
4917    pub fn edge_lifetime(&self) -> f32 {
4918        // SAFETY: plain scalar read through a live handle.
4919        unsafe { ffi::whiteout_m2_M2RibbonEmitter_get_edgeLifetime(self.raw.as_ptr()) }
4920    }
4921
4922    pub fn set_edge_lifetime(&mut self, value: f32) {
4923        // SAFETY: plain scalar write through a live handle.
4924        unsafe { ffi::whiteout_m2_M2RibbonEmitter_set_edgeLifetime(self.raw.as_ptr(), value) }
4925    }
4926
4927    pub fn gravity(&self) -> f32 {
4928        // SAFETY: plain scalar read through a live handle.
4929        unsafe { ffi::whiteout_m2_M2RibbonEmitter_get_gravity(self.raw.as_ptr()) }
4930    }
4931
4932    pub fn set_gravity(&mut self, value: f32) {
4933        // SAFETY: plain scalar write through a live handle.
4934        unsafe { ffi::whiteout_m2_M2RibbonEmitter_set_gravity(self.raw.as_ptr(), value) }
4935    }
4936
4937    pub fn texture_rows(&self) -> u16 {
4938        // SAFETY: plain scalar read through a live handle.
4939        unsafe { ffi::whiteout_m2_M2RibbonEmitter_get_textureRows(self.raw.as_ptr()) }
4940    }
4941
4942    pub fn set_texture_rows(&mut self, value: u16) {
4943        // SAFETY: plain scalar write through a live handle.
4944        unsafe { ffi::whiteout_m2_M2RibbonEmitter_set_textureRows(self.raw.as_ptr(), value) }
4945    }
4946
4947    pub fn texture_cols(&self) -> u16 {
4948        // SAFETY: plain scalar read through a live handle.
4949        unsafe { ffi::whiteout_m2_M2RibbonEmitter_get_textureCols(self.raw.as_ptr()) }
4950    }
4951
4952    pub fn set_texture_cols(&mut self, value: u16) {
4953        // SAFETY: plain scalar write through a live handle.
4954        unsafe { ffi::whiteout_m2_M2RibbonEmitter_set_textureCols(self.raw.as_ptr(), value) }
4955    }
4956
4957    /// Borrows the field in place — no copy, no allocation.
4958    pub fn tex_slot(&self) -> crate::support::Ref<'_, AnimationTrackU16> {
4959        // SAFETY: an interior pointer into `self`, valid for this
4960        // borrow and never freed by the `Ref`.
4961        unsafe {
4962            crate::support::Ref::new(AnimationTrackU16 {
4963                raw: core::ptr::NonNull::new_unchecked(
4964                    ffi::whiteout_m2_M2RibbonEmitter_get_texSlot(self.raw.as_ptr()),
4965                ),
4966            })
4967        }
4968    }
4969
4970    pub fn tex_slot_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackU16> {
4971        // SAFETY: as above; `&mut self` guarantees exclusivity.
4972        unsafe {
4973            crate::support::RefMut::new(AnimationTrackU16 {
4974                raw: core::ptr::NonNull::new_unchecked(
4975                    ffi::whiteout_m2_M2RibbonEmitter_get_texSlot(self.raw.as_ptr()),
4976                ),
4977            })
4978        }
4979    }
4980
4981    /// Borrows the field in place — no copy, no allocation.
4982    pub fn visibility(&self) -> crate::support::Ref<'_, AnimationTrackU8> {
4983        // SAFETY: an interior pointer into `self`, valid for this
4984        // borrow and never freed by the `Ref`.
4985        unsafe {
4986            crate::support::Ref::new(AnimationTrackU8 {
4987                raw: core::ptr::NonNull::new_unchecked(
4988                    ffi::whiteout_m2_M2RibbonEmitter_get_visibility(self.raw.as_ptr()),
4989                ),
4990            })
4991        }
4992    }
4993
4994    pub fn visibility_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackU8> {
4995        // SAFETY: as above; `&mut self` guarantees exclusivity.
4996        unsafe {
4997            crate::support::RefMut::new(AnimationTrackU8 {
4998                raw: core::ptr::NonNull::new_unchecked(
4999                    ffi::whiteout_m2_M2RibbonEmitter_get_visibility(self.raw.as_ptr()),
5000                ),
5001            })
5002        }
5003    }
5004
5005    pub fn priority_plane(&self) -> i16 {
5006        // SAFETY: plain scalar read through a live handle.
5007        unsafe { ffi::whiteout_m2_M2RibbonEmitter_get_priorityPlane(self.raw.as_ptr()) }
5008    }
5009
5010    pub fn set_priority_plane(&mut self, value: i16) {
5011        // SAFETY: plain scalar write through a live handle.
5012        unsafe { ffi::whiteout_m2_M2RibbonEmitter_set_priorityPlane(self.raw.as_ptr(), value) }
5013    }
5014
5015    pub fn ribbon_color_index(&self) -> i8 {
5016        // SAFETY: plain scalar read through a live handle.
5017        unsafe { ffi::whiteout_m2_M2RibbonEmitter_get_ribbonColorIndex(self.raw.as_ptr()) }
5018    }
5019
5020    pub fn set_ribbon_color_index(&mut self, value: i8) {
5021        // SAFETY: plain scalar write through a live handle.
5022        unsafe { ffi::whiteout_m2_M2RibbonEmitter_set_ribbonColorIndex(self.raw.as_ptr(), value) }
5023    }
5024
5025    pub fn texture_transform_index(&self) -> i8 {
5026        // SAFETY: plain scalar read through a live handle.
5027        unsafe { ffi::whiteout_m2_M2RibbonEmitter_get_textureTransformIndex(self.raw.as_ptr()) }
5028    }
5029
5030    pub fn set_texture_transform_index(&mut self, value: i8) {
5031        // SAFETY: plain scalar write through a live handle.
5032        unsafe {
5033            ffi::whiteout_m2_M2RibbonEmitter_set_textureTransformIndex(self.raw.as_ptr(), value)
5034        }
5035    }
5036}
5037
5038impl Default for RibbonEmitter {
5039    fn default() -> Self {
5040        Self::new()
5041    }
5042}
5043
5044pub struct Box {
5045    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2Box>,
5046}
5047
5048impl Drop for Box {
5049    fn drop(&mut self) {
5050        // SAFETY: `raw` came from a native constructor and Drop runs once.
5051        unsafe { ffi::whiteout_m2_M2Box_delete(self.raw.as_ptr()) }
5052    }
5053}
5054
5055impl Box {
5056    /// # Safety
5057    /// `raw` must be a live handle this value takes ownership of.
5058    #[allow(dead_code)] // used by whichever methods return this type
5059    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2Box) -> Option<Self> {
5060        core::ptr::NonNull::new(raw).map(|raw| Box { raw })
5061    }
5062}
5063
5064// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
5065// is deliberately NOT implemented — the C++ types make no documented
5066// guarantee about concurrent use, and claiming one we haven't verified
5067// would be unsound. See `@bind thread_safe` in the plan.
5068unsafe impl Send for Box {}
5069
5070impl core::fmt::Debug for Box {
5071    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
5072        f.debug_struct("Box").finish_non_exhaustive()
5073    }
5074}
5075
5076impl Box {
5077    /// # Panics
5078    /// Panics if the native allocation fails.
5079    pub fn new() -> Self {
5080        // SAFETY: the native constructor returns a live handle; a null here
5081        // means the library is unusable.
5082        unsafe {
5083            let raw = ffi::whiteout_m2_M2Box_new();
5084            Self::from_raw(raw).expect("native Box allocation failed")
5085        }
5086    }
5087
5088    pub fn minimum(&self) -> crate::math::Vector3f {
5089        // SAFETY: the getter returns an interior pointer to a
5090        // layout-identical POD; we copy it out immediately.
5091        unsafe {
5092            *(ffi::whiteout_m2_M2Box_get_minimum(self.raw.as_ptr()) as *const crate::math::Vector3f)
5093        }
5094    }
5095
5096    pub fn set_minimum(&mut self, value: crate::math::Vector3f) {
5097        // SAFETY: as above, in the other direction.
5098        unsafe {
5099            ffi::whiteout_m2_M2Box_set_minimum(
5100                self.raw.as_ptr(),
5101                &value as *const crate::math::Vector3f as *const _,
5102            )
5103        }
5104    }
5105
5106    pub fn maximum(&self) -> crate::math::Vector3f {
5107        // SAFETY: the getter returns an interior pointer to a
5108        // layout-identical POD; we copy it out immediately.
5109        unsafe {
5110            *(ffi::whiteout_m2_M2Box_get_maximum(self.raw.as_ptr()) as *const crate::math::Vector3f)
5111        }
5112    }
5113
5114    pub fn set_maximum(&mut self, value: crate::math::Vector3f) {
5115        // SAFETY: as above, in the other direction.
5116        unsafe {
5117            ffi::whiteout_m2_M2Box_set_maximum(
5118                self.raw.as_ptr(),
5119                &value as *const crate::math::Vector3f as *const _,
5120            )
5121        }
5122    }
5123}
5124
5125impl Default for Box {
5126    fn default() -> Self {
5127        Self::new()
5128    }
5129}
5130
5131pub struct ParticleEmitter {
5132    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2ParticleEmitter>,
5133}
5134
5135impl Drop for ParticleEmitter {
5136    fn drop(&mut self) {
5137        // SAFETY: `raw` came from a native constructor and Drop runs once.
5138        unsafe { ffi::whiteout_m2_M2ParticleEmitter_delete(self.raw.as_ptr()) }
5139    }
5140}
5141
5142impl ParticleEmitter {
5143    /// # Safety
5144    /// `raw` must be a live handle this value takes ownership of.
5145    #[allow(dead_code)] // used by whichever methods return this type
5146    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2ParticleEmitter) -> Option<Self> {
5147        core::ptr::NonNull::new(raw).map(|raw| ParticleEmitter { raw })
5148    }
5149}
5150
5151// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
5152// is deliberately NOT implemented — the C++ types make no documented
5153// guarantee about concurrent use, and claiming one we haven't verified
5154// would be unsound. See `@bind thread_safe` in the plan.
5155unsafe impl Send for ParticleEmitter {}
5156
5157impl core::fmt::Debug for ParticleEmitter {
5158    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
5159        f.debug_struct("ParticleEmitter").finish_non_exhaustive()
5160    }
5161}
5162
5163impl ParticleEmitter {
5164    /// # Panics
5165    /// Panics if the native allocation fails.
5166    pub fn new() -> Self {
5167        // SAFETY: the native constructor returns a live handle; a null here
5168        // means the library is unusable.
5169        unsafe {
5170            let raw = ffi::whiteout_m2_M2ParticleEmitter_new();
5171            Self::from_raw(raw).expect("native ParticleEmitter allocation failed")
5172        }
5173    }
5174
5175    pub fn particle_id(&self) -> u32 {
5176        // SAFETY: plain scalar read through a live handle.
5177        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_particleId(self.raw.as_ptr()) }
5178    }
5179
5180    pub fn set_particle_id(&mut self, value: u32) {
5181        // SAFETY: plain scalar write through a live handle.
5182        unsafe { ffi::whiteout_m2_M2ParticleEmitter_set_particleId(self.raw.as_ptr(), value) }
5183    }
5184
5185    pub fn flags(&self) -> ParticleFlag {
5186        // SAFETY: scalar read; a flag set accepts any bits.
5187        ParticleFlag(unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_flags(self.raw.as_ptr()) })
5188    }
5189
5190    pub fn set_flags(&mut self, value: ParticleFlag) {
5191        // SAFETY: scalar write through a live handle.
5192        unsafe { ffi::whiteout_m2_M2ParticleEmitter_set_flags(self.raw.as_ptr(), value.0) }
5193    }
5194
5195    pub fn position(&self) -> crate::math::Vector3f {
5196        // SAFETY: the getter returns an interior pointer to a
5197        // layout-identical POD; we copy it out immediately.
5198        unsafe {
5199            *(ffi::whiteout_m2_M2ParticleEmitter_get_position(self.raw.as_ptr())
5200                as *const crate::math::Vector3f)
5201        }
5202    }
5203
5204    pub fn set_position(&mut self, value: crate::math::Vector3f) {
5205        // SAFETY: as above, in the other direction.
5206        unsafe {
5207            ffi::whiteout_m2_M2ParticleEmitter_set_position(
5208                self.raw.as_ptr(),
5209                &value as *const crate::math::Vector3f as *const _,
5210            )
5211        }
5212    }
5213
5214    pub fn bone_id(&self) -> u16 {
5215        // SAFETY: plain scalar read through a live handle.
5216        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_boneId(self.raw.as_ptr()) }
5217    }
5218
5219    pub fn set_bone_id(&mut self, value: u16) {
5220        // SAFETY: plain scalar write through a live handle.
5221        unsafe { ffi::whiteout_m2_M2ParticleEmitter_set_boneId(self.raw.as_ptr(), value) }
5222    }
5223
5224    pub fn particle_model_filename(&self) -> String {
5225        // SAFETY: the native side hands over an owned CString.
5226        unsafe {
5227            crate::support::take_string(
5228                ffi::whiteout_m2_M2ParticleEmitter_get_particleModelFilename(self.raw.as_ptr()),
5229            )
5230        }
5231    }
5232
5233    pub fn set_particle_model_filename(&mut self, value: &str) {
5234        let value = std::ffi::CString::new(value).unwrap_or_default();
5235        // SAFETY: the pointer outlives the call.
5236        unsafe {
5237            ffi::whiteout_m2_M2ParticleEmitter_set_particleModelFilename(
5238                self.raw.as_ptr(),
5239                value.as_ptr(),
5240            )
5241        }
5242    }
5243
5244    pub fn child_emitters_model_filename(&self) -> String {
5245        // SAFETY: the native side hands over an owned CString.
5246        unsafe {
5247            crate::support::take_string(
5248                ffi::whiteout_m2_M2ParticleEmitter_get_childEmittersModelFilename(
5249                    self.raw.as_ptr(),
5250                ),
5251            )
5252        }
5253    }
5254
5255    pub fn set_child_emitters_model_filename(&mut self, value: &str) {
5256        let value = std::ffi::CString::new(value).unwrap_or_default();
5257        // SAFETY: the pointer outlives the call.
5258        unsafe {
5259            ffi::whiteout_m2_M2ParticleEmitter_set_childEmittersModelFilename(
5260                self.raw.as_ptr(),
5261                value.as_ptr(),
5262            )
5263        }
5264    }
5265
5266    pub fn blending_type(&self) -> ParticleBlending {
5267        // SAFETY: scalar read; the discriminant is validated below.
5268        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_blendingType(self.raw.as_ptr()) }
5269            .try_into()
5270            .expect("unknown enum discriminant from the native library")
5271    }
5272
5273    pub fn set_blending_type(&mut self, value: ParticleBlending) {
5274        // SAFETY: scalar write through a live handle.
5275        unsafe {
5276            ffi::whiteout_m2_M2ParticleEmitter_set_blendingType(self.raw.as_ptr(), value as i32)
5277        }
5278    }
5279
5280    pub fn emitter_type(&self) -> ParticleEmitterType {
5281        // SAFETY: scalar read; the discriminant is validated below.
5282        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_emitterType(self.raw.as_ptr()) }
5283            .try_into()
5284            .expect("unknown enum discriminant from the native library")
5285    }
5286
5287    pub fn set_emitter_type(&mut self, value: ParticleEmitterType) {
5288        // SAFETY: scalar write through a live handle.
5289        unsafe {
5290            ffi::whiteout_m2_M2ParticleEmitter_set_emitterType(self.raw.as_ptr(), value as i32)
5291        }
5292    }
5293
5294    pub fn particle_color_index(&self) -> u16 {
5295        // SAFETY: plain scalar read through a live handle.
5296        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_particleColorIndex(self.raw.as_ptr()) }
5297    }
5298
5299    pub fn set_particle_color_index(&mut self, value: u16) {
5300        // SAFETY: plain scalar write through a live handle.
5301        unsafe {
5302            ffi::whiteout_m2_M2ParticleEmitter_set_particleColorIndex(self.raw.as_ptr(), value)
5303        }
5304    }
5305
5306    pub fn texture_tilerotation(&self) -> i16 {
5307        // SAFETY: plain scalar read through a live handle.
5308        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_textureTilerotation(self.raw.as_ptr()) }
5309    }
5310
5311    pub fn set_texture_tilerotation(&mut self, value: i16) {
5312        // SAFETY: plain scalar write through a live handle.
5313        unsafe {
5314            ffi::whiteout_m2_M2ParticleEmitter_set_textureTilerotation(self.raw.as_ptr(), value)
5315        }
5316    }
5317
5318    pub fn rows(&self) -> u16 {
5319        // SAFETY: plain scalar read through a live handle.
5320        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_rows(self.raw.as_ptr()) }
5321    }
5322
5323    pub fn set_rows(&mut self, value: u16) {
5324        // SAFETY: plain scalar write through a live handle.
5325        unsafe { ffi::whiteout_m2_M2ParticleEmitter_set_rows(self.raw.as_ptr(), value) }
5326    }
5327
5328    pub fn columns(&self) -> u16 {
5329        // SAFETY: plain scalar read through a live handle.
5330        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_columns(self.raw.as_ptr()) }
5331    }
5332
5333    pub fn set_columns(&mut self, value: u16) {
5334        // SAFETY: plain scalar write through a live handle.
5335        unsafe { ffi::whiteout_m2_M2ParticleEmitter_set_columns(self.raw.as_ptr(), value) }
5336    }
5337
5338    /// Borrows the field in place — no copy, no allocation.
5339    pub fn emission_speed(&self) -> crate::support::Ref<'_, AnimationTrackF32> {
5340        // SAFETY: an interior pointer into `self`, valid for this
5341        // borrow and never freed by the `Ref`.
5342        unsafe {
5343            crate::support::Ref::new(AnimationTrackF32 {
5344                raw: core::ptr::NonNull::new_unchecked(
5345                    ffi::whiteout_m2_M2ParticleEmitter_get_emissionSpeed(self.raw.as_ptr()),
5346                ),
5347            })
5348        }
5349    }
5350
5351    pub fn emission_speed_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackF32> {
5352        // SAFETY: as above; `&mut self` guarantees exclusivity.
5353        unsafe {
5354            crate::support::RefMut::new(AnimationTrackF32 {
5355                raw: core::ptr::NonNull::new_unchecked(
5356                    ffi::whiteout_m2_M2ParticleEmitter_get_emissionSpeed(self.raw.as_ptr()),
5357                ),
5358            })
5359        }
5360    }
5361
5362    /// Borrows the field in place — no copy, no allocation.
5363    pub fn speed_variation(&self) -> crate::support::Ref<'_, AnimationTrackF32> {
5364        // SAFETY: an interior pointer into `self`, valid for this
5365        // borrow and never freed by the `Ref`.
5366        unsafe {
5367            crate::support::Ref::new(AnimationTrackF32 {
5368                raw: core::ptr::NonNull::new_unchecked(
5369                    ffi::whiteout_m2_M2ParticleEmitter_get_speedVariation(self.raw.as_ptr()),
5370                ),
5371            })
5372        }
5373    }
5374
5375    pub fn speed_variation_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackF32> {
5376        // SAFETY: as above; `&mut self` guarantees exclusivity.
5377        unsafe {
5378            crate::support::RefMut::new(AnimationTrackF32 {
5379                raw: core::ptr::NonNull::new_unchecked(
5380                    ffi::whiteout_m2_M2ParticleEmitter_get_speedVariation(self.raw.as_ptr()),
5381                ),
5382            })
5383        }
5384    }
5385
5386    /// Borrows the field in place — no copy, no allocation.
5387    pub fn vertical_range(&self) -> crate::support::Ref<'_, AnimationTrackF32> {
5388        // SAFETY: an interior pointer into `self`, valid for this
5389        // borrow and never freed by the `Ref`.
5390        unsafe {
5391            crate::support::Ref::new(AnimationTrackF32 {
5392                raw: core::ptr::NonNull::new_unchecked(
5393                    ffi::whiteout_m2_M2ParticleEmitter_get_verticalRange(self.raw.as_ptr()),
5394                ),
5395            })
5396        }
5397    }
5398
5399    pub fn vertical_range_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackF32> {
5400        // SAFETY: as above; `&mut self` guarantees exclusivity.
5401        unsafe {
5402            crate::support::RefMut::new(AnimationTrackF32 {
5403                raw: core::ptr::NonNull::new_unchecked(
5404                    ffi::whiteout_m2_M2ParticleEmitter_get_verticalRange(self.raw.as_ptr()),
5405                ),
5406            })
5407        }
5408    }
5409
5410    /// Borrows the field in place — no copy, no allocation.
5411    pub fn horizontal_range(&self) -> crate::support::Ref<'_, AnimationTrackF32> {
5412        // SAFETY: an interior pointer into `self`, valid for this
5413        // borrow and never freed by the `Ref`.
5414        unsafe {
5415            crate::support::Ref::new(AnimationTrackF32 {
5416                raw: core::ptr::NonNull::new_unchecked(
5417                    ffi::whiteout_m2_M2ParticleEmitter_get_horizontalRange(self.raw.as_ptr()),
5418                ),
5419            })
5420        }
5421    }
5422
5423    pub fn horizontal_range_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackF32> {
5424        // SAFETY: as above; `&mut self` guarantees exclusivity.
5425        unsafe {
5426            crate::support::RefMut::new(AnimationTrackF32 {
5427                raw: core::ptr::NonNull::new_unchecked(
5428                    ffi::whiteout_m2_M2ParticleEmitter_get_horizontalRange(self.raw.as_ptr()),
5429                ),
5430            })
5431        }
5432    }
5433
5434    /// Borrows the field in place — no copy, no allocation.
5435    pub fn gravity(&self) -> crate::support::Ref<'_, AnimationTrackF32> {
5436        // SAFETY: an interior pointer into `self`, valid for this
5437        // borrow and never freed by the `Ref`.
5438        unsafe {
5439            crate::support::Ref::new(AnimationTrackF32 {
5440                raw: core::ptr::NonNull::new_unchecked(
5441                    ffi::whiteout_m2_M2ParticleEmitter_get_gravity(self.raw.as_ptr()),
5442                ),
5443            })
5444        }
5445    }
5446
5447    pub fn gravity_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackF32> {
5448        // SAFETY: as above; `&mut self` guarantees exclusivity.
5449        unsafe {
5450            crate::support::RefMut::new(AnimationTrackF32 {
5451                raw: core::ptr::NonNull::new_unchecked(
5452                    ffi::whiteout_m2_M2ParticleEmitter_get_gravity(self.raw.as_ptr()),
5453                ),
5454            })
5455        }
5456    }
5457
5458    /// Borrows the field in place — no copy, no allocation.
5459    pub fn lifespan(&self) -> crate::support::Ref<'_, AnimationTrackF32> {
5460        // SAFETY: an interior pointer into `self`, valid for this
5461        // borrow and never freed by the `Ref`.
5462        unsafe {
5463            crate::support::Ref::new(AnimationTrackF32 {
5464                raw: core::ptr::NonNull::new_unchecked(
5465                    ffi::whiteout_m2_M2ParticleEmitter_get_lifespan(self.raw.as_ptr()),
5466                ),
5467            })
5468        }
5469    }
5470
5471    pub fn lifespan_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackF32> {
5472        // SAFETY: as above; `&mut self` guarantees exclusivity.
5473        unsafe {
5474            crate::support::RefMut::new(AnimationTrackF32 {
5475                raw: core::ptr::NonNull::new_unchecked(
5476                    ffi::whiteout_m2_M2ParticleEmitter_get_lifespan(self.raw.as_ptr()),
5477                ),
5478            })
5479        }
5480    }
5481
5482    pub fn lifespan_variation(&self) -> f32 {
5483        // SAFETY: plain scalar read through a live handle.
5484        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_lifespanVariation(self.raw.as_ptr()) }
5485    }
5486
5487    pub fn set_lifespan_variation(&mut self, value: f32) {
5488        // SAFETY: plain scalar write through a live handle.
5489        unsafe {
5490            ffi::whiteout_m2_M2ParticleEmitter_set_lifespanVariation(self.raw.as_ptr(), value)
5491        }
5492    }
5493
5494    /// Borrows the field in place — no copy, no allocation.
5495    pub fn emission_rate(&self) -> crate::support::Ref<'_, AnimationTrackF32> {
5496        // SAFETY: an interior pointer into `self`, valid for this
5497        // borrow and never freed by the `Ref`.
5498        unsafe {
5499            crate::support::Ref::new(AnimationTrackF32 {
5500                raw: core::ptr::NonNull::new_unchecked(
5501                    ffi::whiteout_m2_M2ParticleEmitter_get_emissionRate(self.raw.as_ptr()),
5502                ),
5503            })
5504        }
5505    }
5506
5507    pub fn emission_rate_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackF32> {
5508        // SAFETY: as above; `&mut self` guarantees exclusivity.
5509        unsafe {
5510            crate::support::RefMut::new(AnimationTrackF32 {
5511                raw: core::ptr::NonNull::new_unchecked(
5512                    ffi::whiteout_m2_M2ParticleEmitter_get_emissionRate(self.raw.as_ptr()),
5513                ),
5514            })
5515        }
5516    }
5517
5518    pub fn emission_rate_variation(&self) -> f32 {
5519        // SAFETY: plain scalar read through a live handle.
5520        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_emissionRateVariation(self.raw.as_ptr()) }
5521    }
5522
5523    pub fn set_emission_rate_variation(&mut self, value: f32) {
5524        // SAFETY: plain scalar write through a live handle.
5525        unsafe {
5526            ffi::whiteout_m2_M2ParticleEmitter_set_emissionRateVariation(self.raw.as_ptr(), value)
5527        }
5528    }
5529
5530    /// Borrows the field in place — no copy, no allocation.
5531    pub fn emission_area_width(&self) -> crate::support::Ref<'_, AnimationTrackF32> {
5532        // SAFETY: an interior pointer into `self`, valid for this
5533        // borrow and never freed by the `Ref`.
5534        unsafe {
5535            crate::support::Ref::new(AnimationTrackF32 {
5536                raw: core::ptr::NonNull::new_unchecked(
5537                    ffi::whiteout_m2_M2ParticleEmitter_get_emissionAreaWidth(self.raw.as_ptr()),
5538                ),
5539            })
5540        }
5541    }
5542
5543    pub fn emission_area_width_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackF32> {
5544        // SAFETY: as above; `&mut self` guarantees exclusivity.
5545        unsafe {
5546            crate::support::RefMut::new(AnimationTrackF32 {
5547                raw: core::ptr::NonNull::new_unchecked(
5548                    ffi::whiteout_m2_M2ParticleEmitter_get_emissionAreaWidth(self.raw.as_ptr()),
5549                ),
5550            })
5551        }
5552    }
5553
5554    /// Borrows the field in place — no copy, no allocation.
5555    pub fn emission_area_length(&self) -> crate::support::Ref<'_, AnimationTrackF32> {
5556        // SAFETY: an interior pointer into `self`, valid for this
5557        // borrow and never freed by the `Ref`.
5558        unsafe {
5559            crate::support::Ref::new(AnimationTrackF32 {
5560                raw: core::ptr::NonNull::new_unchecked(
5561                    ffi::whiteout_m2_M2ParticleEmitter_get_emissionAreaLength(self.raw.as_ptr()),
5562                ),
5563            })
5564        }
5565    }
5566
5567    pub fn emission_area_length_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackF32> {
5568        // SAFETY: as above; `&mut self` guarantees exclusivity.
5569        unsafe {
5570            crate::support::RefMut::new(AnimationTrackF32 {
5571                raw: core::ptr::NonNull::new_unchecked(
5572                    ffi::whiteout_m2_M2ParticleEmitter_get_emissionAreaLength(self.raw.as_ptr()),
5573                ),
5574            })
5575        }
5576    }
5577
5578    /// Borrows the field in place — no copy, no allocation.
5579    pub fn z_source(&self) -> crate::support::Ref<'_, AnimationTrackF32> {
5580        // SAFETY: an interior pointer into `self`, valid for this
5581        // borrow and never freed by the `Ref`.
5582        unsafe {
5583            crate::support::Ref::new(AnimationTrackF32 {
5584                raw: core::ptr::NonNull::new_unchecked(
5585                    ffi::whiteout_m2_M2ParticleEmitter_get_zSource(self.raw.as_ptr()),
5586                ),
5587            })
5588        }
5589    }
5590
5591    pub fn z_source_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackF32> {
5592        // SAFETY: as above; `&mut self` guarantees exclusivity.
5593        unsafe {
5594            crate::support::RefMut::new(AnimationTrackF32 {
5595                raw: core::ptr::NonNull::new_unchecked(
5596                    ffi::whiteout_m2_M2ParticleEmitter_get_zSource(self.raw.as_ptr()),
5597                ),
5598            })
5599        }
5600    }
5601
5602    /// Borrows the field in place — no copy, no allocation.
5603    pub fn color_track(&self) -> crate::support::Ref<'_, ParticleAnimationTrackVector3f> {
5604        // SAFETY: an interior pointer into `self`, valid for this
5605        // borrow and never freed by the `Ref`.
5606        unsafe {
5607            crate::support::Ref::new(ParticleAnimationTrackVector3f {
5608                raw: core::ptr::NonNull::new_unchecked(
5609                    ffi::whiteout_m2_M2ParticleEmitter_get_colorTrack(self.raw.as_ptr()),
5610                ),
5611            })
5612        }
5613    }
5614
5615    pub fn color_track_mut(
5616        &mut self,
5617    ) -> crate::support::RefMut<'_, ParticleAnimationTrackVector3f> {
5618        // SAFETY: as above; `&mut self` guarantees exclusivity.
5619        unsafe {
5620            crate::support::RefMut::new(ParticleAnimationTrackVector3f {
5621                raw: core::ptr::NonNull::new_unchecked(
5622                    ffi::whiteout_m2_M2ParticleEmitter_get_colorTrack(self.raw.as_ptr()),
5623                ),
5624            })
5625        }
5626    }
5627
5628    /// Borrows the field in place — no copy, no allocation.
5629    pub fn scale_track(&self) -> crate::support::Ref<'_, ParticleAnimationTrackVector2f> {
5630        // SAFETY: an interior pointer into `self`, valid for this
5631        // borrow and never freed by the `Ref`.
5632        unsafe {
5633            crate::support::Ref::new(ParticleAnimationTrackVector2f {
5634                raw: core::ptr::NonNull::new_unchecked(
5635                    ffi::whiteout_m2_M2ParticleEmitter_get_scaleTrack(self.raw.as_ptr()),
5636                ),
5637            })
5638        }
5639    }
5640
5641    pub fn scale_track_mut(
5642        &mut self,
5643    ) -> crate::support::RefMut<'_, ParticleAnimationTrackVector2f> {
5644        // SAFETY: as above; `&mut self` guarantees exclusivity.
5645        unsafe {
5646            crate::support::RefMut::new(ParticleAnimationTrackVector2f {
5647                raw: core::ptr::NonNull::new_unchecked(
5648                    ffi::whiteout_m2_M2ParticleEmitter_get_scaleTrack(self.raw.as_ptr()),
5649                ),
5650            })
5651        }
5652    }
5653
5654    pub fn scale_vary(&self) -> crate::math::Vector2f {
5655        // SAFETY: the getter returns an interior pointer to a
5656        // layout-identical POD; we copy it out immediately.
5657        unsafe {
5658            *(ffi::whiteout_m2_M2ParticleEmitter_get_scaleVary(self.raw.as_ptr())
5659                as *const crate::math::Vector2f)
5660        }
5661    }
5662
5663    pub fn set_scale_vary(&mut self, value: crate::math::Vector2f) {
5664        // SAFETY: as above, in the other direction.
5665        unsafe {
5666            ffi::whiteout_m2_M2ParticleEmitter_set_scaleVary(
5667                self.raw.as_ptr(),
5668                &value as *const crate::math::Vector2f as *const _,
5669            )
5670        }
5671    }
5672
5673    pub fn tail_length(&self) -> f32 {
5674        // SAFETY: plain scalar read through a live handle.
5675        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_tailLength(self.raw.as_ptr()) }
5676    }
5677
5678    pub fn set_tail_length(&mut self, value: f32) {
5679        // SAFETY: plain scalar write through a live handle.
5680        unsafe { ffi::whiteout_m2_M2ParticleEmitter_set_tailLength(self.raw.as_ptr(), value) }
5681    }
5682
5683    pub fn twinkle_speed(&self) -> f32 {
5684        // SAFETY: plain scalar read through a live handle.
5685        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_twinkleSpeed(self.raw.as_ptr()) }
5686    }
5687
5688    pub fn set_twinkle_speed(&mut self, value: f32) {
5689        // SAFETY: plain scalar write through a live handle.
5690        unsafe { ffi::whiteout_m2_M2ParticleEmitter_set_twinkleSpeed(self.raw.as_ptr(), value) }
5691    }
5692
5693    pub fn twinkle_percent(&self) -> f32 {
5694        // SAFETY: plain scalar read through a live handle.
5695        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_twinklePercent(self.raw.as_ptr()) }
5696    }
5697
5698    pub fn set_twinkle_percent(&mut self, value: f32) {
5699        // SAFETY: plain scalar write through a live handle.
5700        unsafe { ffi::whiteout_m2_M2ParticleEmitter_set_twinklePercent(self.raw.as_ptr(), value) }
5701    }
5702
5703    pub fn twinkle_scale(&self) -> crate::math::Vector2f {
5704        // SAFETY: the getter returns an interior pointer to a
5705        // layout-identical POD; we copy it out immediately.
5706        unsafe {
5707            *(ffi::whiteout_m2_M2ParticleEmitter_get_twinkleScale(self.raw.as_ptr())
5708                as *const crate::math::Vector2f)
5709        }
5710    }
5711
5712    pub fn set_twinkle_scale(&mut self, value: crate::math::Vector2f) {
5713        // SAFETY: as above, in the other direction.
5714        unsafe {
5715            ffi::whiteout_m2_M2ParticleEmitter_set_twinkleScale(
5716                self.raw.as_ptr(),
5717                &value as *const crate::math::Vector2f as *const _,
5718            )
5719        }
5720    }
5721
5722    pub fn inherit_velocity_scale(&self) -> f32 {
5723        // SAFETY: plain scalar read through a live handle.
5724        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_inheritVelocityScale(self.raw.as_ptr()) }
5725    }
5726
5727    pub fn set_inherit_velocity_scale(&mut self, value: f32) {
5728        // SAFETY: plain scalar write through a live handle.
5729        unsafe {
5730            ffi::whiteout_m2_M2ParticleEmitter_set_inheritVelocityScale(self.raw.as_ptr(), value)
5731        }
5732    }
5733
5734    pub fn drag(&self) -> f32 {
5735        // SAFETY: plain scalar read through a live handle.
5736        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_drag(self.raw.as_ptr()) }
5737    }
5738
5739    pub fn set_drag(&mut self, value: f32) {
5740        // SAFETY: plain scalar write through a live handle.
5741        unsafe { ffi::whiteout_m2_M2ParticleEmitter_set_drag(self.raw.as_ptr(), value) }
5742    }
5743
5744    pub fn base_spin(&self) -> f32 {
5745        // SAFETY: plain scalar read through a live handle.
5746        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_baseSpin(self.raw.as_ptr()) }
5747    }
5748
5749    pub fn set_base_spin(&mut self, value: f32) {
5750        // SAFETY: plain scalar write through a live handle.
5751        unsafe { ffi::whiteout_m2_M2ParticleEmitter_set_baseSpin(self.raw.as_ptr(), value) }
5752    }
5753
5754    pub fn base_spin_variation(&self) -> f32 {
5755        // SAFETY: plain scalar read through a live handle.
5756        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_baseSpinVariation(self.raw.as_ptr()) }
5757    }
5758
5759    pub fn set_base_spin_variation(&mut self, value: f32) {
5760        // SAFETY: plain scalar write through a live handle.
5761        unsafe {
5762            ffi::whiteout_m2_M2ParticleEmitter_set_baseSpinVariation(self.raw.as_ptr(), value)
5763        }
5764    }
5765
5766    pub fn spin_speed(&self) -> f32 {
5767        // SAFETY: plain scalar read through a live handle.
5768        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_spinSpeed(self.raw.as_ptr()) }
5769    }
5770
5771    pub fn set_spin_speed(&mut self, value: f32) {
5772        // SAFETY: plain scalar write through a live handle.
5773        unsafe { ffi::whiteout_m2_M2ParticleEmitter_set_spinSpeed(self.raw.as_ptr(), value) }
5774    }
5775
5776    pub fn spin_speed_variation(&self) -> f32 {
5777        // SAFETY: plain scalar read through a live handle.
5778        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_spinSpeedVariation(self.raw.as_ptr()) }
5779    }
5780
5781    pub fn set_spin_speed_variation(&mut self, value: f32) {
5782        // SAFETY: plain scalar write through a live handle.
5783        unsafe {
5784            ffi::whiteout_m2_M2ParticleEmitter_set_spinSpeedVariation(self.raw.as_ptr(), value)
5785        }
5786    }
5787
5788    /// Borrows the field in place — no copy, no allocation.
5789    pub fn tumble(&self) -> crate::support::Ref<'_, Box> {
5790        // SAFETY: an interior pointer into `self`, valid for this
5791        // borrow and never freed by the `Ref`.
5792        unsafe {
5793            crate::support::Ref::new(Box {
5794                raw: core::ptr::NonNull::new_unchecked(
5795                    ffi::whiteout_m2_M2ParticleEmitter_get_tumble(self.raw.as_ptr()),
5796                ),
5797            })
5798        }
5799    }
5800
5801    pub fn tumble_mut(&mut self) -> crate::support::RefMut<'_, Box> {
5802        // SAFETY: as above; `&mut self` guarantees exclusivity.
5803        unsafe {
5804            crate::support::RefMut::new(Box {
5805                raw: core::ptr::NonNull::new_unchecked(
5806                    ffi::whiteout_m2_M2ParticleEmitter_get_tumble(self.raw.as_ptr()),
5807                ),
5808            })
5809        }
5810    }
5811
5812    pub fn wind_vector(&self) -> crate::math::Vector3f {
5813        // SAFETY: the getter returns an interior pointer to a
5814        // layout-identical POD; we copy it out immediately.
5815        unsafe {
5816            *(ffi::whiteout_m2_M2ParticleEmitter_get_windVector(self.raw.as_ptr())
5817                as *const crate::math::Vector3f)
5818        }
5819    }
5820
5821    pub fn set_wind_vector(&mut self, value: crate::math::Vector3f) {
5822        // SAFETY: as above, in the other direction.
5823        unsafe {
5824            ffi::whiteout_m2_M2ParticleEmitter_set_windVector(
5825                self.raw.as_ptr(),
5826                &value as *const crate::math::Vector3f as *const _,
5827            )
5828        }
5829    }
5830
5831    pub fn wind_time(&self) -> f32 {
5832        // SAFETY: plain scalar read through a live handle.
5833        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_windTime(self.raw.as_ptr()) }
5834    }
5835
5836    pub fn set_wind_time(&mut self, value: f32) {
5837        // SAFETY: plain scalar write through a live handle.
5838        unsafe { ffi::whiteout_m2_M2ParticleEmitter_set_windTime(self.raw.as_ptr(), value) }
5839    }
5840
5841    pub fn follow_speed_1(&self) -> f32 {
5842        // SAFETY: plain scalar read through a live handle.
5843        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_followSpeed1(self.raw.as_ptr()) }
5844    }
5845
5846    pub fn set_follow_speed_1(&mut self, value: f32) {
5847        // SAFETY: plain scalar write through a live handle.
5848        unsafe { ffi::whiteout_m2_M2ParticleEmitter_set_followSpeed1(self.raw.as_ptr(), value) }
5849    }
5850
5851    pub fn follow_scale_1(&self) -> f32 {
5852        // SAFETY: plain scalar read through a live handle.
5853        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_followScale1(self.raw.as_ptr()) }
5854    }
5855
5856    pub fn set_follow_scale_1(&mut self, value: f32) {
5857        // SAFETY: plain scalar write through a live handle.
5858        unsafe { ffi::whiteout_m2_M2ParticleEmitter_set_followScale1(self.raw.as_ptr(), value) }
5859    }
5860
5861    pub fn follow_speed_2(&self) -> f32 {
5862        // SAFETY: plain scalar read through a live handle.
5863        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_followSpeed2(self.raw.as_ptr()) }
5864    }
5865
5866    pub fn set_follow_speed_2(&mut self, value: f32) {
5867        // SAFETY: plain scalar write through a live handle.
5868        unsafe { ffi::whiteout_m2_M2ParticleEmitter_set_followSpeed2(self.raw.as_ptr(), value) }
5869    }
5870
5871    pub fn follow_scale_2(&self) -> f32 {
5872        // SAFETY: plain scalar read through a live handle.
5873        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_followScale2(self.raw.as_ptr()) }
5874    }
5875
5876    pub fn set_follow_scale_2(&mut self, value: f32) {
5877        // SAFETY: plain scalar write through a live handle.
5878        unsafe { ffi::whiteout_m2_M2ParticleEmitter_set_followScale2(self.raw.as_ptr(), value) }
5879    }
5880
5881    /// Zero-copy view of the underlying `std::vector`.
5882    pub fn spline_points(&self) -> &[crate::math::Vector3f] {
5883        // SAFETY: `_data`/`_count` describe one contiguous C++
5884        // allocation, borrowed for as long as `self` is.
5885        unsafe {
5886            let n = ffi::whiteout_m2_M2ParticleEmitter_get_splinePoints_count(self.raw.as_ptr());
5887            let p = ffi::whiteout_m2_M2ParticleEmitter_get_splinePoints_data(self.raw.as_ptr())
5888                as *const crate::math::Vector3f;
5889            if p.is_null() || n == 0 {
5890                &[]
5891            } else {
5892                core::slice::from_raw_parts(p, n)
5893            }
5894        }
5895    }
5896
5897    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
5898    pub fn spline_points_mut(&mut self) -> &mut [crate::math::Vector3f] {
5899        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
5900        unsafe {
5901            let n = ffi::whiteout_m2_M2ParticleEmitter_get_splinePoints_count(self.raw.as_ptr());
5902            let p = ffi::whiteout_m2_M2ParticleEmitter_get_splinePoints_data(self.raw.as_ptr())
5903                as *const crate::math::Vector3f as *mut crate::math::Vector3f;
5904            if p.is_null() || n == 0 {
5905                &mut []
5906            } else {
5907                core::slice::from_raw_parts_mut(p, n)
5908            }
5909        }
5910    }
5911
5912    pub fn set_spline_points(&mut self, values: &[crate::math::Vector3f]) {
5913        // SAFETY: the native side copies `values` before returning.
5914        unsafe {
5915            ffi::whiteout_m2_M2ParticleEmitter_assign_splinePoints(
5916                self.raw.as_ptr(),
5917                values.as_ptr() as *const _,
5918                values.len(),
5919            )
5920        }
5921    }
5922
5923    pub fn resize_spline_points(&mut self, count: usize) {
5924        // SAFETY: reallocation is safe here precisely because
5925        // `&mut self` means no slice borrow is outstanding.
5926        unsafe { ffi::whiteout_m2_M2ParticleEmitter_resize_splinePoints(self.raw.as_ptr(), count) }
5927    }
5928
5929    /// Borrows the field in place — no copy, no allocation.
5930    pub fn enabled_in(&self) -> crate::support::Ref<'_, AnimationTrackU8> {
5931        // SAFETY: an interior pointer into `self`, valid for this
5932        // borrow and never freed by the `Ref`.
5933        unsafe {
5934            crate::support::Ref::new(AnimationTrackU8 {
5935                raw: core::ptr::NonNull::new_unchecked(
5936                    ffi::whiteout_m2_M2ParticleEmitter_get_enabledIn(self.raw.as_ptr()),
5937                ),
5938            })
5939        }
5940    }
5941
5942    pub fn enabled_in_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackU8> {
5943        // SAFETY: as above; `&mut self` guarantees exclusivity.
5944        unsafe {
5945            crate::support::RefMut::new(AnimationTrackU8 {
5946                raw: core::ptr::NonNull::new_unchecked(
5947                    ffi::whiteout_m2_M2ParticleEmitter_get_enabledIn(self.raw.as_ptr()),
5948                ),
5949            })
5950        }
5951    }
5952}
5953
5954impl Default for ParticleEmitter {
5955    fn default() -> Self {
5956        Self::new()
5957    }
5958}
5959
5960pub struct Event {
5961    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2Event>,
5962}
5963
5964impl Drop for Event {
5965    fn drop(&mut self) {
5966        // SAFETY: `raw` came from a native constructor and Drop runs once.
5967        unsafe { ffi::whiteout_m2_M2Event_delete(self.raw.as_ptr()) }
5968    }
5969}
5970
5971impl Event {
5972    /// # Safety
5973    /// `raw` must be a live handle this value takes ownership of.
5974    #[allow(dead_code)] // used by whichever methods return this type
5975    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2Event) -> Option<Self> {
5976        core::ptr::NonNull::new(raw).map(|raw| Event { raw })
5977    }
5978}
5979
5980// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
5981// is deliberately NOT implemented — the C++ types make no documented
5982// guarantee about concurrent use, and claiming one we haven't verified
5983// would be unsound. See `@bind thread_safe` in the plan.
5984unsafe impl Send for Event {}
5985
5986impl core::fmt::Debug for Event {
5987    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
5988        f.debug_struct("Event").finish_non_exhaustive()
5989    }
5990}
5991
5992impl Event {
5993    /// # Panics
5994    /// Panics if the native allocation fails.
5995    pub fn new() -> Self {
5996        // SAFETY: the native constructor returns a live handle; a null here
5997        // means the library is unusable.
5998        unsafe {
5999            let raw = ffi::whiteout_m2_M2Event_new();
6000            Self::from_raw(raw).expect("native Event allocation failed")
6001        }
6002    }
6003
6004    pub fn identifier(&self) -> u32 {
6005        // SAFETY: plain scalar read through a live handle.
6006        unsafe { ffi::whiteout_m2_M2Event_get_identifier(self.raw.as_ptr()) }
6007    }
6008
6009    pub fn set_identifier(&mut self, value: u32) {
6010        // SAFETY: plain scalar write through a live handle.
6011        unsafe { ffi::whiteout_m2_M2Event_set_identifier(self.raw.as_ptr(), value) }
6012    }
6013
6014    pub fn data(&self) -> u32 {
6015        // SAFETY: plain scalar read through a live handle.
6016        unsafe { ffi::whiteout_m2_M2Event_get_data(self.raw.as_ptr()) }
6017    }
6018
6019    pub fn set_data(&mut self, value: u32) {
6020        // SAFETY: plain scalar write through a live handle.
6021        unsafe { ffi::whiteout_m2_M2Event_set_data(self.raw.as_ptr(), value) }
6022    }
6023
6024    pub fn bone_id(&self) -> u32 {
6025        // SAFETY: plain scalar read through a live handle.
6026        unsafe { ffi::whiteout_m2_M2Event_get_boneId(self.raw.as_ptr()) }
6027    }
6028
6029    pub fn set_bone_id(&mut self, value: u32) {
6030        // SAFETY: plain scalar write through a live handle.
6031        unsafe { ffi::whiteout_m2_M2Event_set_boneId(self.raw.as_ptr(), value) }
6032    }
6033
6034    pub fn position(&self) -> crate::math::Vector3f {
6035        // SAFETY: the getter returns an interior pointer to a
6036        // layout-identical POD; we copy it out immediately.
6037        unsafe {
6038            *(ffi::whiteout_m2_M2Event_get_position(self.raw.as_ptr())
6039                as *const crate::math::Vector3f)
6040        }
6041    }
6042
6043    pub fn set_position(&mut self, value: crate::math::Vector3f) {
6044        // SAFETY: as above, in the other direction.
6045        unsafe {
6046            ffi::whiteout_m2_M2Event_set_position(
6047                self.raw.as_ptr(),
6048                &value as *const crate::math::Vector3f as *const _,
6049            )
6050        }
6051    }
6052
6053    /// Borrows the field in place — no copy, no allocation.
6054    pub fn enabled(&self) -> crate::support::Ref<'_, AnimationTrackBase> {
6055        // SAFETY: an interior pointer into `self`, valid for this
6056        // borrow and never freed by the `Ref`.
6057        unsafe {
6058            crate::support::Ref::new(AnimationTrackBase {
6059                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Event_get_enabled(
6060                    self.raw.as_ptr(),
6061                )),
6062            })
6063        }
6064    }
6065
6066    pub fn enabled_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackBase> {
6067        // SAFETY: as above; `&mut self` guarantees exclusivity.
6068        unsafe {
6069            crate::support::RefMut::new(AnimationTrackBase {
6070                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Event_get_enabled(
6071                    self.raw.as_ptr(),
6072                )),
6073            })
6074        }
6075    }
6076}
6077
6078impl Default for Event {
6079    fn default() -> Self {
6080        Self::new()
6081    }
6082}
6083
6084pub struct Model {
6085    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2Model>,
6086}
6087
6088impl Drop for Model {
6089    fn drop(&mut self) {
6090        // SAFETY: `raw` came from a native constructor and Drop runs once.
6091        unsafe { ffi::whiteout_m2_M2Model_delete(self.raw.as_ptr()) }
6092    }
6093}
6094
6095impl Model {
6096    /// # Safety
6097    /// `raw` must be a live handle this value takes ownership of.
6098    #[allow(dead_code)] // used by whichever methods return this type
6099    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2Model) -> Option<Self> {
6100        core::ptr::NonNull::new(raw).map(|raw| Model { raw })
6101    }
6102}
6103
6104// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
6105// is deliberately NOT implemented — the C++ types make no documented
6106// guarantee about concurrent use, and claiming one we haven't verified
6107// would be unsound. See `@bind thread_safe` in the plan.
6108unsafe impl Send for Model {}
6109
6110impl core::fmt::Debug for Model {
6111    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
6112        f.debug_struct("Model").finish_non_exhaustive()
6113    }
6114}
6115
6116impl Model {
6117    /// # Panics
6118    /// Panics if the native allocation fails.
6119    pub fn new() -> Self {
6120        // SAFETY: the native constructor returns a live handle; a null here
6121        // means the library is unusable.
6122        unsafe {
6123            let raw = ffi::whiteout_m2_M2Model_new();
6124            Self::from_raw(raw).expect("native Model allocation failed")
6125        }
6126    }
6127
6128    pub fn model_name(&self) -> String {
6129        // SAFETY: the native side hands over an owned CString.
6130        unsafe {
6131            crate::support::take_string(ffi::whiteout_m2_M2Model_get_modelName(self.raw.as_ptr()))
6132        }
6133    }
6134
6135    pub fn set_model_name(&mut self, value: &str) {
6136        let value = std::ffi::CString::new(value).unwrap_or_default();
6137        // SAFETY: the pointer outlives the call.
6138        unsafe { ffi::whiteout_m2_M2Model_set_modelName(self.raw.as_ptr(), value.as_ptr()) }
6139    }
6140
6141    /// Borrows the field in place — no copy, no allocation.
6142    pub fn global_flags(&self) -> crate::support::Ref<'_, GlobalFlags> {
6143        // SAFETY: an interior pointer into `self`, valid for this
6144        // borrow and never freed by the `Ref`.
6145        unsafe {
6146            crate::support::Ref::new(GlobalFlags {
6147                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_globalFlags(
6148                    self.raw.as_ptr(),
6149                )),
6150            })
6151        }
6152    }
6153
6154    pub fn global_flags_mut(&mut self) -> crate::support::RefMut<'_, GlobalFlags> {
6155        // SAFETY: as above; `&mut self` guarantees exclusivity.
6156        unsafe {
6157            crate::support::RefMut::new(GlobalFlags {
6158                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_globalFlags(
6159                    self.raw.as_ptr(),
6160                )),
6161            })
6162        }
6163    }
6164
6165    pub fn global_loops_len(&self) -> usize {
6166        // SAFETY: scalar read through a live handle.
6167        unsafe { ffi::whiteout_m2_M2Model_get_globalLoops_count(self.raw.as_ptr()) }
6168    }
6169
6170    /// Borrows element `index` in place. `None` when out of range.
6171    pub fn global_loops(&self, index: usize) -> Option<crate::support::Ref<'_, GlobalSequence>> {
6172        if index >= self.global_loops_len() {
6173            return None;
6174        }
6175        // SAFETY: index checked above; the pointer is interior to `self`.
6176        unsafe {
6177            Some(crate::support::Ref::new(GlobalSequence {
6178                raw: core::ptr::NonNull::new_unchecked(
6179                    ffi::whiteout_m2_M2Model_get_globalLoops_at(self.raw.as_ptr(), index),
6180                ),
6181            }))
6182        }
6183    }
6184
6185    pub fn global_loops_mut(
6186        &mut self,
6187        index: usize,
6188    ) -> Option<crate::support::RefMut<'_, GlobalSequence>> {
6189        if index >= self.global_loops_len() {
6190            return None;
6191        }
6192        // SAFETY: as above; `&mut self` guarantees exclusivity.
6193        unsafe {
6194            Some(crate::support::RefMut::new(GlobalSequence {
6195                raw: core::ptr::NonNull::new_unchecked(
6196                    ffi::whiteout_m2_M2Model_get_globalLoops_at(self.raw.as_ptr(), index),
6197                ),
6198            }))
6199        }
6200    }
6201
6202    /// Iterate the elements, borrowing each in turn.
6203    pub fn global_loops_iter(
6204        &self,
6205    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, GlobalSequence>> {
6206        (0..self.global_loops_len()).map(move |i| self.global_loops(i).expect("index below len"))
6207    }
6208
6209    pub fn resize_global_loops(&mut self, count: usize) {
6210        // SAFETY: exclusive access, so no borrow is outstanding.
6211        unsafe { ffi::whiteout_m2_M2Model_resize_globalLoops(self.raw.as_ptr(), count) }
6212    }
6213
6214    pub fn sequences_len(&self) -> usize {
6215        // SAFETY: scalar read through a live handle.
6216        unsafe { ffi::whiteout_m2_M2Model_get_sequences_count(self.raw.as_ptr()) }
6217    }
6218
6219    /// Borrows element `index` in place. `None` when out of range.
6220    pub fn sequences(&self, index: usize) -> Option<crate::support::Ref<'_, Sequence>> {
6221        if index >= self.sequences_len() {
6222            return None;
6223        }
6224        // SAFETY: index checked above; the pointer is interior to `self`.
6225        unsafe {
6226            Some(crate::support::Ref::new(Sequence {
6227                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_sequences_at(
6228                    self.raw.as_ptr(),
6229                    index,
6230                )),
6231            }))
6232        }
6233    }
6234
6235    pub fn sequences_mut(&mut self, index: usize) -> Option<crate::support::RefMut<'_, Sequence>> {
6236        if index >= self.sequences_len() {
6237            return None;
6238        }
6239        // SAFETY: as above; `&mut self` guarantees exclusivity.
6240        unsafe {
6241            Some(crate::support::RefMut::new(Sequence {
6242                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_sequences_at(
6243                    self.raw.as_ptr(),
6244                    index,
6245                )),
6246            }))
6247        }
6248    }
6249
6250    /// Iterate the elements, borrowing each in turn.
6251    pub fn sequences_iter(
6252        &self,
6253    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, Sequence>> {
6254        (0..self.sequences_len()).map(move |i| self.sequences(i).expect("index below len"))
6255    }
6256
6257    pub fn resize_sequences(&mut self, count: usize) {
6258        // SAFETY: exclusive access, so no borrow is outstanding.
6259        unsafe { ffi::whiteout_m2_M2Model_resize_sequences(self.raw.as_ptr(), count) }
6260    }
6261
6262    /// Zero-copy view of the underlying `std::vector`.
6263    pub fn sequence_idx_hash_by_id(&self) -> &[u16] {
6264        // SAFETY: `_data`/`_count` describe one contiguous C++
6265        // allocation, borrowed for as long as `self` is.
6266        unsafe {
6267            let n = ffi::whiteout_m2_M2Model_get_sequenceIdxHashById_count(self.raw.as_ptr());
6268            let p = ffi::whiteout_m2_M2Model_get_sequenceIdxHashById_data(self.raw.as_ptr());
6269            if p.is_null() || n == 0 {
6270                &[]
6271            } else {
6272                core::slice::from_raw_parts(p, n)
6273            }
6274        }
6275    }
6276
6277    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
6278    pub fn sequence_idx_hash_by_id_mut(&mut self) -> &mut [u16] {
6279        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
6280        unsafe {
6281            let n = ffi::whiteout_m2_M2Model_get_sequenceIdxHashById_count(self.raw.as_ptr());
6282            let p = ffi::whiteout_m2_M2Model_get_sequenceIdxHashById_data(self.raw.as_ptr())
6283                as *mut u16;
6284            if p.is_null() || n == 0 {
6285                &mut []
6286            } else {
6287                core::slice::from_raw_parts_mut(p, n)
6288            }
6289        }
6290    }
6291
6292    pub fn set_sequence_idx_hash_by_id(&mut self, values: &[u16]) {
6293        // SAFETY: the native side copies `values` before returning.
6294        unsafe {
6295            ffi::whiteout_m2_M2Model_assign_sequenceIdxHashById(
6296                self.raw.as_ptr(),
6297                values.as_ptr() as *const _,
6298                values.len(),
6299            )
6300        }
6301    }
6302
6303    pub fn resize_sequence_idx_hash_by_id(&mut self, count: usize) {
6304        // SAFETY: reallocation is safe here precisely because
6305        // `&mut self` means no slice borrow is outstanding.
6306        unsafe { ffi::whiteout_m2_M2Model_resize_sequenceIdxHashById(self.raw.as_ptr(), count) }
6307    }
6308
6309    pub fn bones_len(&self) -> usize {
6310        // SAFETY: scalar read through a live handle.
6311        unsafe { ffi::whiteout_m2_M2Model_get_bones_count(self.raw.as_ptr()) }
6312    }
6313
6314    /// Borrows element `index` in place. `None` when out of range.
6315    pub fn bones(&self, index: usize) -> Option<crate::support::Ref<'_, Bone>> {
6316        if index >= self.bones_len() {
6317            return None;
6318        }
6319        // SAFETY: index checked above; the pointer is interior to `self`.
6320        unsafe {
6321            Some(crate::support::Ref::new(Bone {
6322                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_bones_at(
6323                    self.raw.as_ptr(),
6324                    index,
6325                )),
6326            }))
6327        }
6328    }
6329
6330    pub fn bones_mut(&mut self, index: usize) -> Option<crate::support::RefMut<'_, Bone>> {
6331        if index >= self.bones_len() {
6332            return None;
6333        }
6334        // SAFETY: as above; `&mut self` guarantees exclusivity.
6335        unsafe {
6336            Some(crate::support::RefMut::new(Bone {
6337                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_bones_at(
6338                    self.raw.as_ptr(),
6339                    index,
6340                )),
6341            }))
6342        }
6343    }
6344
6345    /// Iterate the elements, borrowing each in turn.
6346    pub fn bones_iter(&self) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, Bone>> {
6347        (0..self.bones_len()).map(move |i| self.bones(i).expect("index below len"))
6348    }
6349
6350    pub fn resize_bones(&mut self, count: usize) {
6351        // SAFETY: exclusive access, so no borrow is outstanding.
6352        unsafe { ffi::whiteout_m2_M2Model_resize_bones(self.raw.as_ptr(), count) }
6353    }
6354
6355    /// Zero-copy view of the underlying `std::vector`.
6356    pub fn key_bone_ids(&self) -> &[u16] {
6357        // SAFETY: `_data`/`_count` describe one contiguous C++
6358        // allocation, borrowed for as long as `self` is.
6359        unsafe {
6360            let n = ffi::whiteout_m2_M2Model_get_keyBoneIds_count(self.raw.as_ptr());
6361            let p = ffi::whiteout_m2_M2Model_get_keyBoneIds_data(self.raw.as_ptr());
6362            if p.is_null() || n == 0 {
6363                &[]
6364            } else {
6365                core::slice::from_raw_parts(p, n)
6366            }
6367        }
6368    }
6369
6370    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
6371    pub fn key_bone_ids_mut(&mut self) -> &mut [u16] {
6372        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
6373        unsafe {
6374            let n = ffi::whiteout_m2_M2Model_get_keyBoneIds_count(self.raw.as_ptr());
6375            let p = ffi::whiteout_m2_M2Model_get_keyBoneIds_data(self.raw.as_ptr()) as *mut u16;
6376            if p.is_null() || n == 0 {
6377                &mut []
6378            } else {
6379                core::slice::from_raw_parts_mut(p, n)
6380            }
6381        }
6382    }
6383
6384    pub fn set_key_bone_ids(&mut self, values: &[u16]) {
6385        // SAFETY: the native side copies `values` before returning.
6386        unsafe {
6387            ffi::whiteout_m2_M2Model_assign_keyBoneIds(
6388                self.raw.as_ptr(),
6389                values.as_ptr() as *const _,
6390                values.len(),
6391            )
6392        }
6393    }
6394
6395    pub fn resize_key_bone_ids(&mut self, count: usize) {
6396        // SAFETY: reallocation is safe here precisely because
6397        // `&mut self` means no slice borrow is outstanding.
6398        unsafe { ffi::whiteout_m2_M2Model_resize_keyBoneIds(self.raw.as_ptr(), count) }
6399    }
6400
6401    pub fn vertices_len(&self) -> usize {
6402        // SAFETY: scalar read through a live handle.
6403        unsafe { ffi::whiteout_m2_M2Model_get_vertices_count(self.raw.as_ptr()) }
6404    }
6405
6406    /// Borrows element `index` in place. `None` when out of range.
6407    pub fn vertices(&self, index: usize) -> Option<crate::support::Ref<'_, Vertex>> {
6408        if index >= self.vertices_len() {
6409            return None;
6410        }
6411        // SAFETY: index checked above; the pointer is interior to `self`.
6412        unsafe {
6413            Some(crate::support::Ref::new(Vertex {
6414                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_vertices_at(
6415                    self.raw.as_ptr(),
6416                    index,
6417                )),
6418            }))
6419        }
6420    }
6421
6422    pub fn vertices_mut(&mut self, index: usize) -> Option<crate::support::RefMut<'_, Vertex>> {
6423        if index >= self.vertices_len() {
6424            return None;
6425        }
6426        // SAFETY: as above; `&mut self` guarantees exclusivity.
6427        unsafe {
6428            Some(crate::support::RefMut::new(Vertex {
6429                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_vertices_at(
6430                    self.raw.as_ptr(),
6431                    index,
6432                )),
6433            }))
6434        }
6435    }
6436
6437    /// Iterate the elements, borrowing each in turn.
6438    pub fn vertices_iter(&self) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, Vertex>> {
6439        (0..self.vertices_len()).map(move |i| self.vertices(i).expect("index below len"))
6440    }
6441
6442    pub fn resize_vertices(&mut self, count: usize) {
6443        // SAFETY: exclusive access, so no borrow is outstanding.
6444        unsafe { ffi::whiteout_m2_M2Model_resize_vertices(self.raw.as_ptr(), count) }
6445    }
6446
6447    pub fn skin_profiles_len(&self) -> usize {
6448        // SAFETY: scalar read through a live handle.
6449        unsafe { ffi::whiteout_m2_M2Model_get_skinProfiles_count(self.raw.as_ptr()) }
6450    }
6451
6452    /// Borrows element `index` in place. `None` when out of range.
6453    pub fn skin_profiles(&self, index: usize) -> Option<crate::support::Ref<'_, SkinProfile>> {
6454        if index >= self.skin_profiles_len() {
6455            return None;
6456        }
6457        // SAFETY: index checked above; the pointer is interior to `self`.
6458        unsafe {
6459            Some(crate::support::Ref::new(SkinProfile {
6460                raw: core::ptr::NonNull::new_unchecked(
6461                    ffi::whiteout_m2_M2Model_get_skinProfiles_at(self.raw.as_ptr(), index),
6462                ),
6463            }))
6464        }
6465    }
6466
6467    pub fn skin_profiles_mut(
6468        &mut self,
6469        index: usize,
6470    ) -> Option<crate::support::RefMut<'_, SkinProfile>> {
6471        if index >= self.skin_profiles_len() {
6472            return None;
6473        }
6474        // SAFETY: as above; `&mut self` guarantees exclusivity.
6475        unsafe {
6476            Some(crate::support::RefMut::new(SkinProfile {
6477                raw: core::ptr::NonNull::new_unchecked(
6478                    ffi::whiteout_m2_M2Model_get_skinProfiles_at(self.raw.as_ptr(), index),
6479                ),
6480            }))
6481        }
6482    }
6483
6484    /// Iterate the elements, borrowing each in turn.
6485    pub fn skin_profiles_iter(
6486        &self,
6487    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, SkinProfile>> {
6488        (0..self.skin_profiles_len()).map(move |i| self.skin_profiles(i).expect("index below len"))
6489    }
6490
6491    pub fn resize_skin_profiles(&mut self, count: usize) {
6492        // SAFETY: exclusive access, so no borrow is outstanding.
6493        unsafe { ffi::whiteout_m2_M2Model_resize_skinProfiles(self.raw.as_ptr(), count) }
6494    }
6495
6496    pub fn lod_profiles_len(&self) -> usize {
6497        // SAFETY: scalar read through a live handle.
6498        unsafe { ffi::whiteout_m2_M2Model_get_lodProfiles_count(self.raw.as_ptr()) }
6499    }
6500
6501    /// Borrows element `index` in place. `None` when out of range.
6502    pub fn lod_profiles(&self, index: usize) -> Option<crate::support::Ref<'_, SkinProfile>> {
6503        if index >= self.lod_profiles_len() {
6504            return None;
6505        }
6506        // SAFETY: index checked above; the pointer is interior to `self`.
6507        unsafe {
6508            Some(crate::support::Ref::new(SkinProfile {
6509                raw: core::ptr::NonNull::new_unchecked(
6510                    ffi::whiteout_m2_M2Model_get_lodProfiles_at(self.raw.as_ptr(), index),
6511                ),
6512            }))
6513        }
6514    }
6515
6516    pub fn lod_profiles_mut(
6517        &mut self,
6518        index: usize,
6519    ) -> Option<crate::support::RefMut<'_, SkinProfile>> {
6520        if index >= self.lod_profiles_len() {
6521            return None;
6522        }
6523        // SAFETY: as above; `&mut self` guarantees exclusivity.
6524        unsafe {
6525            Some(crate::support::RefMut::new(SkinProfile {
6526                raw: core::ptr::NonNull::new_unchecked(
6527                    ffi::whiteout_m2_M2Model_get_lodProfiles_at(self.raw.as_ptr(), index),
6528                ),
6529            }))
6530        }
6531    }
6532
6533    /// Iterate the elements, borrowing each in turn.
6534    pub fn lod_profiles_iter(
6535        &self,
6536    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, SkinProfile>> {
6537        (0..self.lod_profiles_len()).map(move |i| self.lod_profiles(i).expect("index below len"))
6538    }
6539
6540    pub fn resize_lod_profiles(&mut self, count: usize) {
6541        // SAFETY: exclusive access, so no borrow is outstanding.
6542        unsafe { ffi::whiteout_m2_M2Model_resize_lodProfiles(self.raw.as_ptr(), count) }
6543    }
6544
6545    pub fn num_skin_profiles(&self) -> u32 {
6546        // SAFETY: plain scalar read through a live handle.
6547        unsafe { ffi::whiteout_m2_M2Model_get_numSkinProfiles(self.raw.as_ptr()) }
6548    }
6549
6550    pub fn set_num_skin_profiles(&mut self, value: u32) {
6551        // SAFETY: plain scalar write through a live handle.
6552        unsafe { ffi::whiteout_m2_M2Model_set_numSkinProfiles(self.raw.as_ptr(), value) }
6553    }
6554
6555    pub fn colors_len(&self) -> usize {
6556        // SAFETY: scalar read through a live handle.
6557        unsafe { ffi::whiteout_m2_M2Model_get_colors_count(self.raw.as_ptr()) }
6558    }
6559
6560    /// Borrows element `index` in place. `None` when out of range.
6561    pub fn colors(&self, index: usize) -> Option<crate::support::Ref<'_, ColorAnimation>> {
6562        if index >= self.colors_len() {
6563            return None;
6564        }
6565        // SAFETY: index checked above; the pointer is interior to `self`.
6566        unsafe {
6567            Some(crate::support::Ref::new(ColorAnimation {
6568                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_colors_at(
6569                    self.raw.as_ptr(),
6570                    index,
6571                )),
6572            }))
6573        }
6574    }
6575
6576    pub fn colors_mut(
6577        &mut self,
6578        index: usize,
6579    ) -> Option<crate::support::RefMut<'_, ColorAnimation>> {
6580        if index >= self.colors_len() {
6581            return None;
6582        }
6583        // SAFETY: as above; `&mut self` guarantees exclusivity.
6584        unsafe {
6585            Some(crate::support::RefMut::new(ColorAnimation {
6586                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_colors_at(
6587                    self.raw.as_ptr(),
6588                    index,
6589                )),
6590            }))
6591        }
6592    }
6593
6594    /// Iterate the elements, borrowing each in turn.
6595    pub fn colors_iter(
6596        &self,
6597    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, ColorAnimation>> {
6598        (0..self.colors_len()).map(move |i| self.colors(i).expect("index below len"))
6599    }
6600
6601    pub fn resize_colors(&mut self, count: usize) {
6602        // SAFETY: exclusive access, so no borrow is outstanding.
6603        unsafe { ffi::whiteout_m2_M2Model_resize_colors(self.raw.as_ptr(), count) }
6604    }
6605
6606    pub fn textures_len(&self) -> usize {
6607        // SAFETY: scalar read through a live handle.
6608        unsafe { ffi::whiteout_m2_M2Model_get_textures_count(self.raw.as_ptr()) }
6609    }
6610
6611    /// Borrows element `index` in place. `None` when out of range.
6612    pub fn textures(&self, index: usize) -> Option<crate::support::Ref<'_, Texture>> {
6613        if index >= self.textures_len() {
6614            return None;
6615        }
6616        // SAFETY: index checked above; the pointer is interior to `self`.
6617        unsafe {
6618            Some(crate::support::Ref::new(Texture {
6619                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_textures_at(
6620                    self.raw.as_ptr(),
6621                    index,
6622                )),
6623            }))
6624        }
6625    }
6626
6627    pub fn textures_mut(&mut self, index: usize) -> Option<crate::support::RefMut<'_, Texture>> {
6628        if index >= self.textures_len() {
6629            return None;
6630        }
6631        // SAFETY: as above; `&mut self` guarantees exclusivity.
6632        unsafe {
6633            Some(crate::support::RefMut::new(Texture {
6634                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_textures_at(
6635                    self.raw.as_ptr(),
6636                    index,
6637                )),
6638            }))
6639        }
6640    }
6641
6642    /// Iterate the elements, borrowing each in turn.
6643    pub fn textures_iter(&self) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, Texture>> {
6644        (0..self.textures_len()).map(move |i| self.textures(i).expect("index below len"))
6645    }
6646
6647    pub fn resize_textures(&mut self, count: usize) {
6648        // SAFETY: exclusive access, so no borrow is outstanding.
6649        unsafe { ffi::whiteout_m2_M2Model_resize_textures(self.raw.as_ptr(), count) }
6650    }
6651
6652    pub fn texture_weights_len(&self) -> usize {
6653        // SAFETY: scalar read through a live handle.
6654        unsafe { ffi::whiteout_m2_M2Model_get_textureWeights_count(self.raw.as_ptr()) }
6655    }
6656
6657    /// Borrows element `index` in place. `None` when out of range.
6658    pub fn texture_weights(&self, index: usize) -> Option<crate::support::Ref<'_, TextureWeight>> {
6659        if index >= self.texture_weights_len() {
6660            return None;
6661        }
6662        // SAFETY: index checked above; the pointer is interior to `self`.
6663        unsafe {
6664            Some(crate::support::Ref::new(TextureWeight {
6665                raw: core::ptr::NonNull::new_unchecked(
6666                    ffi::whiteout_m2_M2Model_get_textureWeights_at(self.raw.as_ptr(), index),
6667                ),
6668            }))
6669        }
6670    }
6671
6672    pub fn texture_weights_mut(
6673        &mut self,
6674        index: usize,
6675    ) -> Option<crate::support::RefMut<'_, TextureWeight>> {
6676        if index >= self.texture_weights_len() {
6677            return None;
6678        }
6679        // SAFETY: as above; `&mut self` guarantees exclusivity.
6680        unsafe {
6681            Some(crate::support::RefMut::new(TextureWeight {
6682                raw: core::ptr::NonNull::new_unchecked(
6683                    ffi::whiteout_m2_M2Model_get_textureWeights_at(self.raw.as_ptr(), index),
6684                ),
6685            }))
6686        }
6687    }
6688
6689    /// Iterate the elements, borrowing each in turn.
6690    pub fn texture_weights_iter(
6691        &self,
6692    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, TextureWeight>> {
6693        (0..self.texture_weights_len())
6694            .map(move |i| self.texture_weights(i).expect("index below len"))
6695    }
6696
6697    pub fn resize_texture_weights(&mut self, count: usize) {
6698        // SAFETY: exclusive access, so no borrow is outstanding.
6699        unsafe { ffi::whiteout_m2_M2Model_resize_textureWeights(self.raw.as_ptr(), count) }
6700    }
6701
6702    pub fn texture_transforms_len(&self) -> usize {
6703        // SAFETY: scalar read through a live handle.
6704        unsafe { ffi::whiteout_m2_M2Model_get_textureTransforms_count(self.raw.as_ptr()) }
6705    }
6706
6707    /// Borrows element `index` in place. `None` when out of range.
6708    pub fn texture_transforms(
6709        &self,
6710        index: usize,
6711    ) -> Option<crate::support::Ref<'_, TextureTransform>> {
6712        if index >= self.texture_transforms_len() {
6713            return None;
6714        }
6715        // SAFETY: index checked above; the pointer is interior to `self`.
6716        unsafe {
6717            Some(crate::support::Ref::new(TextureTransform {
6718                raw: core::ptr::NonNull::new_unchecked(
6719                    ffi::whiteout_m2_M2Model_get_textureTransforms_at(self.raw.as_ptr(), index),
6720                ),
6721            }))
6722        }
6723    }
6724
6725    pub fn texture_transforms_mut(
6726        &mut self,
6727        index: usize,
6728    ) -> Option<crate::support::RefMut<'_, TextureTransform>> {
6729        if index >= self.texture_transforms_len() {
6730            return None;
6731        }
6732        // SAFETY: as above; `&mut self` guarantees exclusivity.
6733        unsafe {
6734            Some(crate::support::RefMut::new(TextureTransform {
6735                raw: core::ptr::NonNull::new_unchecked(
6736                    ffi::whiteout_m2_M2Model_get_textureTransforms_at(self.raw.as_ptr(), index),
6737                ),
6738            }))
6739        }
6740    }
6741
6742    /// Iterate the elements, borrowing each in turn.
6743    pub fn texture_transforms_iter(
6744        &self,
6745    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, TextureTransform>> {
6746        (0..self.texture_transforms_len())
6747            .map(move |i| self.texture_transforms(i).expect("index below len"))
6748    }
6749
6750    pub fn resize_texture_transforms(&mut self, count: usize) {
6751        // SAFETY: exclusive access, so no borrow is outstanding.
6752        unsafe { ffi::whiteout_m2_M2Model_resize_textureTransforms(self.raw.as_ptr(), count) }
6753    }
6754
6755    /// Zero-copy view of the underlying `std::vector`.
6756    pub fn texture_indices_by_id(&self) -> &[u16] {
6757        // SAFETY: `_data`/`_count` describe one contiguous C++
6758        // allocation, borrowed for as long as `self` is.
6759        unsafe {
6760            let n = ffi::whiteout_m2_M2Model_get_textureIndicesById_count(self.raw.as_ptr());
6761            let p = ffi::whiteout_m2_M2Model_get_textureIndicesById_data(self.raw.as_ptr());
6762            if p.is_null() || n == 0 {
6763                &[]
6764            } else {
6765                core::slice::from_raw_parts(p, n)
6766            }
6767        }
6768    }
6769
6770    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
6771    pub fn texture_indices_by_id_mut(&mut self) -> &mut [u16] {
6772        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
6773        unsafe {
6774            let n = ffi::whiteout_m2_M2Model_get_textureIndicesById_count(self.raw.as_ptr());
6775            let p =
6776                ffi::whiteout_m2_M2Model_get_textureIndicesById_data(self.raw.as_ptr()) as *mut u16;
6777            if p.is_null() || n == 0 {
6778                &mut []
6779            } else {
6780                core::slice::from_raw_parts_mut(p, n)
6781            }
6782        }
6783    }
6784
6785    pub fn set_texture_indices_by_id(&mut self, values: &[u16]) {
6786        // SAFETY: the native side copies `values` before returning.
6787        unsafe {
6788            ffi::whiteout_m2_M2Model_assign_textureIndicesById(
6789                self.raw.as_ptr(),
6790                values.as_ptr() as *const _,
6791                values.len(),
6792            )
6793        }
6794    }
6795
6796    pub fn resize_texture_indices_by_id(&mut self, count: usize) {
6797        // SAFETY: reallocation is safe here precisely because
6798        // `&mut self` means no slice borrow is outstanding.
6799        unsafe { ffi::whiteout_m2_M2Model_resize_textureIndicesById(self.raw.as_ptr(), count) }
6800    }
6801
6802    pub fn materials_len(&self) -> usize {
6803        // SAFETY: scalar read through a live handle.
6804        unsafe { ffi::whiteout_m2_M2Model_get_materials_count(self.raw.as_ptr()) }
6805    }
6806
6807    /// Borrows element `index` in place. `None` when out of range.
6808    pub fn materials(&self, index: usize) -> Option<crate::support::Ref<'_, Material>> {
6809        if index >= self.materials_len() {
6810            return None;
6811        }
6812        // SAFETY: index checked above; the pointer is interior to `self`.
6813        unsafe {
6814            Some(crate::support::Ref::new(Material {
6815                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_materials_at(
6816                    self.raw.as_ptr(),
6817                    index,
6818                )),
6819            }))
6820        }
6821    }
6822
6823    pub fn materials_mut(&mut self, index: usize) -> Option<crate::support::RefMut<'_, Material>> {
6824        if index >= self.materials_len() {
6825            return None;
6826        }
6827        // SAFETY: as above; `&mut self` guarantees exclusivity.
6828        unsafe {
6829            Some(crate::support::RefMut::new(Material {
6830                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_materials_at(
6831                    self.raw.as_ptr(),
6832                    index,
6833                )),
6834            }))
6835        }
6836    }
6837
6838    /// Iterate the elements, borrowing each in turn.
6839    pub fn materials_iter(
6840        &self,
6841    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, Material>> {
6842        (0..self.materials_len()).map(move |i| self.materials(i).expect("index below len"))
6843    }
6844
6845    pub fn resize_materials(&mut self, count: usize) {
6846        // SAFETY: exclusive access, so no borrow is outstanding.
6847        unsafe { ffi::whiteout_m2_M2Model_resize_materials(self.raw.as_ptr(), count) }
6848    }
6849
6850    /// Zero-copy view of the underlying `std::vector`.
6851    pub fn bone_combos(&self) -> &[u16] {
6852        // SAFETY: `_data`/`_count` describe one contiguous C++
6853        // allocation, borrowed for as long as `self` is.
6854        unsafe {
6855            let n = ffi::whiteout_m2_M2Model_get_boneCombos_count(self.raw.as_ptr());
6856            let p = ffi::whiteout_m2_M2Model_get_boneCombos_data(self.raw.as_ptr());
6857            if p.is_null() || n == 0 {
6858                &[]
6859            } else {
6860                core::slice::from_raw_parts(p, n)
6861            }
6862        }
6863    }
6864
6865    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
6866    pub fn bone_combos_mut(&mut self) -> &mut [u16] {
6867        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
6868        unsafe {
6869            let n = ffi::whiteout_m2_M2Model_get_boneCombos_count(self.raw.as_ptr());
6870            let p = ffi::whiteout_m2_M2Model_get_boneCombos_data(self.raw.as_ptr()) as *mut u16;
6871            if p.is_null() || n == 0 {
6872                &mut []
6873            } else {
6874                core::slice::from_raw_parts_mut(p, n)
6875            }
6876        }
6877    }
6878
6879    pub fn set_bone_combos(&mut self, values: &[u16]) {
6880        // SAFETY: the native side copies `values` before returning.
6881        unsafe {
6882            ffi::whiteout_m2_M2Model_assign_boneCombos(
6883                self.raw.as_ptr(),
6884                values.as_ptr() as *const _,
6885                values.len(),
6886            )
6887        }
6888    }
6889
6890    pub fn resize_bone_combos(&mut self, count: usize) {
6891        // SAFETY: reallocation is safe here precisely because
6892        // `&mut self` means no slice borrow is outstanding.
6893        unsafe { ffi::whiteout_m2_M2Model_resize_boneCombos(self.raw.as_ptr(), count) }
6894    }
6895
6896    /// Zero-copy view of the underlying `std::vector`.
6897    pub fn texture_combos(&self) -> &[u16] {
6898        // SAFETY: `_data`/`_count` describe one contiguous C++
6899        // allocation, borrowed for as long as `self` is.
6900        unsafe {
6901            let n = ffi::whiteout_m2_M2Model_get_textureCombos_count(self.raw.as_ptr());
6902            let p = ffi::whiteout_m2_M2Model_get_textureCombos_data(self.raw.as_ptr());
6903            if p.is_null() || n == 0 {
6904                &[]
6905            } else {
6906                core::slice::from_raw_parts(p, n)
6907            }
6908        }
6909    }
6910
6911    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
6912    pub fn texture_combos_mut(&mut self) -> &mut [u16] {
6913        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
6914        unsafe {
6915            let n = ffi::whiteout_m2_M2Model_get_textureCombos_count(self.raw.as_ptr());
6916            let p = ffi::whiteout_m2_M2Model_get_textureCombos_data(self.raw.as_ptr()) as *mut u16;
6917            if p.is_null() || n == 0 {
6918                &mut []
6919            } else {
6920                core::slice::from_raw_parts_mut(p, n)
6921            }
6922        }
6923    }
6924
6925    pub fn set_texture_combos(&mut self, values: &[u16]) {
6926        // SAFETY: the native side copies `values` before returning.
6927        unsafe {
6928            ffi::whiteout_m2_M2Model_assign_textureCombos(
6929                self.raw.as_ptr(),
6930                values.as_ptr() as *const _,
6931                values.len(),
6932            )
6933        }
6934    }
6935
6936    pub fn resize_texture_combos(&mut self, count: usize) {
6937        // SAFETY: reallocation is safe here precisely because
6938        // `&mut self` means no slice borrow is outstanding.
6939        unsafe { ffi::whiteout_m2_M2Model_resize_textureCombos(self.raw.as_ptr(), count) }
6940    }
6941
6942    /// Zero-copy view of the underlying `std::vector`.
6943    pub fn texture_coord_combos(&self) -> &[u16] {
6944        // SAFETY: `_data`/`_count` describe one contiguous C++
6945        // allocation, borrowed for as long as `self` is.
6946        unsafe {
6947            let n = ffi::whiteout_m2_M2Model_get_textureCoordCombos_count(self.raw.as_ptr());
6948            let p = ffi::whiteout_m2_M2Model_get_textureCoordCombos_data(self.raw.as_ptr());
6949            if p.is_null() || n == 0 {
6950                &[]
6951            } else {
6952                core::slice::from_raw_parts(p, n)
6953            }
6954        }
6955    }
6956
6957    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
6958    pub fn texture_coord_combos_mut(&mut self) -> &mut [u16] {
6959        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
6960        unsafe {
6961            let n = ffi::whiteout_m2_M2Model_get_textureCoordCombos_count(self.raw.as_ptr());
6962            let p =
6963                ffi::whiteout_m2_M2Model_get_textureCoordCombos_data(self.raw.as_ptr()) as *mut u16;
6964            if p.is_null() || n == 0 {
6965                &mut []
6966            } else {
6967                core::slice::from_raw_parts_mut(p, n)
6968            }
6969        }
6970    }
6971
6972    pub fn set_texture_coord_combos(&mut self, values: &[u16]) {
6973        // SAFETY: the native side copies `values` before returning.
6974        unsafe {
6975            ffi::whiteout_m2_M2Model_assign_textureCoordCombos(
6976                self.raw.as_ptr(),
6977                values.as_ptr() as *const _,
6978                values.len(),
6979            )
6980        }
6981    }
6982
6983    pub fn resize_texture_coord_combos(&mut self, count: usize) {
6984        // SAFETY: reallocation is safe here precisely because
6985        // `&mut self` means no slice borrow is outstanding.
6986        unsafe { ffi::whiteout_m2_M2Model_resize_textureCoordCombos(self.raw.as_ptr(), count) }
6987    }
6988
6989    /// Zero-copy view of the underlying `std::vector`.
6990    pub fn texture_weight_combos(&self) -> &[u16] {
6991        // SAFETY: `_data`/`_count` describe one contiguous C++
6992        // allocation, borrowed for as long as `self` is.
6993        unsafe {
6994            let n = ffi::whiteout_m2_M2Model_get_textureWeightCombos_count(self.raw.as_ptr());
6995            let p = ffi::whiteout_m2_M2Model_get_textureWeightCombos_data(self.raw.as_ptr());
6996            if p.is_null() || n == 0 {
6997                &[]
6998            } else {
6999                core::slice::from_raw_parts(p, n)
7000            }
7001        }
7002    }
7003
7004    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
7005    pub fn texture_weight_combos_mut(&mut self) -> &mut [u16] {
7006        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
7007        unsafe {
7008            let n = ffi::whiteout_m2_M2Model_get_textureWeightCombos_count(self.raw.as_ptr());
7009            let p = ffi::whiteout_m2_M2Model_get_textureWeightCombos_data(self.raw.as_ptr())
7010                as *mut u16;
7011            if p.is_null() || n == 0 {
7012                &mut []
7013            } else {
7014                core::slice::from_raw_parts_mut(p, n)
7015            }
7016        }
7017    }
7018
7019    pub fn set_texture_weight_combos(&mut self, values: &[u16]) {
7020        // SAFETY: the native side copies `values` before returning.
7021        unsafe {
7022            ffi::whiteout_m2_M2Model_assign_textureWeightCombos(
7023                self.raw.as_ptr(),
7024                values.as_ptr() as *const _,
7025                values.len(),
7026            )
7027        }
7028    }
7029
7030    pub fn resize_texture_weight_combos(&mut self, count: usize) {
7031        // SAFETY: reallocation is safe here precisely because
7032        // `&mut self` means no slice borrow is outstanding.
7033        unsafe { ffi::whiteout_m2_M2Model_resize_textureWeightCombos(self.raw.as_ptr(), count) }
7034    }
7035
7036    /// Zero-copy view of the underlying `std::vector`.
7037    pub fn texture_transform_combos(&self) -> &[u16] {
7038        // SAFETY: `_data`/`_count` describe one contiguous C++
7039        // allocation, borrowed for as long as `self` is.
7040        unsafe {
7041            let n = ffi::whiteout_m2_M2Model_get_textureTransformCombos_count(self.raw.as_ptr());
7042            let p = ffi::whiteout_m2_M2Model_get_textureTransformCombos_data(self.raw.as_ptr());
7043            if p.is_null() || n == 0 {
7044                &[]
7045            } else {
7046                core::slice::from_raw_parts(p, n)
7047            }
7048        }
7049    }
7050
7051    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
7052    pub fn texture_transform_combos_mut(&mut self) -> &mut [u16] {
7053        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
7054        unsafe {
7055            let n = ffi::whiteout_m2_M2Model_get_textureTransformCombos_count(self.raw.as_ptr());
7056            let p = ffi::whiteout_m2_M2Model_get_textureTransformCombos_data(self.raw.as_ptr())
7057                as *mut u16;
7058            if p.is_null() || n == 0 {
7059                &mut []
7060            } else {
7061                core::slice::from_raw_parts_mut(p, n)
7062            }
7063        }
7064    }
7065
7066    pub fn set_texture_transform_combos(&mut self, values: &[u16]) {
7067        // SAFETY: the native side copies `values` before returning.
7068        unsafe {
7069            ffi::whiteout_m2_M2Model_assign_textureTransformCombos(
7070                self.raw.as_ptr(),
7071                values.as_ptr() as *const _,
7072                values.len(),
7073            )
7074        }
7075    }
7076
7077    pub fn resize_texture_transform_combos(&mut self, count: usize) {
7078        // SAFETY: reallocation is safe here precisely because
7079        // `&mut self` means no slice borrow is outstanding.
7080        unsafe { ffi::whiteout_m2_M2Model_resize_textureTransformCombos(self.raw.as_ptr(), count) }
7081    }
7082
7083    /// Borrows the field in place — no copy, no allocation.
7084    pub fn bounding(&self) -> crate::support::Ref<'_, Extent> {
7085        // SAFETY: an interior pointer into `self`, valid for this
7086        // borrow and never freed by the `Ref`.
7087        unsafe {
7088            crate::support::Ref::new(Extent {
7089                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_bounding(
7090                    self.raw.as_ptr(),
7091                )),
7092            })
7093        }
7094    }
7095
7096    pub fn bounding_mut(&mut self) -> crate::support::RefMut<'_, Extent> {
7097        // SAFETY: as above; `&mut self` guarantees exclusivity.
7098        unsafe {
7099            crate::support::RefMut::new(Extent {
7100                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_bounding(
7101                    self.raw.as_ptr(),
7102                )),
7103            })
7104        }
7105    }
7106
7107    /// Borrows the field in place — no copy, no allocation.
7108    pub fn collision(&self) -> crate::support::Ref<'_, Extent> {
7109        // SAFETY: an interior pointer into `self`, valid for this
7110        // borrow and never freed by the `Ref`.
7111        unsafe {
7112            crate::support::Ref::new(Extent {
7113                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_collision(
7114                    self.raw.as_ptr(),
7115                )),
7116            })
7117        }
7118    }
7119
7120    pub fn collision_mut(&mut self) -> crate::support::RefMut<'_, Extent> {
7121        // SAFETY: as above; `&mut self` guarantees exclusivity.
7122        unsafe {
7123            crate::support::RefMut::new(Extent {
7124                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_collision(
7125                    self.raw.as_ptr(),
7126                )),
7127            })
7128        }
7129    }
7130
7131    /// Zero-copy view of the underlying `std::vector`.
7132    pub fn collision_triangle_indices(&self) -> &[u16] {
7133        // SAFETY: `_data`/`_count` describe one contiguous C++
7134        // allocation, borrowed for as long as `self` is.
7135        unsafe {
7136            let n = ffi::whiteout_m2_M2Model_get_collisionTriangleIndices_count(self.raw.as_ptr());
7137            let p = ffi::whiteout_m2_M2Model_get_collisionTriangleIndices_data(self.raw.as_ptr());
7138            if p.is_null() || n == 0 {
7139                &[]
7140            } else {
7141                core::slice::from_raw_parts(p, n)
7142            }
7143        }
7144    }
7145
7146    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
7147    pub fn collision_triangle_indices_mut(&mut self) -> &mut [u16] {
7148        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
7149        unsafe {
7150            let n = ffi::whiteout_m2_M2Model_get_collisionTriangleIndices_count(self.raw.as_ptr());
7151            let p = ffi::whiteout_m2_M2Model_get_collisionTriangleIndices_data(self.raw.as_ptr())
7152                as *mut u16;
7153            if p.is_null() || n == 0 {
7154                &mut []
7155            } else {
7156                core::slice::from_raw_parts_mut(p, n)
7157            }
7158        }
7159    }
7160
7161    pub fn set_collision_triangle_indices(&mut self, values: &[u16]) {
7162        // SAFETY: the native side copies `values` before returning.
7163        unsafe {
7164            ffi::whiteout_m2_M2Model_assign_collisionTriangleIndices(
7165                self.raw.as_ptr(),
7166                values.as_ptr() as *const _,
7167                values.len(),
7168            )
7169        }
7170    }
7171
7172    pub fn resize_collision_triangle_indices(&mut self, count: usize) {
7173        // SAFETY: reallocation is safe here precisely because
7174        // `&mut self` means no slice borrow is outstanding.
7175        unsafe {
7176            ffi::whiteout_m2_M2Model_resize_collisionTriangleIndices(self.raw.as_ptr(), count)
7177        }
7178    }
7179
7180    /// Zero-copy view of the underlying `std::vector`.
7181    pub fn collision_vertices(&self) -> &[crate::math::Vector3f] {
7182        // SAFETY: `_data`/`_count` describe one contiguous C++
7183        // allocation, borrowed for as long as `self` is.
7184        unsafe {
7185            let n = ffi::whiteout_m2_M2Model_get_collisionVertices_count(self.raw.as_ptr());
7186            let p = ffi::whiteout_m2_M2Model_get_collisionVertices_data(self.raw.as_ptr())
7187                as *const crate::math::Vector3f;
7188            if p.is_null() || n == 0 {
7189                &[]
7190            } else {
7191                core::slice::from_raw_parts(p, n)
7192            }
7193        }
7194    }
7195
7196    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
7197    pub fn collision_vertices_mut(&mut self) -> &mut [crate::math::Vector3f] {
7198        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
7199        unsafe {
7200            let n = ffi::whiteout_m2_M2Model_get_collisionVertices_count(self.raw.as_ptr());
7201            let p = ffi::whiteout_m2_M2Model_get_collisionVertices_data(self.raw.as_ptr())
7202                as *const crate::math::Vector3f as *mut crate::math::Vector3f;
7203            if p.is_null() || n == 0 {
7204                &mut []
7205            } else {
7206                core::slice::from_raw_parts_mut(p, n)
7207            }
7208        }
7209    }
7210
7211    pub fn set_collision_vertices(&mut self, values: &[crate::math::Vector3f]) {
7212        // SAFETY: the native side copies `values` before returning.
7213        unsafe {
7214            ffi::whiteout_m2_M2Model_assign_collisionVertices(
7215                self.raw.as_ptr(),
7216                values.as_ptr() as *const _,
7217                values.len(),
7218            )
7219        }
7220    }
7221
7222    pub fn resize_collision_vertices(&mut self, count: usize) {
7223        // SAFETY: reallocation is safe here precisely because
7224        // `&mut self` means no slice borrow is outstanding.
7225        unsafe { ffi::whiteout_m2_M2Model_resize_collisionVertices(self.raw.as_ptr(), count) }
7226    }
7227
7228    /// Zero-copy view of the underlying `std::vector`.
7229    pub fn collision_face_normals(&self) -> &[crate::math::Vector3f] {
7230        // SAFETY: `_data`/`_count` describe one contiguous C++
7231        // allocation, borrowed for as long as `self` is.
7232        unsafe {
7233            let n = ffi::whiteout_m2_M2Model_get_collisionFaceNormals_count(self.raw.as_ptr());
7234            let p = ffi::whiteout_m2_M2Model_get_collisionFaceNormals_data(self.raw.as_ptr())
7235                as *const crate::math::Vector3f;
7236            if p.is_null() || n == 0 {
7237                &[]
7238            } else {
7239                core::slice::from_raw_parts(p, n)
7240            }
7241        }
7242    }
7243
7244    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
7245    pub fn collision_face_normals_mut(&mut self) -> &mut [crate::math::Vector3f] {
7246        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
7247        unsafe {
7248            let n = ffi::whiteout_m2_M2Model_get_collisionFaceNormals_count(self.raw.as_ptr());
7249            let p = ffi::whiteout_m2_M2Model_get_collisionFaceNormals_data(self.raw.as_ptr())
7250                as *const crate::math::Vector3f as *mut crate::math::Vector3f;
7251            if p.is_null() || n == 0 {
7252                &mut []
7253            } else {
7254                core::slice::from_raw_parts_mut(p, n)
7255            }
7256        }
7257    }
7258
7259    pub fn set_collision_face_normals(&mut self, values: &[crate::math::Vector3f]) {
7260        // SAFETY: the native side copies `values` before returning.
7261        unsafe {
7262            ffi::whiteout_m2_M2Model_assign_collisionFaceNormals(
7263                self.raw.as_ptr(),
7264                values.as_ptr() as *const _,
7265                values.len(),
7266            )
7267        }
7268    }
7269
7270    pub fn resize_collision_face_normals(&mut self, count: usize) {
7271        // SAFETY: reallocation is safe here precisely because
7272        // `&mut self` means no slice borrow is outstanding.
7273        unsafe { ffi::whiteout_m2_M2Model_resize_collisionFaceNormals(self.raw.as_ptr(), count) }
7274    }
7275
7276    pub fn attachments_len(&self) -> usize {
7277        // SAFETY: scalar read through a live handle.
7278        unsafe { ffi::whiteout_m2_M2Model_get_attachments_count(self.raw.as_ptr()) }
7279    }
7280
7281    /// Borrows element `index` in place. `None` when out of range.
7282    pub fn attachments(&self, index: usize) -> Option<crate::support::Ref<'_, Attachment>> {
7283        if index >= self.attachments_len() {
7284            return None;
7285        }
7286        // SAFETY: index checked above; the pointer is interior to `self`.
7287        unsafe {
7288            Some(crate::support::Ref::new(Attachment {
7289                raw: core::ptr::NonNull::new_unchecked(
7290                    ffi::whiteout_m2_M2Model_get_attachments_at(self.raw.as_ptr(), index),
7291                ),
7292            }))
7293        }
7294    }
7295
7296    pub fn attachments_mut(
7297        &mut self,
7298        index: usize,
7299    ) -> Option<crate::support::RefMut<'_, Attachment>> {
7300        if index >= self.attachments_len() {
7301            return None;
7302        }
7303        // SAFETY: as above; `&mut self` guarantees exclusivity.
7304        unsafe {
7305            Some(crate::support::RefMut::new(Attachment {
7306                raw: core::ptr::NonNull::new_unchecked(
7307                    ffi::whiteout_m2_M2Model_get_attachments_at(self.raw.as_ptr(), index),
7308                ),
7309            }))
7310        }
7311    }
7312
7313    /// Iterate the elements, borrowing each in turn.
7314    pub fn attachments_iter(
7315        &self,
7316    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, Attachment>> {
7317        (0..self.attachments_len()).map(move |i| self.attachments(i).expect("index below len"))
7318    }
7319
7320    pub fn resize_attachments(&mut self, count: usize) {
7321        // SAFETY: exclusive access, so no borrow is outstanding.
7322        unsafe { ffi::whiteout_m2_M2Model_resize_attachments(self.raw.as_ptr(), count) }
7323    }
7324
7325    /// Zero-copy view of the underlying `std::vector`.
7326    pub fn attachment_indices_by_id(&self) -> &[u16] {
7327        // SAFETY: `_data`/`_count` describe one contiguous C++
7328        // allocation, borrowed for as long as `self` is.
7329        unsafe {
7330            let n = ffi::whiteout_m2_M2Model_get_attachmentIndicesById_count(self.raw.as_ptr());
7331            let p = ffi::whiteout_m2_M2Model_get_attachmentIndicesById_data(self.raw.as_ptr());
7332            if p.is_null() || n == 0 {
7333                &[]
7334            } else {
7335                core::slice::from_raw_parts(p, n)
7336            }
7337        }
7338    }
7339
7340    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
7341    pub fn attachment_indices_by_id_mut(&mut self) -> &mut [u16] {
7342        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
7343        unsafe {
7344            let n = ffi::whiteout_m2_M2Model_get_attachmentIndicesById_count(self.raw.as_ptr());
7345            let p = ffi::whiteout_m2_M2Model_get_attachmentIndicesById_data(self.raw.as_ptr())
7346                as *mut u16;
7347            if p.is_null() || n == 0 {
7348                &mut []
7349            } else {
7350                core::slice::from_raw_parts_mut(p, n)
7351            }
7352        }
7353    }
7354
7355    pub fn set_attachment_indices_by_id(&mut self, values: &[u16]) {
7356        // SAFETY: the native side copies `values` before returning.
7357        unsafe {
7358            ffi::whiteout_m2_M2Model_assign_attachmentIndicesById(
7359                self.raw.as_ptr(),
7360                values.as_ptr() as *const _,
7361                values.len(),
7362            )
7363        }
7364    }
7365
7366    pub fn resize_attachment_indices_by_id(&mut self, count: usize) {
7367        // SAFETY: reallocation is safe here precisely because
7368        // `&mut self` means no slice borrow is outstanding.
7369        unsafe { ffi::whiteout_m2_M2Model_resize_attachmentIndicesById(self.raw.as_ptr(), count) }
7370    }
7371
7372    pub fn events_len(&self) -> usize {
7373        // SAFETY: scalar read through a live handle.
7374        unsafe { ffi::whiteout_m2_M2Model_get_events_count(self.raw.as_ptr()) }
7375    }
7376
7377    /// Borrows element `index` in place. `None` when out of range.
7378    pub fn events(&self, index: usize) -> Option<crate::support::Ref<'_, Event>> {
7379        if index >= self.events_len() {
7380            return None;
7381        }
7382        // SAFETY: index checked above; the pointer is interior to `self`.
7383        unsafe {
7384            Some(crate::support::Ref::new(Event {
7385                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_events_at(
7386                    self.raw.as_ptr(),
7387                    index,
7388                )),
7389            }))
7390        }
7391    }
7392
7393    pub fn events_mut(&mut self, index: usize) -> Option<crate::support::RefMut<'_, Event>> {
7394        if index >= self.events_len() {
7395            return None;
7396        }
7397        // SAFETY: as above; `&mut self` guarantees exclusivity.
7398        unsafe {
7399            Some(crate::support::RefMut::new(Event {
7400                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_events_at(
7401                    self.raw.as_ptr(),
7402                    index,
7403                )),
7404            }))
7405        }
7406    }
7407
7408    /// Iterate the elements, borrowing each in turn.
7409    pub fn events_iter(&self) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, Event>> {
7410        (0..self.events_len()).map(move |i| self.events(i).expect("index below len"))
7411    }
7412
7413    pub fn resize_events(&mut self, count: usize) {
7414        // SAFETY: exclusive access, so no borrow is outstanding.
7415        unsafe { ffi::whiteout_m2_M2Model_resize_events(self.raw.as_ptr(), count) }
7416    }
7417
7418    pub fn lights_len(&self) -> usize {
7419        // SAFETY: scalar read through a live handle.
7420        unsafe { ffi::whiteout_m2_M2Model_get_lights_count(self.raw.as_ptr()) }
7421    }
7422
7423    /// Borrows element `index` in place. `None` when out of range.
7424    pub fn lights(&self, index: usize) -> Option<crate::support::Ref<'_, Light>> {
7425        if index >= self.lights_len() {
7426            return None;
7427        }
7428        // SAFETY: index checked above; the pointer is interior to `self`.
7429        unsafe {
7430            Some(crate::support::Ref::new(Light {
7431                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_lights_at(
7432                    self.raw.as_ptr(),
7433                    index,
7434                )),
7435            }))
7436        }
7437    }
7438
7439    pub fn lights_mut(&mut self, index: usize) -> Option<crate::support::RefMut<'_, Light>> {
7440        if index >= self.lights_len() {
7441            return None;
7442        }
7443        // SAFETY: as above; `&mut self` guarantees exclusivity.
7444        unsafe {
7445            Some(crate::support::RefMut::new(Light {
7446                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_lights_at(
7447                    self.raw.as_ptr(),
7448                    index,
7449                )),
7450            }))
7451        }
7452    }
7453
7454    /// Iterate the elements, borrowing each in turn.
7455    pub fn lights_iter(&self) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, Light>> {
7456        (0..self.lights_len()).map(move |i| self.lights(i).expect("index below len"))
7457    }
7458
7459    pub fn resize_lights(&mut self, count: usize) {
7460        // SAFETY: exclusive access, so no borrow is outstanding.
7461        unsafe { ffi::whiteout_m2_M2Model_resize_lights(self.raw.as_ptr(), count) }
7462    }
7463
7464    pub fn cameras_len(&self) -> usize {
7465        // SAFETY: scalar read through a live handle.
7466        unsafe { ffi::whiteout_m2_M2Model_get_cameras_count(self.raw.as_ptr()) }
7467    }
7468
7469    /// Borrows element `index` in place. `None` when out of range.
7470    pub fn cameras(&self, index: usize) -> Option<crate::support::Ref<'_, Camera>> {
7471        if index >= self.cameras_len() {
7472            return None;
7473        }
7474        // SAFETY: index checked above; the pointer is interior to `self`.
7475        unsafe {
7476            Some(crate::support::Ref::new(Camera {
7477                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_cameras_at(
7478                    self.raw.as_ptr(),
7479                    index,
7480                )),
7481            }))
7482        }
7483    }
7484
7485    pub fn cameras_mut(&mut self, index: usize) -> Option<crate::support::RefMut<'_, Camera>> {
7486        if index >= self.cameras_len() {
7487            return None;
7488        }
7489        // SAFETY: as above; `&mut self` guarantees exclusivity.
7490        unsafe {
7491            Some(crate::support::RefMut::new(Camera {
7492                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_cameras_at(
7493                    self.raw.as_ptr(),
7494                    index,
7495                )),
7496            }))
7497        }
7498    }
7499
7500    /// Iterate the elements, borrowing each in turn.
7501    pub fn cameras_iter(&self) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, Camera>> {
7502        (0..self.cameras_len()).map(move |i| self.cameras(i).expect("index below len"))
7503    }
7504
7505    pub fn resize_cameras(&mut self, count: usize) {
7506        // SAFETY: exclusive access, so no borrow is outstanding.
7507        unsafe { ffi::whiteout_m2_M2Model_resize_cameras(self.raw.as_ptr(), count) }
7508    }
7509
7510    /// Zero-copy view of the underlying `std::vector`.
7511    pub fn camera_indices_by_id(&self) -> &[u16] {
7512        // SAFETY: `_data`/`_count` describe one contiguous C++
7513        // allocation, borrowed for as long as `self` is.
7514        unsafe {
7515            let n = ffi::whiteout_m2_M2Model_get_cameraIndicesById_count(self.raw.as_ptr());
7516            let p = ffi::whiteout_m2_M2Model_get_cameraIndicesById_data(self.raw.as_ptr());
7517            if p.is_null() || n == 0 {
7518                &[]
7519            } else {
7520                core::slice::from_raw_parts(p, n)
7521            }
7522        }
7523    }
7524
7525    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
7526    pub fn camera_indices_by_id_mut(&mut self) -> &mut [u16] {
7527        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
7528        unsafe {
7529            let n = ffi::whiteout_m2_M2Model_get_cameraIndicesById_count(self.raw.as_ptr());
7530            let p =
7531                ffi::whiteout_m2_M2Model_get_cameraIndicesById_data(self.raw.as_ptr()) as *mut u16;
7532            if p.is_null() || n == 0 {
7533                &mut []
7534            } else {
7535                core::slice::from_raw_parts_mut(p, n)
7536            }
7537        }
7538    }
7539
7540    pub fn set_camera_indices_by_id(&mut self, values: &[u16]) {
7541        // SAFETY: the native side copies `values` before returning.
7542        unsafe {
7543            ffi::whiteout_m2_M2Model_assign_cameraIndicesById(
7544                self.raw.as_ptr(),
7545                values.as_ptr() as *const _,
7546                values.len(),
7547            )
7548        }
7549    }
7550
7551    pub fn resize_camera_indices_by_id(&mut self, count: usize) {
7552        // SAFETY: reallocation is safe here precisely because
7553        // `&mut self` means no slice borrow is outstanding.
7554        unsafe { ffi::whiteout_m2_M2Model_resize_cameraIndicesById(self.raw.as_ptr(), count) }
7555    }
7556
7557    pub fn ribbon_emitters_len(&self) -> usize {
7558        // SAFETY: scalar read through a live handle.
7559        unsafe { ffi::whiteout_m2_M2Model_get_ribbonEmitters_count(self.raw.as_ptr()) }
7560    }
7561
7562    /// Borrows element `index` in place. `None` when out of range.
7563    pub fn ribbon_emitters(&self, index: usize) -> Option<crate::support::Ref<'_, RibbonEmitter>> {
7564        if index >= self.ribbon_emitters_len() {
7565            return None;
7566        }
7567        // SAFETY: index checked above; the pointer is interior to `self`.
7568        unsafe {
7569            Some(crate::support::Ref::new(RibbonEmitter {
7570                raw: core::ptr::NonNull::new_unchecked(
7571                    ffi::whiteout_m2_M2Model_get_ribbonEmitters_at(self.raw.as_ptr(), index),
7572                ),
7573            }))
7574        }
7575    }
7576
7577    pub fn ribbon_emitters_mut(
7578        &mut self,
7579        index: usize,
7580    ) -> Option<crate::support::RefMut<'_, RibbonEmitter>> {
7581        if index >= self.ribbon_emitters_len() {
7582            return None;
7583        }
7584        // SAFETY: as above; `&mut self` guarantees exclusivity.
7585        unsafe {
7586            Some(crate::support::RefMut::new(RibbonEmitter {
7587                raw: core::ptr::NonNull::new_unchecked(
7588                    ffi::whiteout_m2_M2Model_get_ribbonEmitters_at(self.raw.as_ptr(), index),
7589                ),
7590            }))
7591        }
7592    }
7593
7594    /// Iterate the elements, borrowing each in turn.
7595    pub fn ribbon_emitters_iter(
7596        &self,
7597    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, RibbonEmitter>> {
7598        (0..self.ribbon_emitters_len())
7599            .map(move |i| self.ribbon_emitters(i).expect("index below len"))
7600    }
7601
7602    pub fn resize_ribbon_emitters(&mut self, count: usize) {
7603        // SAFETY: exclusive access, so no borrow is outstanding.
7604        unsafe { ffi::whiteout_m2_M2Model_resize_ribbonEmitters(self.raw.as_ptr(), count) }
7605    }
7606
7607    pub fn particle_emitters_len(&self) -> usize {
7608        // SAFETY: scalar read through a live handle.
7609        unsafe { ffi::whiteout_m2_M2Model_get_particleEmitters_count(self.raw.as_ptr()) }
7610    }
7611
7612    /// Borrows element `index` in place. `None` when out of range.
7613    pub fn particle_emitters(
7614        &self,
7615        index: usize,
7616    ) -> Option<crate::support::Ref<'_, ParticleEmitter>> {
7617        if index >= self.particle_emitters_len() {
7618            return None;
7619        }
7620        // SAFETY: index checked above; the pointer is interior to `self`.
7621        unsafe {
7622            Some(crate::support::Ref::new(ParticleEmitter {
7623                raw: core::ptr::NonNull::new_unchecked(
7624                    ffi::whiteout_m2_M2Model_get_particleEmitters_at(self.raw.as_ptr(), index),
7625                ),
7626            }))
7627        }
7628    }
7629
7630    pub fn particle_emitters_mut(
7631        &mut self,
7632        index: usize,
7633    ) -> Option<crate::support::RefMut<'_, ParticleEmitter>> {
7634        if index >= self.particle_emitters_len() {
7635            return None;
7636        }
7637        // SAFETY: as above; `&mut self` guarantees exclusivity.
7638        unsafe {
7639            Some(crate::support::RefMut::new(ParticleEmitter {
7640                raw: core::ptr::NonNull::new_unchecked(
7641                    ffi::whiteout_m2_M2Model_get_particleEmitters_at(self.raw.as_ptr(), index),
7642                ),
7643            }))
7644        }
7645    }
7646
7647    /// Iterate the elements, borrowing each in turn.
7648    pub fn particle_emitters_iter(
7649        &self,
7650    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, ParticleEmitter>> {
7651        (0..self.particle_emitters_len())
7652            .map(move |i| self.particle_emitters(i).expect("index below len"))
7653    }
7654
7655    pub fn resize_particle_emitters(&mut self, count: usize) {
7656        // SAFETY: exclusive access, so no borrow is outstanding.
7657        unsafe { ffi::whiteout_m2_M2Model_resize_particleEmitters(self.raw.as_ptr(), count) }
7658    }
7659
7660    /// Zero-copy view of the underlying `std::vector`.
7661    pub fn texture_combiner_combos(&self) -> &[u16] {
7662        // SAFETY: `_data`/`_count` describe one contiguous C++
7663        // allocation, borrowed for as long as `self` is.
7664        unsafe {
7665            let n = ffi::whiteout_m2_M2Model_get_textureCombinerCombos_count(self.raw.as_ptr());
7666            let p = ffi::whiteout_m2_M2Model_get_textureCombinerCombos_data(self.raw.as_ptr());
7667            if p.is_null() || n == 0 {
7668                &[]
7669            } else {
7670                core::slice::from_raw_parts(p, n)
7671            }
7672        }
7673    }
7674
7675    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
7676    pub fn texture_combiner_combos_mut(&mut self) -> &mut [u16] {
7677        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
7678        unsafe {
7679            let n = ffi::whiteout_m2_M2Model_get_textureCombinerCombos_count(self.raw.as_ptr());
7680            let p = ffi::whiteout_m2_M2Model_get_textureCombinerCombos_data(self.raw.as_ptr())
7681                as *mut u16;
7682            if p.is_null() || n == 0 {
7683                &mut []
7684            } else {
7685                core::slice::from_raw_parts_mut(p, n)
7686            }
7687        }
7688    }
7689
7690    pub fn set_texture_combiner_combos(&mut self, values: &[u16]) {
7691        // SAFETY: the native side copies `values` before returning.
7692        unsafe {
7693            ffi::whiteout_m2_M2Model_assign_textureCombinerCombos(
7694                self.raw.as_ptr(),
7695                values.as_ptr() as *const _,
7696                values.len(),
7697            )
7698        }
7699    }
7700
7701    pub fn resize_texture_combiner_combos(&mut self, count: usize) {
7702        // SAFETY: reallocation is safe here precisely because
7703        // `&mut self` means no slice borrow is outstanding.
7704        unsafe { ffi::whiteout_m2_M2Model_resize_textureCombinerCombos(self.raw.as_ptr(), count) }
7705    }
7706
7707    /// TXID
7708    /// Zero-copy view of the underlying `std::vector`.
7709    pub fn texture_ids(&self) -> &[u32] {
7710        // SAFETY: `_data`/`_count` describe one contiguous C++
7711        // allocation, borrowed for as long as `self` is.
7712        unsafe {
7713            let n = ffi::whiteout_m2_M2Model_get_texture_ids_count(self.raw.as_ptr());
7714            let p = ffi::whiteout_m2_M2Model_get_texture_ids_data(self.raw.as_ptr());
7715            if p.is_null() || n == 0 {
7716                &[]
7717            } else {
7718                core::slice::from_raw_parts(p, n)
7719            }
7720        }
7721    }
7722
7723    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
7724    pub fn texture_ids_mut(&mut self) -> &mut [u32] {
7725        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
7726        unsafe {
7727            let n = ffi::whiteout_m2_M2Model_get_texture_ids_count(self.raw.as_ptr());
7728            let p = ffi::whiteout_m2_M2Model_get_texture_ids_data(self.raw.as_ptr()) as *mut u32;
7729            if p.is_null() || n == 0 {
7730                &mut []
7731            } else {
7732                core::slice::from_raw_parts_mut(p, n)
7733            }
7734        }
7735    }
7736
7737    pub fn set_texture_ids(&mut self, values: &[u32]) {
7738        // SAFETY: the native side copies `values` before returning.
7739        unsafe {
7740            ffi::whiteout_m2_M2Model_assign_texture_ids(
7741                self.raw.as_ptr(),
7742                values.as_ptr() as *const _,
7743                values.len(),
7744            )
7745        }
7746    }
7747
7748    pub fn resize_texture_ids(&mut self, count: usize) {
7749        // SAFETY: reallocation is safe here precisely because
7750        // `&mut self` means no slice borrow is outstanding.
7751        unsafe { ffi::whiteout_m2_M2Model_resize_texture_ids(self.raw.as_ptr(), count) }
7752    }
7753
7754    /// PABC
7755    /// Zero-copy view of the underlying `std::vector`.
7756    pub fn parent_sequence_replacements(&self) -> &[u16] {
7757        // SAFETY: `_data`/`_count` describe one contiguous C++
7758        // allocation, borrowed for as long as `self` is.
7759        unsafe {
7760            let n =
7761                ffi::whiteout_m2_M2Model_get_parentSequenceReplacements_count(self.raw.as_ptr());
7762            let p = ffi::whiteout_m2_M2Model_get_parentSequenceReplacements_data(self.raw.as_ptr());
7763            if p.is_null() || n == 0 {
7764                &[]
7765            } else {
7766                core::slice::from_raw_parts(p, n)
7767            }
7768        }
7769    }
7770
7771    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
7772    pub fn parent_sequence_replacements_mut(&mut self) -> &mut [u16] {
7773        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
7774        unsafe {
7775            let n =
7776                ffi::whiteout_m2_M2Model_get_parentSequenceReplacements_count(self.raw.as_ptr());
7777            let p = ffi::whiteout_m2_M2Model_get_parentSequenceReplacements_data(self.raw.as_ptr())
7778                as *mut u16;
7779            if p.is_null() || n == 0 {
7780                &mut []
7781            } else {
7782                core::slice::from_raw_parts_mut(p, n)
7783            }
7784        }
7785    }
7786
7787    pub fn set_parent_sequence_replacements(&mut self, values: &[u16]) {
7788        // SAFETY: the native side copies `values` before returning.
7789        unsafe {
7790            ffi::whiteout_m2_M2Model_assign_parentSequenceReplacements(
7791                self.raw.as_ptr(),
7792                values.as_ptr() as *const _,
7793                values.len(),
7794            )
7795        }
7796    }
7797
7798    pub fn resize_parent_sequence_replacements(&mut self, count: usize) {
7799        // SAFETY: reallocation is safe here precisely because
7800        // `&mut self` means no slice borrow is outstanding.
7801        unsafe {
7802            ffi::whiteout_m2_M2Model_resize_parentSequenceReplacements(self.raw.as_ptr(), count)
7803        }
7804    }
7805
7806    /// PADC
7807    pub fn parent_texture_weights_len(&self) -> usize {
7808        // SAFETY: scalar read through a live handle.
7809        unsafe { ffi::whiteout_m2_M2Model_get_parentTextureWeights_count(self.raw.as_ptr()) }
7810    }
7811
7812    /// Borrows element `index` in place. `None` when out of range.
7813    pub fn parent_texture_weights(
7814        &self,
7815        index: usize,
7816    ) -> Option<crate::support::Ref<'_, TextureWeight>> {
7817        if index >= self.parent_texture_weights_len() {
7818            return None;
7819        }
7820        // SAFETY: index checked above; the pointer is interior to `self`.
7821        unsafe {
7822            Some(crate::support::Ref::new(TextureWeight {
7823                raw: core::ptr::NonNull::new_unchecked(
7824                    ffi::whiteout_m2_M2Model_get_parentTextureWeights_at(self.raw.as_ptr(), index),
7825                ),
7826            }))
7827        }
7828    }
7829
7830    pub fn parent_texture_weights_mut(
7831        &mut self,
7832        index: usize,
7833    ) -> Option<crate::support::RefMut<'_, TextureWeight>> {
7834        if index >= self.parent_texture_weights_len() {
7835            return None;
7836        }
7837        // SAFETY: as above; `&mut self` guarantees exclusivity.
7838        unsafe {
7839            Some(crate::support::RefMut::new(TextureWeight {
7840                raw: core::ptr::NonNull::new_unchecked(
7841                    ffi::whiteout_m2_M2Model_get_parentTextureWeights_at(self.raw.as_ptr(), index),
7842                ),
7843            }))
7844        }
7845    }
7846
7847    /// Iterate the elements, borrowing each in turn.
7848    pub fn parent_texture_weights_iter(
7849        &self,
7850    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, TextureWeight>> {
7851        (0..self.parent_texture_weights_len())
7852            .map(move |i| self.parent_texture_weights(i).expect("index below len"))
7853    }
7854
7855    pub fn resize_parent_texture_weights(&mut self, count: usize) {
7856        // SAFETY: exclusive access, so no borrow is outstanding.
7857        unsafe { ffi::whiteout_m2_M2Model_resize_parentTextureWeights(self.raw.as_ptr(), count) }
7858    }
7859
7860    /// PSBC
7861    pub fn parent_sequence_bounds_len(&self) -> usize {
7862        // SAFETY: scalar read through a live handle.
7863        unsafe { ffi::whiteout_m2_M2Model_get_parentSequenceBounds_count(self.raw.as_ptr()) }
7864    }
7865
7866    /// Borrows element `index` in place. `None` when out of range.
7867    pub fn parent_sequence_bounds(&self, index: usize) -> Option<crate::support::Ref<'_, Extent>> {
7868        if index >= self.parent_sequence_bounds_len() {
7869            return None;
7870        }
7871        // SAFETY: index checked above; the pointer is interior to `self`.
7872        unsafe {
7873            Some(crate::support::Ref::new(Extent {
7874                raw: core::ptr::NonNull::new_unchecked(
7875                    ffi::whiteout_m2_M2Model_get_parentSequenceBounds_at(self.raw.as_ptr(), index),
7876                ),
7877            }))
7878        }
7879    }
7880
7881    pub fn parent_sequence_bounds_mut(
7882        &mut self,
7883        index: usize,
7884    ) -> Option<crate::support::RefMut<'_, Extent>> {
7885        if index >= self.parent_sequence_bounds_len() {
7886            return None;
7887        }
7888        // SAFETY: as above; `&mut self` guarantees exclusivity.
7889        unsafe {
7890            Some(crate::support::RefMut::new(Extent {
7891                raw: core::ptr::NonNull::new_unchecked(
7892                    ffi::whiteout_m2_M2Model_get_parentSequenceBounds_at(self.raw.as_ptr(), index),
7893                ),
7894            }))
7895        }
7896    }
7897
7898    /// Iterate the elements, borrowing each in turn.
7899    pub fn parent_sequence_bounds_iter(
7900        &self,
7901    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, Extent>> {
7902        (0..self.parent_sequence_bounds_len())
7903            .map(move |i| self.parent_sequence_bounds(i).expect("index below len"))
7904    }
7905
7906    pub fn resize_parent_sequence_bounds(&mut self, count: usize) {
7907        // SAFETY: exclusive access, so no borrow is outstanding.
7908        unsafe { ffi::whiteout_m2_M2Model_resize_parentSequenceBounds(self.raw.as_ptr(), count) }
7909    }
7910
7911    /// PEDC
7912    pub fn parent_event_data_len(&self) -> usize {
7913        // SAFETY: scalar read through a live handle.
7914        unsafe { ffi::whiteout_m2_M2Model_get_parentEventData_count(self.raw.as_ptr()) }
7915    }
7916
7917    /// Borrows element `index` in place. `None` when out of range.
7918    pub fn parent_event_data(
7919        &self,
7920        index: usize,
7921    ) -> Option<crate::support::Ref<'_, AnimationTrackBase>> {
7922        if index >= self.parent_event_data_len() {
7923            return None;
7924        }
7925        // SAFETY: index checked above; the pointer is interior to `self`.
7926        unsafe {
7927            Some(crate::support::Ref::new(AnimationTrackBase {
7928                raw: core::ptr::NonNull::new_unchecked(
7929                    ffi::whiteout_m2_M2Model_get_parentEventData_at(self.raw.as_ptr(), index),
7930                ),
7931            }))
7932        }
7933    }
7934
7935    pub fn parent_event_data_mut(
7936        &mut self,
7937        index: usize,
7938    ) -> Option<crate::support::RefMut<'_, AnimationTrackBase>> {
7939        if index >= self.parent_event_data_len() {
7940            return None;
7941        }
7942        // SAFETY: as above; `&mut self` guarantees exclusivity.
7943        unsafe {
7944            Some(crate::support::RefMut::new(AnimationTrackBase {
7945                raw: core::ptr::NonNull::new_unchecked(
7946                    ffi::whiteout_m2_M2Model_get_parentEventData_at(self.raw.as_ptr(), index),
7947                ),
7948            }))
7949        }
7950    }
7951
7952    /// Iterate the elements, borrowing each in turn.
7953    pub fn parent_event_data_iter(
7954        &self,
7955    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, AnimationTrackBase>> {
7956        (0..self.parent_event_data_len())
7957            .map(move |i| self.parent_event_data(i).expect("index below len"))
7958    }
7959
7960    pub fn resize_parent_event_data(&mut self, count: usize) {
7961        // SAFETY: exclusive access, so no borrow is outstanding.
7962        unsafe { ffi::whiteout_m2_M2Model_resize_parentEventData(self.raw.as_ptr(), count) }
7963    }
7964
7965    /// RPID
7966    /// Zero-copy view of the underlying `std::vector`.
7967    pub fn recursive_particle_model_ids(&self) -> &[u32] {
7968        // SAFETY: `_data`/`_count` describe one contiguous C++
7969        // allocation, borrowed for as long as `self` is.
7970        unsafe {
7971            let n = ffi::whiteout_m2_M2Model_get_recursiveParticleModelIds_count(self.raw.as_ptr());
7972            let p = ffi::whiteout_m2_M2Model_get_recursiveParticleModelIds_data(self.raw.as_ptr());
7973            if p.is_null() || n == 0 {
7974                &[]
7975            } else {
7976                core::slice::from_raw_parts(p, n)
7977            }
7978        }
7979    }
7980
7981    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
7982    pub fn recursive_particle_model_ids_mut(&mut self) -> &mut [u32] {
7983        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
7984        unsafe {
7985            let n = ffi::whiteout_m2_M2Model_get_recursiveParticleModelIds_count(self.raw.as_ptr());
7986            let p = ffi::whiteout_m2_M2Model_get_recursiveParticleModelIds_data(self.raw.as_ptr())
7987                as *mut u32;
7988            if p.is_null() || n == 0 {
7989                &mut []
7990            } else {
7991                core::slice::from_raw_parts_mut(p, n)
7992            }
7993        }
7994    }
7995
7996    pub fn set_recursive_particle_model_ids(&mut self, values: &[u32]) {
7997        // SAFETY: the native side copies `values` before returning.
7998        unsafe {
7999            ffi::whiteout_m2_M2Model_assign_recursiveParticleModelIds(
8000                self.raw.as_ptr(),
8001                values.as_ptr() as *const _,
8002                values.len(),
8003            )
8004        }
8005    }
8006
8007    pub fn resize_recursive_particle_model_ids(&mut self, count: usize) {
8008        // SAFETY: reallocation is safe here precisely because
8009        // `&mut self` means no slice borrow is outstanding.
8010        unsafe {
8011            ffi::whiteout_m2_M2Model_resize_recursiveParticleModelIds(self.raw.as_ptr(), count)
8012        }
8013    }
8014
8015    /// GPID
8016    /// Zero-copy view of the underlying `std::vector`.
8017    pub fn geometry_particle_model_ids(&self) -> &[u32] {
8018        // SAFETY: `_data`/`_count` describe one contiguous C++
8019        // allocation, borrowed for as long as `self` is.
8020        unsafe {
8021            let n = ffi::whiteout_m2_M2Model_get_geometryParticleModelIds_count(self.raw.as_ptr());
8022            let p = ffi::whiteout_m2_M2Model_get_geometryParticleModelIds_data(self.raw.as_ptr());
8023            if p.is_null() || n == 0 {
8024                &[]
8025            } else {
8026                core::slice::from_raw_parts(p, n)
8027            }
8028        }
8029    }
8030
8031    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
8032    pub fn geometry_particle_model_ids_mut(&mut self) -> &mut [u32] {
8033        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
8034        unsafe {
8035            let n = ffi::whiteout_m2_M2Model_get_geometryParticleModelIds_count(self.raw.as_ptr());
8036            let p = ffi::whiteout_m2_M2Model_get_geometryParticleModelIds_data(self.raw.as_ptr())
8037                as *mut u32;
8038            if p.is_null() || n == 0 {
8039                &mut []
8040            } else {
8041                core::slice::from_raw_parts_mut(p, n)
8042            }
8043        }
8044    }
8045
8046    pub fn set_geometry_particle_model_ids(&mut self, values: &[u32]) {
8047        // SAFETY: the native side copies `values` before returning.
8048        unsafe {
8049            ffi::whiteout_m2_M2Model_assign_geometryParticleModelIds(
8050                self.raw.as_ptr(),
8051                values.as_ptr() as *const _,
8052                values.len(),
8053            )
8054        }
8055    }
8056
8057    pub fn resize_geometry_particle_model_ids(&mut self, count: usize) {
8058        // SAFETY: reallocation is safe here precisely because
8059        // `&mut self` means no slice borrow is outstanding.
8060        unsafe {
8061            ffi::whiteout_m2_M2Model_resize_geometryParticleModelIds(self.raw.as_ptr(), count)
8062        }
8063    }
8064
8065    /// PGD1
8066    pub fn particle_geosets_len(&self) -> usize {
8067        // SAFETY: scalar read through a live handle.
8068        unsafe { ffi::whiteout_m2_M2Model_get_particleGeosets_count(self.raw.as_ptr()) }
8069    }
8070
8071    /// Borrows element `index` in place. `None` when out of range.
8072    pub fn particle_geosets(
8073        &self,
8074        index: usize,
8075    ) -> Option<crate::support::Ref<'_, ParticleGeosetData>> {
8076        if index >= self.particle_geosets_len() {
8077            return None;
8078        }
8079        // SAFETY: index checked above; the pointer is interior to `self`.
8080        unsafe {
8081            Some(crate::support::Ref::new(ParticleGeosetData {
8082                raw: core::ptr::NonNull::new_unchecked(
8083                    ffi::whiteout_m2_M2Model_get_particleGeosets_at(self.raw.as_ptr(), index),
8084                ),
8085            }))
8086        }
8087    }
8088
8089    pub fn particle_geosets_mut(
8090        &mut self,
8091        index: usize,
8092    ) -> Option<crate::support::RefMut<'_, ParticleGeosetData>> {
8093        if index >= self.particle_geosets_len() {
8094            return None;
8095        }
8096        // SAFETY: as above; `&mut self` guarantees exclusivity.
8097        unsafe {
8098            Some(crate::support::RefMut::new(ParticleGeosetData {
8099                raw: core::ptr::NonNull::new_unchecked(
8100                    ffi::whiteout_m2_M2Model_get_particleGeosets_at(self.raw.as_ptr(), index),
8101                ),
8102            }))
8103        }
8104    }
8105
8106    /// Iterate the elements, borrowing each in turn.
8107    pub fn particle_geosets_iter(
8108        &self,
8109    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, ParticleGeosetData>> {
8110        (0..self.particle_geosets_len())
8111            .map(move |i| self.particle_geosets(i).expect("index below len"))
8112    }
8113
8114    pub fn resize_particle_geosets(&mut self, count: usize) {
8115        // SAFETY: exclusive access, so no borrow is outstanding.
8116        unsafe { ffi::whiteout_m2_M2Model_resize_particleGeosets(self.raw.as_ptr(), count) }
8117    }
8118
8119    /// PFDC
8120    /// Zero-copy view of the underlying `std::vector`.
8121    pub fn physics_file_data(&self) -> &[u8] {
8122        // SAFETY: `_data`/`_count` describe one contiguous C++
8123        // allocation, borrowed for as long as `self` is.
8124        unsafe {
8125            let n = ffi::whiteout_m2_M2Model_get_physicsFileData_count(self.raw.as_ptr());
8126            let p = ffi::whiteout_m2_M2Model_get_physicsFileData_data(self.raw.as_ptr());
8127            if p.is_null() || n == 0 {
8128                &[]
8129            } else {
8130                core::slice::from_raw_parts(p, n)
8131            }
8132        }
8133    }
8134
8135    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
8136    pub fn physics_file_data_mut(&mut self) -> &mut [u8] {
8137        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
8138        unsafe {
8139            let n = ffi::whiteout_m2_M2Model_get_physicsFileData_count(self.raw.as_ptr());
8140            let p = ffi::whiteout_m2_M2Model_get_physicsFileData_data(self.raw.as_ptr()) as *mut u8;
8141            if p.is_null() || n == 0 {
8142                &mut []
8143            } else {
8144                core::slice::from_raw_parts_mut(p, n)
8145            }
8146        }
8147    }
8148
8149    pub fn set_physics_file_data(&mut self, values: &[u8]) {
8150        // SAFETY: the native side copies `values` before returning.
8151        unsafe {
8152            ffi::whiteout_m2_M2Model_assign_physicsFileData(
8153                self.raw.as_ptr(),
8154                values.as_ptr() as *const _,
8155                values.len(),
8156            )
8157        }
8158    }
8159
8160    pub fn resize_physics_file_data(&mut self, count: usize) {
8161        // SAFETY: reallocation is safe here precisely because
8162        // `&mut self` means no slice borrow is outstanding.
8163        unsafe { ffi::whiteout_m2_M2Model_resize_physicsFileData(self.raw.as_ptr(), count) }
8164    }
8165
8166    /// EDGF
8167    pub fn edge_fade_entries_len(&self) -> usize {
8168        // SAFETY: scalar read through a live handle.
8169        unsafe { ffi::whiteout_m2_M2Model_get_edgeFadeEntries_count(self.raw.as_ptr()) }
8170    }
8171
8172    /// Borrows element `index` in place. `None` when out of range.
8173    pub fn edge_fade_entries(&self, index: usize) -> Option<crate::support::Ref<'_, EdgeFadeData>> {
8174        if index >= self.edge_fade_entries_len() {
8175            return None;
8176        }
8177        // SAFETY: index checked above; the pointer is interior to `self`.
8178        unsafe {
8179            Some(crate::support::Ref::new(EdgeFadeData {
8180                raw: core::ptr::NonNull::new_unchecked(
8181                    ffi::whiteout_m2_M2Model_get_edgeFadeEntries_at(self.raw.as_ptr(), index),
8182                ),
8183            }))
8184        }
8185    }
8186
8187    pub fn edge_fade_entries_mut(
8188        &mut self,
8189        index: usize,
8190    ) -> Option<crate::support::RefMut<'_, EdgeFadeData>> {
8191        if index >= self.edge_fade_entries_len() {
8192            return None;
8193        }
8194        // SAFETY: as above; `&mut self` guarantees exclusivity.
8195        unsafe {
8196            Some(crate::support::RefMut::new(EdgeFadeData {
8197                raw: core::ptr::NonNull::new_unchecked(
8198                    ffi::whiteout_m2_M2Model_get_edgeFadeEntries_at(self.raw.as_ptr(), index),
8199                ),
8200            }))
8201        }
8202    }
8203
8204    /// Iterate the elements, borrowing each in turn.
8205    pub fn edge_fade_entries_iter(
8206        &self,
8207    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, EdgeFadeData>> {
8208        (0..self.edge_fade_entries_len())
8209            .map(move |i| self.edge_fade_entries(i).expect("index below len"))
8210    }
8211
8212    pub fn resize_edge_fade_entries(&mut self, count: usize) {
8213        // SAFETY: exclusive access, so no borrow is outstanding.
8214        unsafe { ffi::whiteout_m2_M2Model_resize_edgeFadeEntries(self.raw.as_ptr(), count) }
8215    }
8216
8217    /// NERF
8218    pub fn nerf_entries_len(&self) -> usize {
8219        // SAFETY: scalar read through a live handle.
8220        unsafe { ffi::whiteout_m2_M2Model_get_nerfEntries_count(self.raw.as_ptr()) }
8221    }
8222
8223    /// Borrows element `index` in place. `None` when out of range.
8224    pub fn nerf_entries(&self, index: usize) -> Option<crate::support::Ref<'_, DistanceFadeData>> {
8225        if index >= self.nerf_entries_len() {
8226            return None;
8227        }
8228        // SAFETY: index checked above; the pointer is interior to `self`.
8229        unsafe {
8230            Some(crate::support::Ref::new(DistanceFadeData {
8231                raw: core::ptr::NonNull::new_unchecked(
8232                    ffi::whiteout_m2_M2Model_get_nerfEntries_at(self.raw.as_ptr(), index),
8233                ),
8234            }))
8235        }
8236    }
8237
8238    pub fn nerf_entries_mut(
8239        &mut self,
8240        index: usize,
8241    ) -> Option<crate::support::RefMut<'_, DistanceFadeData>> {
8242        if index >= self.nerf_entries_len() {
8243            return None;
8244        }
8245        // SAFETY: as above; `&mut self` guarantees exclusivity.
8246        unsafe {
8247            Some(crate::support::RefMut::new(DistanceFadeData {
8248                raw: core::ptr::NonNull::new_unchecked(
8249                    ffi::whiteout_m2_M2Model_get_nerfEntries_at(self.raw.as_ptr(), index),
8250                ),
8251            }))
8252        }
8253    }
8254
8255    /// Iterate the elements, borrowing each in turn.
8256    pub fn nerf_entries_iter(
8257        &self,
8258    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, DistanceFadeData>> {
8259        (0..self.nerf_entries_len()).map(move |i| self.nerf_entries(i).expect("index below len"))
8260    }
8261
8262    pub fn resize_nerf_entries(&mut self, count: usize) {
8263        // SAFETY: exclusive access, so no borrow is outstanding.
8264        unsafe { ffi::whiteout_m2_M2Model_resize_nerfEntries(self.raw.as_ptr(), count) }
8265    }
8266
8267    /// DETL
8268    pub fn detailed_light_entries_len(&self) -> usize {
8269        // SAFETY: scalar read through a live handle.
8270        unsafe { ffi::whiteout_m2_M2Model_get_detailedLightEntries_count(self.raw.as_ptr()) }
8271    }
8272
8273    /// Borrows element `index` in place. `None` when out of range.
8274    pub fn detailed_light_entries(
8275        &self,
8276        index: usize,
8277    ) -> Option<crate::support::Ref<'_, DetailedLightData>> {
8278        if index >= self.detailed_light_entries_len() {
8279            return None;
8280        }
8281        // SAFETY: index checked above; the pointer is interior to `self`.
8282        unsafe {
8283            Some(crate::support::Ref::new(DetailedLightData {
8284                raw: core::ptr::NonNull::new_unchecked(
8285                    ffi::whiteout_m2_M2Model_get_detailedLightEntries_at(self.raw.as_ptr(), index),
8286                ),
8287            }))
8288        }
8289    }
8290
8291    pub fn detailed_light_entries_mut(
8292        &mut self,
8293        index: usize,
8294    ) -> Option<crate::support::RefMut<'_, DetailedLightData>> {
8295        if index >= self.detailed_light_entries_len() {
8296            return None;
8297        }
8298        // SAFETY: as above; `&mut self` guarantees exclusivity.
8299        unsafe {
8300            Some(crate::support::RefMut::new(DetailedLightData {
8301                raw: core::ptr::NonNull::new_unchecked(
8302                    ffi::whiteout_m2_M2Model_get_detailedLightEntries_at(self.raw.as_ptr(), index),
8303                ),
8304            }))
8305        }
8306    }
8307
8308    /// Iterate the elements, borrowing each in turn.
8309    pub fn detailed_light_entries_iter(
8310        &self,
8311    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, DetailedLightData>> {
8312        (0..self.detailed_light_entries_len())
8313            .map(move |i| self.detailed_light_entries(i).expect("index below len"))
8314    }
8315
8316    pub fn resize_detailed_light_entries(&mut self, count: usize) {
8317        // SAFETY: exclusive access, so no borrow is outstanding.
8318        unsafe { ffi::whiteout_m2_M2Model_resize_detailedLightEntries(self.raw.as_ptr(), count) }
8319    }
8320
8321    /// DBOC
8322    pub fn debug_occlusion_entries_len(&self) -> usize {
8323        // SAFETY: scalar read through a live handle.
8324        unsafe { ffi::whiteout_m2_M2Model_get_debugOcclusionEntries_count(self.raw.as_ptr()) }
8325    }
8326
8327    /// Borrows element `index` in place. `None` when out of range.
8328    pub fn debug_occlusion_entries(
8329        &self,
8330        index: usize,
8331    ) -> Option<crate::support::Ref<'_, DebugOcclusionData>> {
8332        if index >= self.debug_occlusion_entries_len() {
8333            return None;
8334        }
8335        // SAFETY: index checked above; the pointer is interior to `self`.
8336        unsafe {
8337            Some(crate::support::Ref::new(DebugOcclusionData {
8338                raw: core::ptr::NonNull::new_unchecked(
8339                    ffi::whiteout_m2_M2Model_get_debugOcclusionEntries_at(self.raw.as_ptr(), index),
8340                ),
8341            }))
8342        }
8343    }
8344
8345    pub fn debug_occlusion_entries_mut(
8346        &mut self,
8347        index: usize,
8348    ) -> Option<crate::support::RefMut<'_, DebugOcclusionData>> {
8349        if index >= self.debug_occlusion_entries_len() {
8350            return None;
8351        }
8352        // SAFETY: as above; `&mut self` guarantees exclusivity.
8353        unsafe {
8354            Some(crate::support::RefMut::new(DebugOcclusionData {
8355                raw: core::ptr::NonNull::new_unchecked(
8356                    ffi::whiteout_m2_M2Model_get_debugOcclusionEntries_at(self.raw.as_ptr(), index),
8357                ),
8358            }))
8359        }
8360    }
8361
8362    /// Iterate the elements, borrowing each in turn.
8363    pub fn debug_occlusion_entries_iter(
8364        &self,
8365    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, DebugOcclusionData>> {
8366        (0..self.debug_occlusion_entries_len())
8367            .map(move |i| self.debug_occlusion_entries(i).expect("index below len"))
8368    }
8369
8370    pub fn resize_debug_occlusion_entries(&mut self, count: usize) {
8371        // SAFETY: exclusive access, so no borrow is outstanding.
8372        unsafe { ffi::whiteout_m2_M2Model_resize_debugOcclusionEntries(self.raw.as_ptr(), count) }
8373    }
8374
8375    /// AFRA
8376    /// Zero-copy view of the underlying `std::vector`.
8377    pub fn anim_frame_data(&self) -> &[u8] {
8378        // SAFETY: `_data`/`_count` describe one contiguous C++
8379        // allocation, borrowed for as long as `self` is.
8380        unsafe {
8381            let n = ffi::whiteout_m2_M2Model_get_animFrameData_count(self.raw.as_ptr());
8382            let p = ffi::whiteout_m2_M2Model_get_animFrameData_data(self.raw.as_ptr());
8383            if p.is_null() || n == 0 {
8384                &[]
8385            } else {
8386                core::slice::from_raw_parts(p, n)
8387            }
8388        }
8389    }
8390
8391    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
8392    pub fn anim_frame_data_mut(&mut self) -> &mut [u8] {
8393        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
8394        unsafe {
8395            let n = ffi::whiteout_m2_M2Model_get_animFrameData_count(self.raw.as_ptr());
8396            let p = ffi::whiteout_m2_M2Model_get_animFrameData_data(self.raw.as_ptr()) as *mut u8;
8397            if p.is_null() || n == 0 {
8398                &mut []
8399            } else {
8400                core::slice::from_raw_parts_mut(p, n)
8401            }
8402        }
8403    }
8404
8405    pub fn set_anim_frame_data(&mut self, values: &[u8]) {
8406        // SAFETY: the native side copies `values` before returning.
8407        unsafe {
8408            ffi::whiteout_m2_M2Model_assign_animFrameData(
8409                self.raw.as_ptr(),
8410                values.as_ptr() as *const _,
8411                values.len(),
8412            )
8413        }
8414    }
8415
8416    pub fn resize_anim_frame_data(&mut self, count: usize) {
8417        // SAFETY: reallocation is safe here precisely because
8418        // `&mut self` means no slice borrow is outstanding.
8419        unsafe { ffi::whiteout_m2_M2Model_resize_animFrameData(self.raw.as_ptr(), count) }
8420    }
8421
8422    /// TEXL
8423    pub fn textured_light_entries_len(&self) -> usize {
8424        // SAFETY: scalar read through a live handle.
8425        unsafe { ffi::whiteout_m2_M2Model_get_texturedLightEntries_count(self.raw.as_ptr()) }
8426    }
8427
8428    /// Borrows element `index` in place. `None` when out of range.
8429    pub fn textured_light_entries(
8430        &self,
8431        index: usize,
8432    ) -> Option<crate::support::Ref<'_, TexturedLightData>> {
8433        if index >= self.textured_light_entries_len() {
8434            return None;
8435        }
8436        // SAFETY: index checked above; the pointer is interior to `self`.
8437        unsafe {
8438            Some(crate::support::Ref::new(TexturedLightData {
8439                raw: core::ptr::NonNull::new_unchecked(
8440                    ffi::whiteout_m2_M2Model_get_texturedLightEntries_at(self.raw.as_ptr(), index),
8441                ),
8442            }))
8443        }
8444    }
8445
8446    pub fn textured_light_entries_mut(
8447        &mut self,
8448        index: usize,
8449    ) -> Option<crate::support::RefMut<'_, TexturedLightData>> {
8450        if index >= self.textured_light_entries_len() {
8451            return None;
8452        }
8453        // SAFETY: as above; `&mut self` guarantees exclusivity.
8454        unsafe {
8455            Some(crate::support::RefMut::new(TexturedLightData {
8456                raw: core::ptr::NonNull::new_unchecked(
8457                    ffi::whiteout_m2_M2Model_get_texturedLightEntries_at(self.raw.as_ptr(), index),
8458                ),
8459            }))
8460        }
8461    }
8462
8463    /// Iterate the elements, borrowing each in turn.
8464    pub fn textured_light_entries_iter(
8465        &self,
8466    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, TexturedLightData>> {
8467        (0..self.textured_light_entries_len())
8468            .map(move |i| self.textured_light_entries(i).expect("index below len"))
8469    }
8470
8471    pub fn resize_textured_light_entries(&mut self, count: usize) {
8472        // SAFETY: exclusive access, so no borrow is outstanding.
8473        unsafe { ffi::whiteout_m2_M2Model_resize_texturedLightEntries(self.raw.as_ptr(), count) }
8474    }
8475}
8476
8477impl Default for Model {
8478    fn default() -> Self {
8479        Self::new()
8480    }
8481}
8482
8483pub struct Parser {
8484    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2Parser>,
8485}
8486
8487impl Drop for Parser {
8488    fn drop(&mut self) {
8489        // SAFETY: `raw` came from a native constructor and Drop runs once.
8490        unsafe { ffi::whiteout_m2_M2Parser_delete(self.raw.as_ptr()) }
8491    }
8492}
8493
8494impl Parser {
8495    /// # Safety
8496    /// `raw` must be a live handle this value takes ownership of.
8497    #[allow(dead_code)] // used by whichever methods return this type
8498    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2Parser) -> Option<Self> {
8499        core::ptr::NonNull::new(raw).map(|raw| Parser { raw })
8500    }
8501}
8502
8503// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
8504// is deliberately NOT implemented — the C++ types make no documented
8505// guarantee about concurrent use, and claiming one we haven't verified
8506// would be unsound. See `@bind thread_safe` in the plan.
8507unsafe impl Send for Parser {}
8508
8509impl core::fmt::Debug for Parser {
8510    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
8511        f.debug_struct("Parser").finish_non_exhaustive()
8512    }
8513}
8514
8515impl Parser {
8516    /// # Panics
8517    /// Panics if the native allocation fails.
8518    pub fn new() -> Self {
8519        // SAFETY: the native constructor returns a live handle; a null here
8520        // means the library is unusable.
8521        unsafe {
8522            let raw = ffi::whiteout_m2_M2Parser_new();
8523            Self::from_raw(raw).expect("native Parser allocation failed")
8524        }
8525    }
8526
8527    pub fn parse_file(
8528        &mut self,
8529        fs: Option<&crate::interfaces::HostFileSystem>,
8530        file_path: &str,
8531    ) -> Option<Model> {
8532        let file_path_cstr = std::ffi::CString::new(file_path).unwrap_or_default();
8533        // SAFETY: handle is live for the duration of the call.
8534        unsafe {
8535            Model::from_raw(ffi::whiteout_m2_M2Parser_parse(
8536                self.raw.as_ptr(),
8537                fs.map_or(core::ptr::null_mut(), |v| v.as_ptr()),
8538                file_path_cstr.as_ptr(),
8539            ))
8540        }
8541    }
8542
8543    pub fn parse_casc_fs_buffer(&mut self, casc_fs: &[u8], buffer: &[u8]) -> Option<Model> {
8544        // SAFETY: handle is live for the duration of the call.
8545        unsafe {
8546            Model::from_raw(ffi::whiteout_m2_M2Parser_parse_cascFs_buffer(
8547                self.raw.as_ptr(),
8548                casc_fs.as_ptr(),
8549                casc_fs.len(),
8550                buffer.as_ptr(),
8551                buffer.len(),
8552            ))
8553        }
8554    }
8555
8556    pub fn has_issues(&self) -> bool {
8557        // SAFETY: handle is live for the duration of the call.
8558        unsafe { ffi::whiteout_m2_M2Parser_hasIssues(self.raw.as_ptr()) != 0 }
8559    }
8560
8561    pub fn issues(&self) -> Vec<String> {
8562        // SAFETY: index stays below the reported count.
8563        unsafe {
8564            let n = ffi::whiteout_m2_M2Parser_getIssues_count(self.raw.as_ptr());
8565            (0..n)
8566                .map(|i| {
8567                    crate::support::take_string(ffi::whiteout_m2_M2Parser_getIssues_at(
8568                        self.raw.as_ptr(),
8569                        i,
8570                    ))
8571                })
8572                .collect()
8573        }
8574    }
8575}
8576
8577impl Default for Parser {
8578    fn default() -> Self {
8579        Self::new()
8580    }
8581}
8582
8583pub struct WriteOptions {
8584    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2WriteOptions>,
8585}
8586
8587impl Drop for WriteOptions {
8588    fn drop(&mut self) {
8589        // SAFETY: `raw` came from a native constructor and Drop runs once.
8590        unsafe { ffi::whiteout_m2_M2WriteOptions_delete(self.raw.as_ptr()) }
8591    }
8592}
8593
8594impl WriteOptions {
8595    /// # Safety
8596    /// `raw` must be a live handle this value takes ownership of.
8597    #[allow(dead_code)] // used by whichever methods return this type
8598    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2WriteOptions) -> Option<Self> {
8599        core::ptr::NonNull::new(raw).map(|raw| WriteOptions { raw })
8600    }
8601}
8602
8603// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
8604// is deliberately NOT implemented — the C++ types make no documented
8605// guarantee about concurrent use, and claiming one we haven't verified
8606// would be unsound. See `@bind thread_safe` in the plan.
8607unsafe impl Send for WriteOptions {}
8608
8609impl core::fmt::Debug for WriteOptions {
8610    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
8611        f.debug_struct("WriteOptions").finish_non_exhaustive()
8612    }
8613}
8614
8615impl WriteOptions {
8616    /// # Panics
8617    /// Panics if the native allocation fails.
8618    pub fn new() -> Self {
8619        // SAFETY: the native constructor returns a live handle; a null here
8620        // means the library is unusable.
8621        unsafe {
8622            let raw = ffi::whiteout_m2_M2WriteOptions_new();
8623            Self::from_raw(raw).expect("native WriteOptions allocation failed")
8624        }
8625    }
8626
8627    pub fn m_2_version(&self) -> u32 {
8628        // SAFETY: plain scalar read through a live handle.
8629        unsafe { ffi::whiteout_m2_M2WriteOptions_get_m2Version(self.raw.as_ptr()) }
8630    }
8631
8632    pub fn set_m_2_version(&mut self, value: u32) {
8633        // SAFETY: plain scalar write through a live handle.
8634        unsafe { ffi::whiteout_m2_M2WriteOptions_set_m2Version(self.raw.as_ptr(), value) }
8635    }
8636
8637    pub fn emit_skeleton(&self) -> bool {
8638        // SAFETY: plain scalar read through a live handle.
8639        unsafe { ffi::whiteout_m2_M2WriteOptions_get_emitSkeleton(self.raw.as_ptr()) != 0 }
8640    }
8641
8642    pub fn set_emit_skeleton(&mut self, value: bool) {
8643        // SAFETY: plain scalar write through a live handle.
8644        unsafe {
8645            ffi::whiteout_m2_M2WriteOptions_set_emitSkeleton(
8646                self.raw.as_ptr(),
8647                if value { 1 } else { 0 },
8648            )
8649        }
8650    }
8651
8652    pub fn base_stem(&self) -> String {
8653        // SAFETY: the native side hands over an owned CString.
8654        unsafe {
8655            crate::support::take_string(ffi::whiteout_m2_M2WriteOptions_get_baseStem(
8656                self.raw.as_ptr(),
8657            ))
8658        }
8659    }
8660
8661    pub fn set_base_stem(&mut self, value: &str) {
8662        let value = std::ffi::CString::new(value).unwrap_or_default();
8663        // SAFETY: the pointer outlives the call.
8664        unsafe { ffi::whiteout_m2_M2WriteOptions_set_baseStem(self.raw.as_ptr(), value.as_ptr()) }
8665    }
8666}
8667
8668impl Default for WriteOptions {
8669    fn default() -> Self {
8670        Self::new()
8671    }
8672}
8673
8674pub struct SerializeResult {
8675    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2SerializeResult>,
8676}
8677
8678impl Drop for SerializeResult {
8679    fn drop(&mut self) {
8680        // SAFETY: `raw` came from a native constructor and Drop runs once.
8681        unsafe { ffi::whiteout_m2_M2SerializeResult_delete(self.raw.as_ptr()) }
8682    }
8683}
8684
8685impl SerializeResult {
8686    /// # Safety
8687    /// `raw` must be a live handle this value takes ownership of.
8688    #[allow(dead_code)] // used by whichever methods return this type
8689    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2SerializeResult) -> Option<Self> {
8690        core::ptr::NonNull::new(raw).map(|raw| SerializeResult { raw })
8691    }
8692}
8693
8694// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
8695// is deliberately NOT implemented — the C++ types make no documented
8696// guarantee about concurrent use, and claiming one we haven't verified
8697// would be unsound. See `@bind thread_safe` in the plan.
8698unsafe impl Send for SerializeResult {}
8699
8700impl core::fmt::Debug for SerializeResult {
8701    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
8702        f.debug_struct("SerializeResult").finish_non_exhaustive()
8703    }
8704}
8705
8706impl SerializeResult {
8707    /// # Panics
8708    /// Panics if the native allocation fails.
8709    pub fn new() -> Self {
8710        // SAFETY: the native constructor returns a live handle; a null here
8711        // means the library is unusable.
8712        unsafe {
8713            let raw = ffi::whiteout_m2_M2SerializeResult_new();
8714            Self::from_raw(raw).expect("native SerializeResult allocation failed")
8715        }
8716    }
8717
8718    /// Zero-copy view of the underlying `std::vector`.
8719    pub fn m_2_data(&self) -> &[u8] {
8720        // SAFETY: `_data`/`_count` describe one contiguous C++
8721        // allocation, borrowed for as long as `self` is.
8722        unsafe {
8723            let n = ffi::whiteout_m2_M2SerializeResult_get_m2Data_count(self.raw.as_ptr());
8724            let p = ffi::whiteout_m2_M2SerializeResult_get_m2Data_data(self.raw.as_ptr());
8725            if p.is_null() || n == 0 {
8726                &[]
8727            } else {
8728                core::slice::from_raw_parts(p, n)
8729            }
8730        }
8731    }
8732
8733    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
8734    pub fn m_2_data_mut(&mut self) -> &mut [u8] {
8735        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
8736        unsafe {
8737            let n = ffi::whiteout_m2_M2SerializeResult_get_m2Data_count(self.raw.as_ptr());
8738            let p =
8739                ffi::whiteout_m2_M2SerializeResult_get_m2Data_data(self.raw.as_ptr()) as *mut u8;
8740            if p.is_null() || n == 0 {
8741                &mut []
8742            } else {
8743                core::slice::from_raw_parts_mut(p, n)
8744            }
8745        }
8746    }
8747
8748    pub fn set_m_2_data(&mut self, values: &[u8]) {
8749        // SAFETY: the native side copies `values` before returning.
8750        unsafe {
8751            ffi::whiteout_m2_M2SerializeResult_assign_m2Data(
8752                self.raw.as_ptr(),
8753                values.as_ptr() as *const _,
8754                values.len(),
8755            )
8756        }
8757    }
8758
8759    pub fn resize_m_2_data(&mut self, count: usize) {
8760        // SAFETY: reallocation is safe here precisely because
8761        // `&mut self` means no slice borrow is outstanding.
8762        unsafe { ffi::whiteout_m2_M2SerializeResult_resize_m2Data(self.raw.as_ptr(), count) }
8763    }
8764}
8765
8766impl Default for SerializeResult {
8767    fn default() -> Self {
8768        Self::new()
8769    }
8770}
8771
8772pub struct Writer {
8773    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2Writer>,
8774}
8775
8776impl Drop for Writer {
8777    fn drop(&mut self) {
8778        // SAFETY: `raw` came from a native constructor and Drop runs once.
8779        unsafe { ffi::whiteout_m2_M2Writer_delete(self.raw.as_ptr()) }
8780    }
8781}
8782
8783impl Writer {
8784    /// # Safety
8785    /// `raw` must be a live handle this value takes ownership of.
8786    #[allow(dead_code)] // used by whichever methods return this type
8787    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2Writer) -> Option<Self> {
8788        core::ptr::NonNull::new(raw).map(|raw| Writer { raw })
8789    }
8790}
8791
8792// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
8793// is deliberately NOT implemented — the C++ types make no documented
8794// guarantee about concurrent use, and claiming one we haven't verified
8795// would be unsound. See `@bind thread_safe` in the plan.
8796unsafe impl Send for Writer {}
8797
8798impl core::fmt::Debug for Writer {
8799    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
8800        f.debug_struct("Writer").finish_non_exhaustive()
8801    }
8802}
8803
8804impl Writer {
8805    /// # Panics
8806    /// Panics if the native allocation fails.
8807    pub fn new() -> Self {
8808        // SAFETY: the native constructor returns a live handle; a null here
8809        // means the library is unusable.
8810        unsafe {
8811            let raw = ffi::whiteout_m2_M2Writer_new();
8812            Self::from_raw(raw).expect("native Writer allocation failed")
8813        }
8814    }
8815
8816    pub fn write_file(
8817        &mut self,
8818        fs: Option<&crate::interfaces::HostFileSystem>,
8819        file_path: &str,
8820        model: &Model,
8821    ) {
8822        let file_path_cstr = std::ffi::CString::new(file_path).unwrap_or_default();
8823        // SAFETY: handle is live for the duration of the call.
8824        unsafe {
8825            ffi::whiteout_m2_M2Writer_write(
8826                self.raw.as_ptr(),
8827                fs.map_or(core::ptr::null_mut(), |v| v.as_ptr()),
8828                file_path_cstr.as_ptr(),
8829                model.raw.as_ptr(),
8830            );
8831        }
8832    }
8833
8834    pub fn write_casc_fs_model(
8835        &mut self,
8836        casc_fs: Option<&crate::interfaces::HostCascFileSystem>,
8837        model: &Model,
8838    ) {
8839        // SAFETY: handle is live for the duration of the call.
8840        unsafe {
8841            ffi::whiteout_m2_M2Writer_write_cascFs_model(
8842                self.raw.as_ptr(),
8843                casc_fs.map_or(core::ptr::null_mut(), |v| v.as_ptr()),
8844                model.raw.as_ptr(),
8845            );
8846        }
8847    }
8848
8849    pub fn write(&mut self, model: &Model) -> Option<SerializeResult> {
8850        // SAFETY: handle is live for the duration of the call.
8851        unsafe {
8852            SerializeResult::from_raw(ffi::whiteout_m2_M2Writer_write_model(
8853                self.raw.as_ptr(),
8854                model.raw.as_ptr(),
8855            ))
8856        }
8857    }
8858
8859    pub fn has_issues(&self) -> bool {
8860        // SAFETY: handle is live for the duration of the call.
8861        unsafe { ffi::whiteout_m2_M2Writer_hasIssues(self.raw.as_ptr()) != 0 }
8862    }
8863
8864    pub fn issues(&self) -> Vec<String> {
8865        // SAFETY: index stays below the reported count.
8866        unsafe {
8867            let n = ffi::whiteout_m2_M2Writer_getIssues_count(self.raw.as_ptr());
8868            (0..n)
8869                .map(|i| {
8870                    crate::support::take_string(ffi::whiteout_m2_M2Writer_getIssues_at(
8871                        self.raw.as_ptr(),
8872                        i,
8873                    ))
8874                })
8875                .collect()
8876        }
8877    }
8878}
8879
8880impl Default for Writer {
8881    fn default() -> Self {
8882        Self::new()
8883    }
8884}
8885
8886pub struct AnimationTrackVector3f {
8887    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2AnimationTrackVector3f>,
8888}
8889
8890impl Drop for AnimationTrackVector3f {
8891    fn drop(&mut self) {
8892        // SAFETY: `raw` came from a native constructor and Drop runs once.
8893        unsafe { ffi::whiteout_m2_M2AnimationTrackVector3f_delete(self.raw.as_ptr()) }
8894    }
8895}
8896
8897impl AnimationTrackVector3f {
8898    /// # Safety
8899    /// `raw` must be a live handle this value takes ownership of.
8900    #[allow(dead_code)] // used by whichever methods return this type
8901    pub(crate) unsafe fn from_raw(
8902        raw: *mut ffi::whiteout_M2AnimationTrackVector3f,
8903    ) -> Option<Self> {
8904        core::ptr::NonNull::new(raw).map(|raw| AnimationTrackVector3f { raw })
8905    }
8906}
8907
8908// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
8909// is deliberately NOT implemented — the C++ types make no documented
8910// guarantee about concurrent use, and claiming one we haven't verified
8911// would be unsound. See `@bind thread_safe` in the plan.
8912unsafe impl Send for AnimationTrackVector3f {}
8913
8914impl core::fmt::Debug for AnimationTrackVector3f {
8915    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
8916        f.debug_struct("AnimationTrackVector3f")
8917            .finish_non_exhaustive()
8918    }
8919}
8920
8921impl AnimationTrackVector3f {
8922    /// # Panics
8923    /// Panics if the native allocation fails.
8924    pub fn new() -> Self {
8925        // SAFETY: the native constructor returns a live handle; a null here
8926        // means the library is unusable.
8927        unsafe {
8928            let raw = ffi::whiteout_m2_M2AnimationTrackVector3f_new();
8929            Self::from_raw(raw).expect("native AnimationTrackVector3f allocation failed")
8930        }
8931    }
8932
8933    pub fn interpolation_type(&self) -> InterpolationType {
8934        // SAFETY: scalar read; the discriminant is validated below.
8935        unsafe {
8936            ffi::whiteout_m2_M2AnimationTrackVector3f_get_interpolationType(self.raw.as_ptr())
8937        }
8938        .try_into()
8939        .expect("unknown enum discriminant from the native library")
8940    }
8941
8942    pub fn set_interpolation_type(&mut self, value: InterpolationType) {
8943        // SAFETY: scalar write through a live handle.
8944        unsafe {
8945            ffi::whiteout_m2_M2AnimationTrackVector3f_set_interpolationType(
8946                self.raw.as_ptr(),
8947                value as i32,
8948            )
8949        }
8950    }
8951
8952    pub fn global_sequence_id(&self) -> u16 {
8953        // SAFETY: plain scalar read through a live handle.
8954        unsafe { ffi::whiteout_m2_M2AnimationTrackVector3f_get_globalSequenceId(self.raw.as_ptr()) }
8955    }
8956
8957    pub fn set_global_sequence_id(&mut self, value: u16) {
8958        // SAFETY: plain scalar write through a live handle.
8959        unsafe {
8960            ffi::whiteout_m2_M2AnimationTrackVector3f_set_globalSequenceId(self.raw.as_ptr(), value)
8961        }
8962    }
8963
8964    /// Number of inner sequences.
8965    pub fn timestamps_len(&self) -> usize {
8966        // SAFETY: scalar read through a live handle.
8967        unsafe { ffi::whiteout_m2_M2AnimationTrackVector3f_get_timestamps_count(self.raw.as_ptr()) }
8968    }
8969
8970    /// Zero-copy view of inner sequence `outer`. Empty when out of range.
8971    ///
8972    /// Each inner vector is contiguous on its own, but the outer one
8973    /// is a vector of vectors — so this borrows per sequence rather
8974    /// than handing back one flat slice.
8975    pub fn timestamps(&self, outer: usize) -> &[u32] {
8976        if outer >= self.timestamps_len() {
8977            return &[];
8978        }
8979        // SAFETY: index checked; the pointer borrows `self`.
8980        unsafe {
8981            let n = ffi::whiteout_m2_M2AnimationTrackVector3f_get_timestamps_inner_count(
8982                self.raw.as_ptr(),
8983                outer,
8984            );
8985            let p = ffi::whiteout_m2_M2AnimationTrackVector3f_get_timestamps_inner_data(
8986                self.raw.as_ptr(),
8987                outer,
8988            );
8989            if p.is_null() || n == 0 {
8990                &[]
8991            } else {
8992                core::slice::from_raw_parts(p, n)
8993            }
8994        }
8995    }
8996
8997    pub fn timestamps_mut(&mut self, outer: usize) -> &mut [u32] {
8998        if outer >= self.timestamps_len() {
8999            return &mut [];
9000        }
9001        // SAFETY: as above; `&mut self` rules out aliasing.
9002        unsafe {
9003            let n = ffi::whiteout_m2_M2AnimationTrackVector3f_get_timestamps_inner_count(
9004                self.raw.as_ptr(),
9005                outer,
9006            );
9007            let p = ffi::whiteout_m2_M2AnimationTrackVector3f_get_timestamps_inner_data(
9008                self.raw.as_ptr(),
9009                outer,
9010            ) as *mut u32;
9011            if p.is_null() || n == 0 {
9012                &mut []
9013            } else {
9014                core::slice::from_raw_parts_mut(p, n)
9015            }
9016        }
9017    }
9018
9019    pub fn set_timestamps(&mut self, outer: usize, values: &[u32]) {
9020        // SAFETY: the native side copies `values` before returning.
9021        unsafe {
9022            ffi::whiteout_m2_M2AnimationTrackVector3f_assign_timestamps_inner(
9023                self.raw.as_ptr(),
9024                outer,
9025                values.as_ptr() as *const _,
9026                values.len(),
9027            )
9028        }
9029    }
9030
9031    /// Resize the outer sequence. Do this before taking any borrow.
9032    pub fn resize_timestamps(&mut self, count: usize) {
9033        // SAFETY: exclusive access, so no borrow is outstanding.
9034        unsafe {
9035            ffi::whiteout_m2_M2AnimationTrackVector3f_resize_timestamps(self.raw.as_ptr(), count)
9036        }
9037    }
9038
9039    pub fn resize_timestamps_inner(&mut self, outer: usize, count: usize) {
9040        // SAFETY: as above.
9041        unsafe {
9042            ffi::whiteout_m2_M2AnimationTrackVector3f_resize_timestamps_inner(
9043                self.raw.as_ptr(),
9044                outer,
9045                count,
9046            )
9047        }
9048    }
9049
9050    /// Number of inner sequences.
9051    pub fn values_len(&self) -> usize {
9052        // SAFETY: scalar read through a live handle.
9053        unsafe { ffi::whiteout_m2_M2AnimationTrackVector3f_get_values_count(self.raw.as_ptr()) }
9054    }
9055
9056    /// Zero-copy view of inner sequence `outer`. Empty when out of range.
9057    ///
9058    /// Each inner vector is contiguous on its own, but the outer one
9059    /// is a vector of vectors — so this borrows per sequence rather
9060    /// than handing back one flat slice.
9061    pub fn values(&self, outer: usize) -> &[crate::math::Vector3f] {
9062        if outer >= self.values_len() {
9063            return &[];
9064        }
9065        // SAFETY: index checked; the pointer borrows `self`.
9066        unsafe {
9067            let n = ffi::whiteout_m2_M2AnimationTrackVector3f_get_values_inner_count(
9068                self.raw.as_ptr(),
9069                outer,
9070            );
9071            let p = ffi::whiteout_m2_M2AnimationTrackVector3f_get_values_inner_data(
9072                self.raw.as_ptr(),
9073                outer,
9074            ) as *const crate::math::Vector3f;
9075            if p.is_null() || n == 0 {
9076                &[]
9077            } else {
9078                core::slice::from_raw_parts(p, n)
9079            }
9080        }
9081    }
9082
9083    pub fn values_mut(&mut self, outer: usize) -> &mut [crate::math::Vector3f] {
9084        if outer >= self.values_len() {
9085            return &mut [];
9086        }
9087        // SAFETY: as above; `&mut self` rules out aliasing.
9088        unsafe {
9089            let n = ffi::whiteout_m2_M2AnimationTrackVector3f_get_values_inner_count(
9090                self.raw.as_ptr(),
9091                outer,
9092            );
9093            let p = ffi::whiteout_m2_M2AnimationTrackVector3f_get_values_inner_data(
9094                self.raw.as_ptr(),
9095                outer,
9096            ) as *const crate::math::Vector3f as *mut crate::math::Vector3f;
9097            if p.is_null() || n == 0 {
9098                &mut []
9099            } else {
9100                core::slice::from_raw_parts_mut(p, n)
9101            }
9102        }
9103    }
9104
9105    pub fn set_values(&mut self, outer: usize, values: &[crate::math::Vector3f]) {
9106        // SAFETY: the native side copies `values` before returning.
9107        unsafe {
9108            ffi::whiteout_m2_M2AnimationTrackVector3f_assign_values_inner(
9109                self.raw.as_ptr(),
9110                outer,
9111                values.as_ptr() as *const _,
9112                values.len(),
9113            )
9114        }
9115    }
9116
9117    /// Resize the outer sequence. Do this before taking any borrow.
9118    pub fn resize_values(&mut self, count: usize) {
9119        // SAFETY: exclusive access, so no borrow is outstanding.
9120        unsafe { ffi::whiteout_m2_M2AnimationTrackVector3f_resize_values(self.raw.as_ptr(), count) }
9121    }
9122
9123    pub fn resize_values_inner(&mut self, outer: usize, count: usize) {
9124        // SAFETY: as above.
9125        unsafe {
9126            ffi::whiteout_m2_M2AnimationTrackVector3f_resize_values_inner(
9127                self.raw.as_ptr(),
9128                outer,
9129                count,
9130            )
9131        }
9132    }
9133}
9134
9135impl Default for AnimationTrackVector3f {
9136    fn default() -> Self {
9137        Self::new()
9138    }
9139}
9140
9141pub struct AnimationTrackM2CompatQuaternion {
9142    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2AnimationTrackM2CompatQuaternion>,
9143}
9144
9145impl Drop for AnimationTrackM2CompatQuaternion {
9146    fn drop(&mut self) {
9147        // SAFETY: `raw` came from a native constructor and Drop runs once.
9148        unsafe { ffi::whiteout_m2_M2AnimationTrackM2CompatQuaternion_delete(self.raw.as_ptr()) }
9149    }
9150}
9151
9152impl AnimationTrackM2CompatQuaternion {
9153    /// # Safety
9154    /// `raw` must be a live handle this value takes ownership of.
9155    #[allow(dead_code)] // used by whichever methods return this type
9156    pub(crate) unsafe fn from_raw(
9157        raw: *mut ffi::whiteout_M2AnimationTrackM2CompatQuaternion,
9158    ) -> Option<Self> {
9159        core::ptr::NonNull::new(raw).map(|raw| AnimationTrackM2CompatQuaternion { raw })
9160    }
9161}
9162
9163// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
9164// is deliberately NOT implemented — the C++ types make no documented
9165// guarantee about concurrent use, and claiming one we haven't verified
9166// would be unsound. See `@bind thread_safe` in the plan.
9167unsafe impl Send for AnimationTrackM2CompatQuaternion {}
9168
9169impl core::fmt::Debug for AnimationTrackM2CompatQuaternion {
9170    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
9171        f.debug_struct("AnimationTrackM2CompatQuaternion")
9172            .finish_non_exhaustive()
9173    }
9174}
9175
9176impl AnimationTrackM2CompatQuaternion {
9177    /// # Panics
9178    /// Panics if the native allocation fails.
9179    pub fn new() -> Self {
9180        // SAFETY: the native constructor returns a live handle; a null here
9181        // means the library is unusable.
9182        unsafe {
9183            let raw = ffi::whiteout_m2_M2AnimationTrackM2CompatQuaternion_new();
9184            Self::from_raw(raw).expect("native AnimationTrackM2CompatQuaternion allocation failed")
9185        }
9186    }
9187
9188    pub fn interpolation_type(&self) -> InterpolationType {
9189        // SAFETY: scalar read; the discriminant is validated below.
9190        unsafe {
9191            ffi::whiteout_m2_M2AnimationTrackM2CompatQuaternion_get_interpolationType(
9192                self.raw.as_ptr(),
9193            )
9194        }
9195        .try_into()
9196        .expect("unknown enum discriminant from the native library")
9197    }
9198
9199    pub fn set_interpolation_type(&mut self, value: InterpolationType) {
9200        // SAFETY: scalar write through a live handle.
9201        unsafe {
9202            ffi::whiteout_m2_M2AnimationTrackM2CompatQuaternion_set_interpolationType(
9203                self.raw.as_ptr(),
9204                value as i32,
9205            )
9206        }
9207    }
9208
9209    pub fn global_sequence_id(&self) -> u16 {
9210        // SAFETY: plain scalar read through a live handle.
9211        unsafe {
9212            ffi::whiteout_m2_M2AnimationTrackM2CompatQuaternion_get_globalSequenceId(
9213                self.raw.as_ptr(),
9214            )
9215        }
9216    }
9217
9218    pub fn set_global_sequence_id(&mut self, value: u16) {
9219        // SAFETY: plain scalar write through a live handle.
9220        unsafe {
9221            ffi::whiteout_m2_M2AnimationTrackM2CompatQuaternion_set_globalSequenceId(
9222                self.raw.as_ptr(),
9223                value,
9224            )
9225        }
9226    }
9227
9228    /// Number of inner sequences.
9229    pub fn timestamps_len(&self) -> usize {
9230        // SAFETY: scalar read through a live handle.
9231        unsafe {
9232            ffi::whiteout_m2_M2AnimationTrackM2CompatQuaternion_get_timestamps_count(
9233                self.raw.as_ptr(),
9234            )
9235        }
9236    }
9237
9238    /// Zero-copy view of inner sequence `outer`. Empty when out of range.
9239    ///
9240    /// Each inner vector is contiguous on its own, but the outer one
9241    /// is a vector of vectors — so this borrows per sequence rather
9242    /// than handing back one flat slice.
9243    pub fn timestamps(&self, outer: usize) -> &[u32] {
9244        if outer >= self.timestamps_len() {
9245            return &[];
9246        }
9247        // SAFETY: index checked; the pointer borrows `self`.
9248        unsafe {
9249            let n = ffi::whiteout_m2_M2AnimationTrackM2CompatQuaternion_get_timestamps_inner_count(
9250                self.raw.as_ptr(),
9251                outer,
9252            );
9253            let p = ffi::whiteout_m2_M2AnimationTrackM2CompatQuaternion_get_timestamps_inner_data(
9254                self.raw.as_ptr(),
9255                outer,
9256            );
9257            if p.is_null() || n == 0 {
9258                &[]
9259            } else {
9260                core::slice::from_raw_parts(p, n)
9261            }
9262        }
9263    }
9264
9265    pub fn timestamps_mut(&mut self, outer: usize) -> &mut [u32] {
9266        if outer >= self.timestamps_len() {
9267            return &mut [];
9268        }
9269        // SAFETY: as above; `&mut self` rules out aliasing.
9270        unsafe {
9271            let n = ffi::whiteout_m2_M2AnimationTrackM2CompatQuaternion_get_timestamps_inner_count(
9272                self.raw.as_ptr(),
9273                outer,
9274            );
9275            let p = ffi::whiteout_m2_M2AnimationTrackM2CompatQuaternion_get_timestamps_inner_data(
9276                self.raw.as_ptr(),
9277                outer,
9278            ) as *mut u32;
9279            if p.is_null() || n == 0 {
9280                &mut []
9281            } else {
9282                core::slice::from_raw_parts_mut(p, n)
9283            }
9284        }
9285    }
9286
9287    pub fn set_timestamps(&mut self, outer: usize, values: &[u32]) {
9288        // SAFETY: the native side copies `values` before returning.
9289        unsafe {
9290            ffi::whiteout_m2_M2AnimationTrackM2CompatQuaternion_assign_timestamps_inner(
9291                self.raw.as_ptr(),
9292                outer,
9293                values.as_ptr() as *const _,
9294                values.len(),
9295            )
9296        }
9297    }
9298
9299    /// Resize the outer sequence. Do this before taking any borrow.
9300    pub fn resize_timestamps(&mut self, count: usize) {
9301        // SAFETY: exclusive access, so no borrow is outstanding.
9302        unsafe {
9303            ffi::whiteout_m2_M2AnimationTrackM2CompatQuaternion_resize_timestamps(
9304                self.raw.as_ptr(),
9305                count,
9306            )
9307        }
9308    }
9309
9310    pub fn resize_timestamps_inner(&mut self, outer: usize, count: usize) {
9311        // SAFETY: as above.
9312        unsafe {
9313            ffi::whiteout_m2_M2AnimationTrackM2CompatQuaternion_resize_timestamps_inner(
9314                self.raw.as_ptr(),
9315                outer,
9316                count,
9317            )
9318        }
9319    }
9320
9321    /// Number of inner sequences.
9322    pub fn values_len(&self) -> usize {
9323        // SAFETY: scalar read through a live handle.
9324        unsafe {
9325            ffi::whiteout_m2_M2AnimationTrackM2CompatQuaternion_get_values_count(self.raw.as_ptr())
9326        }
9327    }
9328
9329    /// Length of inner sequence `outer`.
9330    pub fn values_inner_len(&self, outer: usize) -> usize {
9331        if outer >= self.values_len() {
9332            return 0;
9333        }
9334        // SAFETY: index checked above.
9335        unsafe {
9336            ffi::whiteout_m2_M2AnimationTrackM2CompatQuaternion_get_values_inner_count(
9337                self.raw.as_ptr(),
9338                outer,
9339            )
9340        }
9341    }
9342
9343    /// Borrow element `inner` of sequence `outer` in place.
9344    pub fn values(
9345        &self,
9346        outer: usize,
9347        inner: usize,
9348    ) -> Option<crate::support::Ref<'_, CompatQuaternion>> {
9349        if inner >= self.values_inner_len(outer) {
9350            return None;
9351        }
9352        // SAFETY: both indices checked; the pointer is
9353        // interior to `self`.
9354        unsafe {
9355            Some(crate::support::Ref::new(CompatQuaternion {
9356                raw: core::ptr::NonNull::new_unchecked(
9357                    ffi::whiteout_m2_M2AnimationTrackM2CompatQuaternion_get_values_at(
9358                        self.raw.as_ptr(),
9359                        outer,
9360                        inner,
9361                    ),
9362                ),
9363            }))
9364        }
9365    }
9366
9367    pub fn values_mut(
9368        &mut self,
9369        outer: usize,
9370        inner: usize,
9371    ) -> Option<crate::support::RefMut<'_, CompatQuaternion>> {
9372        if inner >= self.values_inner_len(outer) {
9373            return None;
9374        }
9375        // SAFETY: as above; `&mut self` guarantees exclusivity.
9376        unsafe {
9377            Some(crate::support::RefMut::new(CompatQuaternion {
9378                raw: core::ptr::NonNull::new_unchecked(
9379                    ffi::whiteout_m2_M2AnimationTrackM2CompatQuaternion_get_values_at(
9380                        self.raw.as_ptr(),
9381                        outer,
9382                        inner,
9383                    ),
9384                ),
9385            }))
9386        }
9387    }
9388
9389    /// Resize the outer sequence. Do this before taking a borrow.
9390    pub fn resize_values(&mut self, count: usize) {
9391        // SAFETY: exclusive access, so no borrow is outstanding.
9392        unsafe {
9393            ffi::whiteout_m2_M2AnimationTrackM2CompatQuaternion_resize_values(
9394                self.raw.as_ptr(),
9395                count,
9396            )
9397        }
9398    }
9399
9400    pub fn resize_values_inner(&mut self, outer: usize, count: usize) {
9401        // SAFETY: as above.
9402        unsafe {
9403            ffi::whiteout_m2_M2AnimationTrackM2CompatQuaternion_resize_values_inner(
9404                self.raw.as_ptr(),
9405                outer,
9406                count,
9407            )
9408        }
9409    }
9410}
9411
9412impl Default for AnimationTrackM2CompatQuaternion {
9413    fn default() -> Self {
9414        Self::new()
9415    }
9416}
9417
9418pub struct AnimationTrackI16 {
9419    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2AnimationTrackI16>,
9420}
9421
9422impl Drop for AnimationTrackI16 {
9423    fn drop(&mut self) {
9424        // SAFETY: `raw` came from a native constructor and Drop runs once.
9425        unsafe { ffi::whiteout_m2_M2AnimationTrackI16_delete(self.raw.as_ptr()) }
9426    }
9427}
9428
9429impl AnimationTrackI16 {
9430    /// # Safety
9431    /// `raw` must be a live handle this value takes ownership of.
9432    #[allow(dead_code)] // used by whichever methods return this type
9433    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2AnimationTrackI16) -> Option<Self> {
9434        core::ptr::NonNull::new(raw).map(|raw| AnimationTrackI16 { raw })
9435    }
9436}
9437
9438// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
9439// is deliberately NOT implemented — the C++ types make no documented
9440// guarantee about concurrent use, and claiming one we haven't verified
9441// would be unsound. See `@bind thread_safe` in the plan.
9442unsafe impl Send for AnimationTrackI16 {}
9443
9444impl core::fmt::Debug for AnimationTrackI16 {
9445    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
9446        f.debug_struct("AnimationTrackI16").finish_non_exhaustive()
9447    }
9448}
9449
9450impl AnimationTrackI16 {
9451    /// # Panics
9452    /// Panics if the native allocation fails.
9453    pub fn new() -> Self {
9454        // SAFETY: the native constructor returns a live handle; a null here
9455        // means the library is unusable.
9456        unsafe {
9457            let raw = ffi::whiteout_m2_M2AnimationTrackI16_new();
9458            Self::from_raw(raw).expect("native AnimationTrackI16 allocation failed")
9459        }
9460    }
9461
9462    pub fn interpolation_type(&self) -> InterpolationType {
9463        // SAFETY: scalar read; the discriminant is validated below.
9464        unsafe { ffi::whiteout_m2_M2AnimationTrackI16_get_interpolationType(self.raw.as_ptr()) }
9465            .try_into()
9466            .expect("unknown enum discriminant from the native library")
9467    }
9468
9469    pub fn set_interpolation_type(&mut self, value: InterpolationType) {
9470        // SAFETY: scalar write through a live handle.
9471        unsafe {
9472            ffi::whiteout_m2_M2AnimationTrackI16_set_interpolationType(
9473                self.raw.as_ptr(),
9474                value as i32,
9475            )
9476        }
9477    }
9478
9479    pub fn global_sequence_id(&self) -> u16 {
9480        // SAFETY: plain scalar read through a live handle.
9481        unsafe { ffi::whiteout_m2_M2AnimationTrackI16_get_globalSequenceId(self.raw.as_ptr()) }
9482    }
9483
9484    pub fn set_global_sequence_id(&mut self, value: u16) {
9485        // SAFETY: plain scalar write through a live handle.
9486        unsafe {
9487            ffi::whiteout_m2_M2AnimationTrackI16_set_globalSequenceId(self.raw.as_ptr(), value)
9488        }
9489    }
9490
9491    /// Number of inner sequences.
9492    pub fn timestamps_len(&self) -> usize {
9493        // SAFETY: scalar read through a live handle.
9494        unsafe { ffi::whiteout_m2_M2AnimationTrackI16_get_timestamps_count(self.raw.as_ptr()) }
9495    }
9496
9497    /// Zero-copy view of inner sequence `outer`. Empty when out of range.
9498    ///
9499    /// Each inner vector is contiguous on its own, but the outer one
9500    /// is a vector of vectors — so this borrows per sequence rather
9501    /// than handing back one flat slice.
9502    pub fn timestamps(&self, outer: usize) -> &[u32] {
9503        if outer >= self.timestamps_len() {
9504            return &[];
9505        }
9506        // SAFETY: index checked; the pointer borrows `self`.
9507        unsafe {
9508            let n = ffi::whiteout_m2_M2AnimationTrackI16_get_timestamps_inner_count(
9509                self.raw.as_ptr(),
9510                outer,
9511            );
9512            let p = ffi::whiteout_m2_M2AnimationTrackI16_get_timestamps_inner_data(
9513                self.raw.as_ptr(),
9514                outer,
9515            );
9516            if p.is_null() || n == 0 {
9517                &[]
9518            } else {
9519                core::slice::from_raw_parts(p, n)
9520            }
9521        }
9522    }
9523
9524    pub fn timestamps_mut(&mut self, outer: usize) -> &mut [u32] {
9525        if outer >= self.timestamps_len() {
9526            return &mut [];
9527        }
9528        // SAFETY: as above; `&mut self` rules out aliasing.
9529        unsafe {
9530            let n = ffi::whiteout_m2_M2AnimationTrackI16_get_timestamps_inner_count(
9531                self.raw.as_ptr(),
9532                outer,
9533            );
9534            let p = ffi::whiteout_m2_M2AnimationTrackI16_get_timestamps_inner_data(
9535                self.raw.as_ptr(),
9536                outer,
9537            ) as *mut u32;
9538            if p.is_null() || n == 0 {
9539                &mut []
9540            } else {
9541                core::slice::from_raw_parts_mut(p, n)
9542            }
9543        }
9544    }
9545
9546    pub fn set_timestamps(&mut self, outer: usize, values: &[u32]) {
9547        // SAFETY: the native side copies `values` before returning.
9548        unsafe {
9549            ffi::whiteout_m2_M2AnimationTrackI16_assign_timestamps_inner(
9550                self.raw.as_ptr(),
9551                outer,
9552                values.as_ptr() as *const _,
9553                values.len(),
9554            )
9555        }
9556    }
9557
9558    /// Resize the outer sequence. Do this before taking any borrow.
9559    pub fn resize_timestamps(&mut self, count: usize) {
9560        // SAFETY: exclusive access, so no borrow is outstanding.
9561        unsafe { ffi::whiteout_m2_M2AnimationTrackI16_resize_timestamps(self.raw.as_ptr(), count) }
9562    }
9563
9564    pub fn resize_timestamps_inner(&mut self, outer: usize, count: usize) {
9565        // SAFETY: as above.
9566        unsafe {
9567            ffi::whiteout_m2_M2AnimationTrackI16_resize_timestamps_inner(
9568                self.raw.as_ptr(),
9569                outer,
9570                count,
9571            )
9572        }
9573    }
9574
9575    /// Number of inner sequences.
9576    pub fn values_len(&self) -> usize {
9577        // SAFETY: scalar read through a live handle.
9578        unsafe { ffi::whiteout_m2_M2AnimationTrackI16_get_values_count(self.raw.as_ptr()) }
9579    }
9580
9581    /// Zero-copy view of inner sequence `outer`. Empty when out of range.
9582    ///
9583    /// Each inner vector is contiguous on its own, but the outer one
9584    /// is a vector of vectors — so this borrows per sequence rather
9585    /// than handing back one flat slice.
9586    pub fn values(&self, outer: usize) -> &[i16] {
9587        if outer >= self.values_len() {
9588            return &[];
9589        }
9590        // SAFETY: index checked; the pointer borrows `self`.
9591        unsafe {
9592            let n = ffi::whiteout_m2_M2AnimationTrackI16_get_values_inner_count(
9593                self.raw.as_ptr(),
9594                outer,
9595            );
9596            let p = ffi::whiteout_m2_M2AnimationTrackI16_get_values_inner_data(
9597                self.raw.as_ptr(),
9598                outer,
9599            );
9600            if p.is_null() || n == 0 {
9601                &[]
9602            } else {
9603                core::slice::from_raw_parts(p, n)
9604            }
9605        }
9606    }
9607
9608    pub fn values_mut(&mut self, outer: usize) -> &mut [i16] {
9609        if outer >= self.values_len() {
9610            return &mut [];
9611        }
9612        // SAFETY: as above; `&mut self` rules out aliasing.
9613        unsafe {
9614            let n = ffi::whiteout_m2_M2AnimationTrackI16_get_values_inner_count(
9615                self.raw.as_ptr(),
9616                outer,
9617            );
9618            let p = ffi::whiteout_m2_M2AnimationTrackI16_get_values_inner_data(
9619                self.raw.as_ptr(),
9620                outer,
9621            ) as *mut i16;
9622            if p.is_null() || n == 0 {
9623                &mut []
9624            } else {
9625                core::slice::from_raw_parts_mut(p, n)
9626            }
9627        }
9628    }
9629
9630    pub fn set_values(&mut self, outer: usize, values: &[i16]) {
9631        // SAFETY: the native side copies `values` before returning.
9632        unsafe {
9633            ffi::whiteout_m2_M2AnimationTrackI16_assign_values_inner(
9634                self.raw.as_ptr(),
9635                outer,
9636                values.as_ptr() as *const _,
9637                values.len(),
9638            )
9639        }
9640    }
9641
9642    /// Resize the outer sequence. Do this before taking any borrow.
9643    pub fn resize_values(&mut self, count: usize) {
9644        // SAFETY: exclusive access, so no borrow is outstanding.
9645        unsafe { ffi::whiteout_m2_M2AnimationTrackI16_resize_values(self.raw.as_ptr(), count) }
9646    }
9647
9648    pub fn resize_values_inner(&mut self, outer: usize, count: usize) {
9649        // SAFETY: as above.
9650        unsafe {
9651            ffi::whiteout_m2_M2AnimationTrackI16_resize_values_inner(
9652                self.raw.as_ptr(),
9653                outer,
9654                count,
9655            )
9656        }
9657    }
9658}
9659
9660impl Default for AnimationTrackI16 {
9661    fn default() -> Self {
9662        Self::new()
9663    }
9664}
9665
9666pub struct AnimationTrackF32 {
9667    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2AnimationTrackF32>,
9668}
9669
9670impl Drop for AnimationTrackF32 {
9671    fn drop(&mut self) {
9672        // SAFETY: `raw` came from a native constructor and Drop runs once.
9673        unsafe { ffi::whiteout_m2_M2AnimationTrackF32_delete(self.raw.as_ptr()) }
9674    }
9675}
9676
9677impl AnimationTrackF32 {
9678    /// # Safety
9679    /// `raw` must be a live handle this value takes ownership of.
9680    #[allow(dead_code)] // used by whichever methods return this type
9681    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2AnimationTrackF32) -> Option<Self> {
9682        core::ptr::NonNull::new(raw).map(|raw| AnimationTrackF32 { raw })
9683    }
9684}
9685
9686// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
9687// is deliberately NOT implemented — the C++ types make no documented
9688// guarantee about concurrent use, and claiming one we haven't verified
9689// would be unsound. See `@bind thread_safe` in the plan.
9690unsafe impl Send for AnimationTrackF32 {}
9691
9692impl core::fmt::Debug for AnimationTrackF32 {
9693    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
9694        f.debug_struct("AnimationTrackF32").finish_non_exhaustive()
9695    }
9696}
9697
9698impl AnimationTrackF32 {
9699    /// # Panics
9700    /// Panics if the native allocation fails.
9701    pub fn new() -> Self {
9702        // SAFETY: the native constructor returns a live handle; a null here
9703        // means the library is unusable.
9704        unsafe {
9705            let raw = ffi::whiteout_m2_M2AnimationTrackF32_new();
9706            Self::from_raw(raw).expect("native AnimationTrackF32 allocation failed")
9707        }
9708    }
9709
9710    pub fn interpolation_type(&self) -> InterpolationType {
9711        // SAFETY: scalar read; the discriminant is validated below.
9712        unsafe { ffi::whiteout_m2_M2AnimationTrackF32_get_interpolationType(self.raw.as_ptr()) }
9713            .try_into()
9714            .expect("unknown enum discriminant from the native library")
9715    }
9716
9717    pub fn set_interpolation_type(&mut self, value: InterpolationType) {
9718        // SAFETY: scalar write through a live handle.
9719        unsafe {
9720            ffi::whiteout_m2_M2AnimationTrackF32_set_interpolationType(
9721                self.raw.as_ptr(),
9722                value as i32,
9723            )
9724        }
9725    }
9726
9727    pub fn global_sequence_id(&self) -> u16 {
9728        // SAFETY: plain scalar read through a live handle.
9729        unsafe { ffi::whiteout_m2_M2AnimationTrackF32_get_globalSequenceId(self.raw.as_ptr()) }
9730    }
9731
9732    pub fn set_global_sequence_id(&mut self, value: u16) {
9733        // SAFETY: plain scalar write through a live handle.
9734        unsafe {
9735            ffi::whiteout_m2_M2AnimationTrackF32_set_globalSequenceId(self.raw.as_ptr(), value)
9736        }
9737    }
9738
9739    /// Number of inner sequences.
9740    pub fn timestamps_len(&self) -> usize {
9741        // SAFETY: scalar read through a live handle.
9742        unsafe { ffi::whiteout_m2_M2AnimationTrackF32_get_timestamps_count(self.raw.as_ptr()) }
9743    }
9744
9745    /// Zero-copy view of inner sequence `outer`. Empty when out of range.
9746    ///
9747    /// Each inner vector is contiguous on its own, but the outer one
9748    /// is a vector of vectors — so this borrows per sequence rather
9749    /// than handing back one flat slice.
9750    pub fn timestamps(&self, outer: usize) -> &[u32] {
9751        if outer >= self.timestamps_len() {
9752            return &[];
9753        }
9754        // SAFETY: index checked; the pointer borrows `self`.
9755        unsafe {
9756            let n = ffi::whiteout_m2_M2AnimationTrackF32_get_timestamps_inner_count(
9757                self.raw.as_ptr(),
9758                outer,
9759            );
9760            let p = ffi::whiteout_m2_M2AnimationTrackF32_get_timestamps_inner_data(
9761                self.raw.as_ptr(),
9762                outer,
9763            );
9764            if p.is_null() || n == 0 {
9765                &[]
9766            } else {
9767                core::slice::from_raw_parts(p, n)
9768            }
9769        }
9770    }
9771
9772    pub fn timestamps_mut(&mut self, outer: usize) -> &mut [u32] {
9773        if outer >= self.timestamps_len() {
9774            return &mut [];
9775        }
9776        // SAFETY: as above; `&mut self` rules out aliasing.
9777        unsafe {
9778            let n = ffi::whiteout_m2_M2AnimationTrackF32_get_timestamps_inner_count(
9779                self.raw.as_ptr(),
9780                outer,
9781            );
9782            let p = ffi::whiteout_m2_M2AnimationTrackF32_get_timestamps_inner_data(
9783                self.raw.as_ptr(),
9784                outer,
9785            ) as *mut u32;
9786            if p.is_null() || n == 0 {
9787                &mut []
9788            } else {
9789                core::slice::from_raw_parts_mut(p, n)
9790            }
9791        }
9792    }
9793
9794    pub fn set_timestamps(&mut self, outer: usize, values: &[u32]) {
9795        // SAFETY: the native side copies `values` before returning.
9796        unsafe {
9797            ffi::whiteout_m2_M2AnimationTrackF32_assign_timestamps_inner(
9798                self.raw.as_ptr(),
9799                outer,
9800                values.as_ptr() as *const _,
9801                values.len(),
9802            )
9803        }
9804    }
9805
9806    /// Resize the outer sequence. Do this before taking any borrow.
9807    pub fn resize_timestamps(&mut self, count: usize) {
9808        // SAFETY: exclusive access, so no borrow is outstanding.
9809        unsafe { ffi::whiteout_m2_M2AnimationTrackF32_resize_timestamps(self.raw.as_ptr(), count) }
9810    }
9811
9812    pub fn resize_timestamps_inner(&mut self, outer: usize, count: usize) {
9813        // SAFETY: as above.
9814        unsafe {
9815            ffi::whiteout_m2_M2AnimationTrackF32_resize_timestamps_inner(
9816                self.raw.as_ptr(),
9817                outer,
9818                count,
9819            )
9820        }
9821    }
9822
9823    /// Number of inner sequences.
9824    pub fn values_len(&self) -> usize {
9825        // SAFETY: scalar read through a live handle.
9826        unsafe { ffi::whiteout_m2_M2AnimationTrackF32_get_values_count(self.raw.as_ptr()) }
9827    }
9828
9829    /// Zero-copy view of inner sequence `outer`. Empty when out of range.
9830    ///
9831    /// Each inner vector is contiguous on its own, but the outer one
9832    /// is a vector of vectors — so this borrows per sequence rather
9833    /// than handing back one flat slice.
9834    pub fn values(&self, outer: usize) -> &[f32] {
9835        if outer >= self.values_len() {
9836            return &[];
9837        }
9838        // SAFETY: index checked; the pointer borrows `self`.
9839        unsafe {
9840            let n = ffi::whiteout_m2_M2AnimationTrackF32_get_values_inner_count(
9841                self.raw.as_ptr(),
9842                outer,
9843            );
9844            let p = ffi::whiteout_m2_M2AnimationTrackF32_get_values_inner_data(
9845                self.raw.as_ptr(),
9846                outer,
9847            );
9848            if p.is_null() || n == 0 {
9849                &[]
9850            } else {
9851                core::slice::from_raw_parts(p, n)
9852            }
9853        }
9854    }
9855
9856    pub fn values_mut(&mut self, outer: usize) -> &mut [f32] {
9857        if outer >= self.values_len() {
9858            return &mut [];
9859        }
9860        // SAFETY: as above; `&mut self` rules out aliasing.
9861        unsafe {
9862            let n = ffi::whiteout_m2_M2AnimationTrackF32_get_values_inner_count(
9863                self.raw.as_ptr(),
9864                outer,
9865            );
9866            let p = ffi::whiteout_m2_M2AnimationTrackF32_get_values_inner_data(
9867                self.raw.as_ptr(),
9868                outer,
9869            ) as *mut f32;
9870            if p.is_null() || n == 0 {
9871                &mut []
9872            } else {
9873                core::slice::from_raw_parts_mut(p, n)
9874            }
9875        }
9876    }
9877
9878    pub fn set_values(&mut self, outer: usize, values: &[f32]) {
9879        // SAFETY: the native side copies `values` before returning.
9880        unsafe {
9881            ffi::whiteout_m2_M2AnimationTrackF32_assign_values_inner(
9882                self.raw.as_ptr(),
9883                outer,
9884                values.as_ptr() as *const _,
9885                values.len(),
9886            )
9887        }
9888    }
9889
9890    /// Resize the outer sequence. Do this before taking any borrow.
9891    pub fn resize_values(&mut self, count: usize) {
9892        // SAFETY: exclusive access, so no borrow is outstanding.
9893        unsafe { ffi::whiteout_m2_M2AnimationTrackF32_resize_values(self.raw.as_ptr(), count) }
9894    }
9895
9896    pub fn resize_values_inner(&mut self, outer: usize, count: usize) {
9897        // SAFETY: as above.
9898        unsafe {
9899            ffi::whiteout_m2_M2AnimationTrackF32_resize_values_inner(
9900                self.raw.as_ptr(),
9901                outer,
9902                count,
9903            )
9904        }
9905    }
9906}
9907
9908impl Default for AnimationTrackF32 {
9909    fn default() -> Self {
9910        Self::new()
9911    }
9912}
9913
9914pub struct AnimationTrackU8 {
9915    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2AnimationTrackU8>,
9916}
9917
9918impl Drop for AnimationTrackU8 {
9919    fn drop(&mut self) {
9920        // SAFETY: `raw` came from a native constructor and Drop runs once.
9921        unsafe { ffi::whiteout_m2_M2AnimationTrackU8_delete(self.raw.as_ptr()) }
9922    }
9923}
9924
9925impl AnimationTrackU8 {
9926    /// # Safety
9927    /// `raw` must be a live handle this value takes ownership of.
9928    #[allow(dead_code)] // used by whichever methods return this type
9929    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2AnimationTrackU8) -> Option<Self> {
9930        core::ptr::NonNull::new(raw).map(|raw| AnimationTrackU8 { raw })
9931    }
9932}
9933
9934// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
9935// is deliberately NOT implemented — the C++ types make no documented
9936// guarantee about concurrent use, and claiming one we haven't verified
9937// would be unsound. See `@bind thread_safe` in the plan.
9938unsafe impl Send for AnimationTrackU8 {}
9939
9940impl core::fmt::Debug for AnimationTrackU8 {
9941    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
9942        f.debug_struct("AnimationTrackU8").finish_non_exhaustive()
9943    }
9944}
9945
9946impl AnimationTrackU8 {
9947    /// # Panics
9948    /// Panics if the native allocation fails.
9949    pub fn new() -> Self {
9950        // SAFETY: the native constructor returns a live handle; a null here
9951        // means the library is unusable.
9952        unsafe {
9953            let raw = ffi::whiteout_m2_M2AnimationTrackU8_new();
9954            Self::from_raw(raw).expect("native AnimationTrackU8 allocation failed")
9955        }
9956    }
9957
9958    pub fn interpolation_type(&self) -> InterpolationType {
9959        // SAFETY: scalar read; the discriminant is validated below.
9960        unsafe { ffi::whiteout_m2_M2AnimationTrackU8_get_interpolationType(self.raw.as_ptr()) }
9961            .try_into()
9962            .expect("unknown enum discriminant from the native library")
9963    }
9964
9965    pub fn set_interpolation_type(&mut self, value: InterpolationType) {
9966        // SAFETY: scalar write through a live handle.
9967        unsafe {
9968            ffi::whiteout_m2_M2AnimationTrackU8_set_interpolationType(
9969                self.raw.as_ptr(),
9970                value as i32,
9971            )
9972        }
9973    }
9974
9975    pub fn global_sequence_id(&self) -> u16 {
9976        // SAFETY: plain scalar read through a live handle.
9977        unsafe { ffi::whiteout_m2_M2AnimationTrackU8_get_globalSequenceId(self.raw.as_ptr()) }
9978    }
9979
9980    pub fn set_global_sequence_id(&mut self, value: u16) {
9981        // SAFETY: plain scalar write through a live handle.
9982        unsafe {
9983            ffi::whiteout_m2_M2AnimationTrackU8_set_globalSequenceId(self.raw.as_ptr(), value)
9984        }
9985    }
9986
9987    /// Number of inner sequences.
9988    pub fn timestamps_len(&self) -> usize {
9989        // SAFETY: scalar read through a live handle.
9990        unsafe { ffi::whiteout_m2_M2AnimationTrackU8_get_timestamps_count(self.raw.as_ptr()) }
9991    }
9992
9993    /// Zero-copy view of inner sequence `outer`. Empty when out of range.
9994    ///
9995    /// Each inner vector is contiguous on its own, but the outer one
9996    /// is a vector of vectors — so this borrows per sequence rather
9997    /// than handing back one flat slice.
9998    pub fn timestamps(&self, outer: usize) -> &[u32] {
9999        if outer >= self.timestamps_len() {
10000            return &[];
10001        }
10002        // SAFETY: index checked; the pointer borrows `self`.
10003        unsafe {
10004            let n = ffi::whiteout_m2_M2AnimationTrackU8_get_timestamps_inner_count(
10005                self.raw.as_ptr(),
10006                outer,
10007            );
10008            let p = ffi::whiteout_m2_M2AnimationTrackU8_get_timestamps_inner_data(
10009                self.raw.as_ptr(),
10010                outer,
10011            );
10012            if p.is_null() || n == 0 {
10013                &[]
10014            } else {
10015                core::slice::from_raw_parts(p, n)
10016            }
10017        }
10018    }
10019
10020    pub fn timestamps_mut(&mut self, outer: usize) -> &mut [u32] {
10021        if outer >= self.timestamps_len() {
10022            return &mut [];
10023        }
10024        // SAFETY: as above; `&mut self` rules out aliasing.
10025        unsafe {
10026            let n = ffi::whiteout_m2_M2AnimationTrackU8_get_timestamps_inner_count(
10027                self.raw.as_ptr(),
10028                outer,
10029            );
10030            let p = ffi::whiteout_m2_M2AnimationTrackU8_get_timestamps_inner_data(
10031                self.raw.as_ptr(),
10032                outer,
10033            ) as *mut u32;
10034            if p.is_null() || n == 0 {
10035                &mut []
10036            } else {
10037                core::slice::from_raw_parts_mut(p, n)
10038            }
10039        }
10040    }
10041
10042    pub fn set_timestamps(&mut self, outer: usize, values: &[u32]) {
10043        // SAFETY: the native side copies `values` before returning.
10044        unsafe {
10045            ffi::whiteout_m2_M2AnimationTrackU8_assign_timestamps_inner(
10046                self.raw.as_ptr(),
10047                outer,
10048                values.as_ptr() as *const _,
10049                values.len(),
10050            )
10051        }
10052    }
10053
10054    /// Resize the outer sequence. Do this before taking any borrow.
10055    pub fn resize_timestamps(&mut self, count: usize) {
10056        // SAFETY: exclusive access, so no borrow is outstanding.
10057        unsafe { ffi::whiteout_m2_M2AnimationTrackU8_resize_timestamps(self.raw.as_ptr(), count) }
10058    }
10059
10060    pub fn resize_timestamps_inner(&mut self, outer: usize, count: usize) {
10061        // SAFETY: as above.
10062        unsafe {
10063            ffi::whiteout_m2_M2AnimationTrackU8_resize_timestamps_inner(
10064                self.raw.as_ptr(),
10065                outer,
10066                count,
10067            )
10068        }
10069    }
10070
10071    /// Number of inner sequences.
10072    pub fn values_len(&self) -> usize {
10073        // SAFETY: scalar read through a live handle.
10074        unsafe { ffi::whiteout_m2_M2AnimationTrackU8_get_values_count(self.raw.as_ptr()) }
10075    }
10076
10077    /// Zero-copy view of inner sequence `outer`. Empty when out of range.
10078    ///
10079    /// Each inner vector is contiguous on its own, but the outer one
10080    /// is a vector of vectors — so this borrows per sequence rather
10081    /// than handing back one flat slice.
10082    pub fn values(&self, outer: usize) -> &[u8] {
10083        if outer >= self.values_len() {
10084            return &[];
10085        }
10086        // SAFETY: index checked; the pointer borrows `self`.
10087        unsafe {
10088            let n = ffi::whiteout_m2_M2AnimationTrackU8_get_values_inner_count(
10089                self.raw.as_ptr(),
10090                outer,
10091            );
10092            let p =
10093                ffi::whiteout_m2_M2AnimationTrackU8_get_values_inner_data(self.raw.as_ptr(), outer);
10094            if p.is_null() || n == 0 {
10095                &[]
10096            } else {
10097                core::slice::from_raw_parts(p, n)
10098            }
10099        }
10100    }
10101
10102    pub fn values_mut(&mut self, outer: usize) -> &mut [u8] {
10103        if outer >= self.values_len() {
10104            return &mut [];
10105        }
10106        // SAFETY: as above; `&mut self` rules out aliasing.
10107        unsafe {
10108            let n = ffi::whiteout_m2_M2AnimationTrackU8_get_values_inner_count(
10109                self.raw.as_ptr(),
10110                outer,
10111            );
10112            let p =
10113                ffi::whiteout_m2_M2AnimationTrackU8_get_values_inner_data(self.raw.as_ptr(), outer)
10114                    as *mut u8;
10115            if p.is_null() || n == 0 {
10116                &mut []
10117            } else {
10118                core::slice::from_raw_parts_mut(p, n)
10119            }
10120        }
10121    }
10122
10123    pub fn set_values(&mut self, outer: usize, values: &[u8]) {
10124        // SAFETY: the native side copies `values` before returning.
10125        unsafe {
10126            ffi::whiteout_m2_M2AnimationTrackU8_assign_values_inner(
10127                self.raw.as_ptr(),
10128                outer,
10129                values.as_ptr() as *const _,
10130                values.len(),
10131            )
10132        }
10133    }
10134
10135    /// Resize the outer sequence. Do this before taking any borrow.
10136    pub fn resize_values(&mut self, count: usize) {
10137        // SAFETY: exclusive access, so no borrow is outstanding.
10138        unsafe { ffi::whiteout_m2_M2AnimationTrackU8_resize_values(self.raw.as_ptr(), count) }
10139    }
10140
10141    pub fn resize_values_inner(&mut self, outer: usize, count: usize) {
10142        // SAFETY: as above.
10143        unsafe {
10144            ffi::whiteout_m2_M2AnimationTrackU8_resize_values_inner(self.raw.as_ptr(), outer, count)
10145        }
10146    }
10147}
10148
10149impl Default for AnimationTrackU8 {
10150    fn default() -> Self {
10151        Self::new()
10152    }
10153}
10154
10155pub struct AnimationTrackM2CameraSpline {
10156    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2AnimationTrackM2CameraSpline>,
10157}
10158
10159impl Drop for AnimationTrackM2CameraSpline {
10160    fn drop(&mut self) {
10161        // SAFETY: `raw` came from a native constructor and Drop runs once.
10162        unsafe { ffi::whiteout_m2_M2AnimationTrackM2CameraSpline_delete(self.raw.as_ptr()) }
10163    }
10164}
10165
10166impl AnimationTrackM2CameraSpline {
10167    /// # Safety
10168    /// `raw` must be a live handle this value takes ownership of.
10169    #[allow(dead_code)] // used by whichever methods return this type
10170    pub(crate) unsafe fn from_raw(
10171        raw: *mut ffi::whiteout_M2AnimationTrackM2CameraSpline,
10172    ) -> Option<Self> {
10173        core::ptr::NonNull::new(raw).map(|raw| AnimationTrackM2CameraSpline { raw })
10174    }
10175}
10176
10177// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
10178// is deliberately NOT implemented — the C++ types make no documented
10179// guarantee about concurrent use, and claiming one we haven't verified
10180// would be unsound. See `@bind thread_safe` in the plan.
10181unsafe impl Send for AnimationTrackM2CameraSpline {}
10182
10183impl core::fmt::Debug for AnimationTrackM2CameraSpline {
10184    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
10185        f.debug_struct("AnimationTrackM2CameraSpline")
10186            .finish_non_exhaustive()
10187    }
10188}
10189
10190impl AnimationTrackM2CameraSpline {
10191    /// # Panics
10192    /// Panics if the native allocation fails.
10193    pub fn new() -> Self {
10194        // SAFETY: the native constructor returns a live handle; a null here
10195        // means the library is unusable.
10196        unsafe {
10197            let raw = ffi::whiteout_m2_M2AnimationTrackM2CameraSpline_new();
10198            Self::from_raw(raw).expect("native AnimationTrackM2CameraSpline allocation failed")
10199        }
10200    }
10201
10202    pub fn interpolation_type(&self) -> InterpolationType {
10203        // SAFETY: scalar read; the discriminant is validated below.
10204        unsafe {
10205            ffi::whiteout_m2_M2AnimationTrackM2CameraSpline_get_interpolationType(self.raw.as_ptr())
10206        }
10207        .try_into()
10208        .expect("unknown enum discriminant from the native library")
10209    }
10210
10211    pub fn set_interpolation_type(&mut self, value: InterpolationType) {
10212        // SAFETY: scalar write through a live handle.
10213        unsafe {
10214            ffi::whiteout_m2_M2AnimationTrackM2CameraSpline_set_interpolationType(
10215                self.raw.as_ptr(),
10216                value as i32,
10217            )
10218        }
10219    }
10220
10221    pub fn global_sequence_id(&self) -> u16 {
10222        // SAFETY: plain scalar read through a live handle.
10223        unsafe {
10224            ffi::whiteout_m2_M2AnimationTrackM2CameraSpline_get_globalSequenceId(self.raw.as_ptr())
10225        }
10226    }
10227
10228    pub fn set_global_sequence_id(&mut self, value: u16) {
10229        // SAFETY: plain scalar write through a live handle.
10230        unsafe {
10231            ffi::whiteout_m2_M2AnimationTrackM2CameraSpline_set_globalSequenceId(
10232                self.raw.as_ptr(),
10233                value,
10234            )
10235        }
10236    }
10237
10238    /// Number of inner sequences.
10239    pub fn timestamps_len(&self) -> usize {
10240        // SAFETY: scalar read through a live handle.
10241        unsafe {
10242            ffi::whiteout_m2_M2AnimationTrackM2CameraSpline_get_timestamps_count(self.raw.as_ptr())
10243        }
10244    }
10245
10246    /// Zero-copy view of inner sequence `outer`. Empty when out of range.
10247    ///
10248    /// Each inner vector is contiguous on its own, but the outer one
10249    /// is a vector of vectors — so this borrows per sequence rather
10250    /// than handing back one flat slice.
10251    pub fn timestamps(&self, outer: usize) -> &[u32] {
10252        if outer >= self.timestamps_len() {
10253            return &[];
10254        }
10255        // SAFETY: index checked; the pointer borrows `self`.
10256        unsafe {
10257            let n = ffi::whiteout_m2_M2AnimationTrackM2CameraSpline_get_timestamps_inner_count(
10258                self.raw.as_ptr(),
10259                outer,
10260            );
10261            let p = ffi::whiteout_m2_M2AnimationTrackM2CameraSpline_get_timestamps_inner_data(
10262                self.raw.as_ptr(),
10263                outer,
10264            );
10265            if p.is_null() || n == 0 {
10266                &[]
10267            } else {
10268                core::slice::from_raw_parts(p, n)
10269            }
10270        }
10271    }
10272
10273    pub fn timestamps_mut(&mut self, outer: usize) -> &mut [u32] {
10274        if outer >= self.timestamps_len() {
10275            return &mut [];
10276        }
10277        // SAFETY: as above; `&mut self` rules out aliasing.
10278        unsafe {
10279            let n = ffi::whiteout_m2_M2AnimationTrackM2CameraSpline_get_timestamps_inner_count(
10280                self.raw.as_ptr(),
10281                outer,
10282            );
10283            let p = ffi::whiteout_m2_M2AnimationTrackM2CameraSpline_get_timestamps_inner_data(
10284                self.raw.as_ptr(),
10285                outer,
10286            ) as *mut u32;
10287            if p.is_null() || n == 0 {
10288                &mut []
10289            } else {
10290                core::slice::from_raw_parts_mut(p, n)
10291            }
10292        }
10293    }
10294
10295    pub fn set_timestamps(&mut self, outer: usize, values: &[u32]) {
10296        // SAFETY: the native side copies `values` before returning.
10297        unsafe {
10298            ffi::whiteout_m2_M2AnimationTrackM2CameraSpline_assign_timestamps_inner(
10299                self.raw.as_ptr(),
10300                outer,
10301                values.as_ptr() as *const _,
10302                values.len(),
10303            )
10304        }
10305    }
10306
10307    /// Resize the outer sequence. Do this before taking any borrow.
10308    pub fn resize_timestamps(&mut self, count: usize) {
10309        // SAFETY: exclusive access, so no borrow is outstanding.
10310        unsafe {
10311            ffi::whiteout_m2_M2AnimationTrackM2CameraSpline_resize_timestamps(
10312                self.raw.as_ptr(),
10313                count,
10314            )
10315        }
10316    }
10317
10318    pub fn resize_timestamps_inner(&mut self, outer: usize, count: usize) {
10319        // SAFETY: as above.
10320        unsafe {
10321            ffi::whiteout_m2_M2AnimationTrackM2CameraSpline_resize_timestamps_inner(
10322                self.raw.as_ptr(),
10323                outer,
10324                count,
10325            )
10326        }
10327    }
10328
10329    /// Number of inner sequences.
10330    pub fn values_len(&self) -> usize {
10331        // SAFETY: scalar read through a live handle.
10332        unsafe {
10333            ffi::whiteout_m2_M2AnimationTrackM2CameraSpline_get_values_count(self.raw.as_ptr())
10334        }
10335    }
10336
10337    /// Length of inner sequence `outer`.
10338    pub fn values_inner_len(&self, outer: usize) -> usize {
10339        if outer >= self.values_len() {
10340            return 0;
10341        }
10342        // SAFETY: index checked above.
10343        unsafe {
10344            ffi::whiteout_m2_M2AnimationTrackM2CameraSpline_get_values_inner_count(
10345                self.raw.as_ptr(),
10346                outer,
10347            )
10348        }
10349    }
10350
10351    /// Borrow element `inner` of sequence `outer` in place.
10352    pub fn values(
10353        &self,
10354        outer: usize,
10355        inner: usize,
10356    ) -> Option<crate::support::Ref<'_, CameraSpline>> {
10357        if inner >= self.values_inner_len(outer) {
10358            return None;
10359        }
10360        // SAFETY: both indices checked; the pointer is
10361        // interior to `self`.
10362        unsafe {
10363            Some(crate::support::Ref::new(CameraSpline {
10364                raw: core::ptr::NonNull::new_unchecked(
10365                    ffi::whiteout_m2_M2AnimationTrackM2CameraSpline_get_values_at(
10366                        self.raw.as_ptr(),
10367                        outer,
10368                        inner,
10369                    ),
10370                ),
10371            }))
10372        }
10373    }
10374
10375    pub fn values_mut(
10376        &mut self,
10377        outer: usize,
10378        inner: usize,
10379    ) -> Option<crate::support::RefMut<'_, CameraSpline>> {
10380        if inner >= self.values_inner_len(outer) {
10381            return None;
10382        }
10383        // SAFETY: as above; `&mut self` guarantees exclusivity.
10384        unsafe {
10385            Some(crate::support::RefMut::new(CameraSpline {
10386                raw: core::ptr::NonNull::new_unchecked(
10387                    ffi::whiteout_m2_M2AnimationTrackM2CameraSpline_get_values_at(
10388                        self.raw.as_ptr(),
10389                        outer,
10390                        inner,
10391                    ),
10392                ),
10393            }))
10394        }
10395    }
10396
10397    /// Resize the outer sequence. Do this before taking a borrow.
10398    pub fn resize_values(&mut self, count: usize) {
10399        // SAFETY: exclusive access, so no borrow is outstanding.
10400        unsafe {
10401            ffi::whiteout_m2_M2AnimationTrackM2CameraSpline_resize_values(self.raw.as_ptr(), count)
10402        }
10403    }
10404
10405    pub fn resize_values_inner(&mut self, outer: usize, count: usize) {
10406        // SAFETY: as above.
10407        unsafe {
10408            ffi::whiteout_m2_M2AnimationTrackM2CameraSpline_resize_values_inner(
10409                self.raw.as_ptr(),
10410                outer,
10411                count,
10412            )
10413        }
10414    }
10415}
10416
10417impl Default for AnimationTrackM2CameraSpline {
10418    fn default() -> Self {
10419        Self::new()
10420    }
10421}
10422
10423pub struct AnimationTrackU16 {
10424    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2AnimationTrackU16>,
10425}
10426
10427impl Drop for AnimationTrackU16 {
10428    fn drop(&mut self) {
10429        // SAFETY: `raw` came from a native constructor and Drop runs once.
10430        unsafe { ffi::whiteout_m2_M2AnimationTrackU16_delete(self.raw.as_ptr()) }
10431    }
10432}
10433
10434impl AnimationTrackU16 {
10435    /// # Safety
10436    /// `raw` must be a live handle this value takes ownership of.
10437    #[allow(dead_code)] // used by whichever methods return this type
10438    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2AnimationTrackU16) -> Option<Self> {
10439        core::ptr::NonNull::new(raw).map(|raw| AnimationTrackU16 { raw })
10440    }
10441}
10442
10443// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
10444// is deliberately NOT implemented — the C++ types make no documented
10445// guarantee about concurrent use, and claiming one we haven't verified
10446// would be unsound. See `@bind thread_safe` in the plan.
10447unsafe impl Send for AnimationTrackU16 {}
10448
10449impl core::fmt::Debug for AnimationTrackU16 {
10450    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
10451        f.debug_struct("AnimationTrackU16").finish_non_exhaustive()
10452    }
10453}
10454
10455impl AnimationTrackU16 {
10456    /// # Panics
10457    /// Panics if the native allocation fails.
10458    pub fn new() -> Self {
10459        // SAFETY: the native constructor returns a live handle; a null here
10460        // means the library is unusable.
10461        unsafe {
10462            let raw = ffi::whiteout_m2_M2AnimationTrackU16_new();
10463            Self::from_raw(raw).expect("native AnimationTrackU16 allocation failed")
10464        }
10465    }
10466
10467    pub fn interpolation_type(&self) -> InterpolationType {
10468        // SAFETY: scalar read; the discriminant is validated below.
10469        unsafe { ffi::whiteout_m2_M2AnimationTrackU16_get_interpolationType(self.raw.as_ptr()) }
10470            .try_into()
10471            .expect("unknown enum discriminant from the native library")
10472    }
10473
10474    pub fn set_interpolation_type(&mut self, value: InterpolationType) {
10475        // SAFETY: scalar write through a live handle.
10476        unsafe {
10477            ffi::whiteout_m2_M2AnimationTrackU16_set_interpolationType(
10478                self.raw.as_ptr(),
10479                value as i32,
10480            )
10481        }
10482    }
10483
10484    pub fn global_sequence_id(&self) -> u16 {
10485        // SAFETY: plain scalar read through a live handle.
10486        unsafe { ffi::whiteout_m2_M2AnimationTrackU16_get_globalSequenceId(self.raw.as_ptr()) }
10487    }
10488
10489    pub fn set_global_sequence_id(&mut self, value: u16) {
10490        // SAFETY: plain scalar write through a live handle.
10491        unsafe {
10492            ffi::whiteout_m2_M2AnimationTrackU16_set_globalSequenceId(self.raw.as_ptr(), value)
10493        }
10494    }
10495
10496    /// Number of inner sequences.
10497    pub fn timestamps_len(&self) -> usize {
10498        // SAFETY: scalar read through a live handle.
10499        unsafe { ffi::whiteout_m2_M2AnimationTrackU16_get_timestamps_count(self.raw.as_ptr()) }
10500    }
10501
10502    /// Zero-copy view of inner sequence `outer`. Empty when out of range.
10503    ///
10504    /// Each inner vector is contiguous on its own, but the outer one
10505    /// is a vector of vectors — so this borrows per sequence rather
10506    /// than handing back one flat slice.
10507    pub fn timestamps(&self, outer: usize) -> &[u32] {
10508        if outer >= self.timestamps_len() {
10509            return &[];
10510        }
10511        // SAFETY: index checked; the pointer borrows `self`.
10512        unsafe {
10513            let n = ffi::whiteout_m2_M2AnimationTrackU16_get_timestamps_inner_count(
10514                self.raw.as_ptr(),
10515                outer,
10516            );
10517            let p = ffi::whiteout_m2_M2AnimationTrackU16_get_timestamps_inner_data(
10518                self.raw.as_ptr(),
10519                outer,
10520            );
10521            if p.is_null() || n == 0 {
10522                &[]
10523            } else {
10524                core::slice::from_raw_parts(p, n)
10525            }
10526        }
10527    }
10528
10529    pub fn timestamps_mut(&mut self, outer: usize) -> &mut [u32] {
10530        if outer >= self.timestamps_len() {
10531            return &mut [];
10532        }
10533        // SAFETY: as above; `&mut self` rules out aliasing.
10534        unsafe {
10535            let n = ffi::whiteout_m2_M2AnimationTrackU16_get_timestamps_inner_count(
10536                self.raw.as_ptr(),
10537                outer,
10538            );
10539            let p = ffi::whiteout_m2_M2AnimationTrackU16_get_timestamps_inner_data(
10540                self.raw.as_ptr(),
10541                outer,
10542            ) as *mut u32;
10543            if p.is_null() || n == 0 {
10544                &mut []
10545            } else {
10546                core::slice::from_raw_parts_mut(p, n)
10547            }
10548        }
10549    }
10550
10551    pub fn set_timestamps(&mut self, outer: usize, values: &[u32]) {
10552        // SAFETY: the native side copies `values` before returning.
10553        unsafe {
10554            ffi::whiteout_m2_M2AnimationTrackU16_assign_timestamps_inner(
10555                self.raw.as_ptr(),
10556                outer,
10557                values.as_ptr() as *const _,
10558                values.len(),
10559            )
10560        }
10561    }
10562
10563    /// Resize the outer sequence. Do this before taking any borrow.
10564    pub fn resize_timestamps(&mut self, count: usize) {
10565        // SAFETY: exclusive access, so no borrow is outstanding.
10566        unsafe { ffi::whiteout_m2_M2AnimationTrackU16_resize_timestamps(self.raw.as_ptr(), count) }
10567    }
10568
10569    pub fn resize_timestamps_inner(&mut self, outer: usize, count: usize) {
10570        // SAFETY: as above.
10571        unsafe {
10572            ffi::whiteout_m2_M2AnimationTrackU16_resize_timestamps_inner(
10573                self.raw.as_ptr(),
10574                outer,
10575                count,
10576            )
10577        }
10578    }
10579
10580    /// Number of inner sequences.
10581    pub fn values_len(&self) -> usize {
10582        // SAFETY: scalar read through a live handle.
10583        unsafe { ffi::whiteout_m2_M2AnimationTrackU16_get_values_count(self.raw.as_ptr()) }
10584    }
10585
10586    /// Zero-copy view of inner sequence `outer`. Empty when out of range.
10587    ///
10588    /// Each inner vector is contiguous on its own, but the outer one
10589    /// is a vector of vectors — so this borrows per sequence rather
10590    /// than handing back one flat slice.
10591    pub fn values(&self, outer: usize) -> &[u16] {
10592        if outer >= self.values_len() {
10593            return &[];
10594        }
10595        // SAFETY: index checked; the pointer borrows `self`.
10596        unsafe {
10597            let n = ffi::whiteout_m2_M2AnimationTrackU16_get_values_inner_count(
10598                self.raw.as_ptr(),
10599                outer,
10600            );
10601            let p = ffi::whiteout_m2_M2AnimationTrackU16_get_values_inner_data(
10602                self.raw.as_ptr(),
10603                outer,
10604            );
10605            if p.is_null() || n == 0 {
10606                &[]
10607            } else {
10608                core::slice::from_raw_parts(p, n)
10609            }
10610        }
10611    }
10612
10613    pub fn values_mut(&mut self, outer: usize) -> &mut [u16] {
10614        if outer >= self.values_len() {
10615            return &mut [];
10616        }
10617        // SAFETY: as above; `&mut self` rules out aliasing.
10618        unsafe {
10619            let n = ffi::whiteout_m2_M2AnimationTrackU16_get_values_inner_count(
10620                self.raw.as_ptr(),
10621                outer,
10622            );
10623            let p = ffi::whiteout_m2_M2AnimationTrackU16_get_values_inner_data(
10624                self.raw.as_ptr(),
10625                outer,
10626            ) as *mut u16;
10627            if p.is_null() || n == 0 {
10628                &mut []
10629            } else {
10630                core::slice::from_raw_parts_mut(p, n)
10631            }
10632        }
10633    }
10634
10635    pub fn set_values(&mut self, outer: usize, values: &[u16]) {
10636        // SAFETY: the native side copies `values` before returning.
10637        unsafe {
10638            ffi::whiteout_m2_M2AnimationTrackU16_assign_values_inner(
10639                self.raw.as_ptr(),
10640                outer,
10641                values.as_ptr() as *const _,
10642                values.len(),
10643            )
10644        }
10645    }
10646
10647    /// Resize the outer sequence. Do this before taking any borrow.
10648    pub fn resize_values(&mut self, count: usize) {
10649        // SAFETY: exclusive access, so no borrow is outstanding.
10650        unsafe { ffi::whiteout_m2_M2AnimationTrackU16_resize_values(self.raw.as_ptr(), count) }
10651    }
10652
10653    pub fn resize_values_inner(&mut self, outer: usize, count: usize) {
10654        // SAFETY: as above.
10655        unsafe {
10656            ffi::whiteout_m2_M2AnimationTrackU16_resize_values_inner(
10657                self.raw.as_ptr(),
10658                outer,
10659                count,
10660            )
10661        }
10662    }
10663}
10664
10665impl Default for AnimationTrackU16 {
10666    fn default() -> Self {
10667        Self::new()
10668    }
10669}
10670
10671pub struct ParticleAnimationTrackVector3f {
10672    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2ParticleAnimationTrackVector3f>,
10673}
10674
10675impl Drop for ParticleAnimationTrackVector3f {
10676    fn drop(&mut self) {
10677        // SAFETY: `raw` came from a native constructor and Drop runs once.
10678        unsafe { ffi::whiteout_m2_M2ParticleAnimationTrackVector3f_delete(self.raw.as_ptr()) }
10679    }
10680}
10681
10682impl ParticleAnimationTrackVector3f {
10683    /// # Safety
10684    /// `raw` must be a live handle this value takes ownership of.
10685    #[allow(dead_code)] // used by whichever methods return this type
10686    pub(crate) unsafe fn from_raw(
10687        raw: *mut ffi::whiteout_M2ParticleAnimationTrackVector3f,
10688    ) -> Option<Self> {
10689        core::ptr::NonNull::new(raw).map(|raw| ParticleAnimationTrackVector3f { raw })
10690    }
10691}
10692
10693// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
10694// is deliberately NOT implemented — the C++ types make no documented
10695// guarantee about concurrent use, and claiming one we haven't verified
10696// would be unsound. See `@bind thread_safe` in the plan.
10697unsafe impl Send for ParticleAnimationTrackVector3f {}
10698
10699impl core::fmt::Debug for ParticleAnimationTrackVector3f {
10700    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
10701        f.debug_struct("ParticleAnimationTrackVector3f")
10702            .finish_non_exhaustive()
10703    }
10704}
10705
10706impl ParticleAnimationTrackVector3f {
10707    /// # Panics
10708    /// Panics if the native allocation fails.
10709    pub fn new() -> Self {
10710        // SAFETY: the native constructor returns a live handle; a null here
10711        // means the library is unusable.
10712        unsafe {
10713            let raw = ffi::whiteout_m2_M2ParticleAnimationTrackVector3f_new();
10714            Self::from_raw(raw).expect("native ParticleAnimationTrackVector3f allocation failed")
10715        }
10716    }
10717
10718    /// Zero-copy view of the underlying `std::vector`.
10719    pub fn values(&self) -> &[crate::math::Vector3f] {
10720        // SAFETY: `_data`/`_count` describe one contiguous C++
10721        // allocation, borrowed for as long as `self` is.
10722        unsafe {
10723            let n = ffi::whiteout_m2_M2ParticleAnimationTrackVector3f_get_values_count(
10724                self.raw.as_ptr(),
10725            );
10726            let p = ffi::whiteout_m2_M2ParticleAnimationTrackVector3f_get_values_data(
10727                self.raw.as_ptr(),
10728            ) as *const crate::math::Vector3f;
10729            if p.is_null() || n == 0 {
10730                &[]
10731            } else {
10732                core::slice::from_raw_parts(p, n)
10733            }
10734        }
10735    }
10736
10737    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
10738    pub fn values_mut(&mut self) -> &mut [crate::math::Vector3f] {
10739        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
10740        unsafe {
10741            let n = ffi::whiteout_m2_M2ParticleAnimationTrackVector3f_get_values_count(
10742                self.raw.as_ptr(),
10743            );
10744            let p = ffi::whiteout_m2_M2ParticleAnimationTrackVector3f_get_values_data(
10745                self.raw.as_ptr(),
10746            ) as *const crate::math::Vector3f as *mut crate::math::Vector3f;
10747            if p.is_null() || n == 0 {
10748                &mut []
10749            } else {
10750                core::slice::from_raw_parts_mut(p, n)
10751            }
10752        }
10753    }
10754
10755    pub fn set_values(&mut self, values: &[crate::math::Vector3f]) {
10756        // SAFETY: the native side copies `values` before returning.
10757        unsafe {
10758            ffi::whiteout_m2_M2ParticleAnimationTrackVector3f_assign_values(
10759                self.raw.as_ptr(),
10760                values.as_ptr() as *const _,
10761                values.len(),
10762            )
10763        }
10764    }
10765
10766    pub fn resize_values(&mut self, count: usize) {
10767        // SAFETY: reallocation is safe here precisely because
10768        // `&mut self` means no slice borrow is outstanding.
10769        unsafe {
10770            ffi::whiteout_m2_M2ParticleAnimationTrackVector3f_resize_values(
10771                self.raw.as_ptr(),
10772                count,
10773            )
10774        }
10775    }
10776}
10777
10778impl Default for ParticleAnimationTrackVector3f {
10779    fn default() -> Self {
10780        Self::new()
10781    }
10782}
10783
10784pub struct ParticleAnimationTrackVector2f {
10785    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2ParticleAnimationTrackVector2f>,
10786}
10787
10788impl Drop for ParticleAnimationTrackVector2f {
10789    fn drop(&mut self) {
10790        // SAFETY: `raw` came from a native constructor and Drop runs once.
10791        unsafe { ffi::whiteout_m2_M2ParticleAnimationTrackVector2f_delete(self.raw.as_ptr()) }
10792    }
10793}
10794
10795impl ParticleAnimationTrackVector2f {
10796    /// # Safety
10797    /// `raw` must be a live handle this value takes ownership of.
10798    #[allow(dead_code)] // used by whichever methods return this type
10799    pub(crate) unsafe fn from_raw(
10800        raw: *mut ffi::whiteout_M2ParticleAnimationTrackVector2f,
10801    ) -> Option<Self> {
10802        core::ptr::NonNull::new(raw).map(|raw| ParticleAnimationTrackVector2f { raw })
10803    }
10804}
10805
10806// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
10807// is deliberately NOT implemented — the C++ types make no documented
10808// guarantee about concurrent use, and claiming one we haven't verified
10809// would be unsound. See `@bind thread_safe` in the plan.
10810unsafe impl Send for ParticleAnimationTrackVector2f {}
10811
10812impl core::fmt::Debug for ParticleAnimationTrackVector2f {
10813    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
10814        f.debug_struct("ParticleAnimationTrackVector2f")
10815            .finish_non_exhaustive()
10816    }
10817}
10818
10819impl ParticleAnimationTrackVector2f {
10820    /// # Panics
10821    /// Panics if the native allocation fails.
10822    pub fn new() -> Self {
10823        // SAFETY: the native constructor returns a live handle; a null here
10824        // means the library is unusable.
10825        unsafe {
10826            let raw = ffi::whiteout_m2_M2ParticleAnimationTrackVector2f_new();
10827            Self::from_raw(raw).expect("native ParticleAnimationTrackVector2f allocation failed")
10828        }
10829    }
10830
10831    /// Zero-copy view of the underlying `std::vector`.
10832    pub fn values(&self) -> &[crate::math::Vector2f] {
10833        // SAFETY: `_data`/`_count` describe one contiguous C++
10834        // allocation, borrowed for as long as `self` is.
10835        unsafe {
10836            let n = ffi::whiteout_m2_M2ParticleAnimationTrackVector2f_get_values_count(
10837                self.raw.as_ptr(),
10838            );
10839            let p = ffi::whiteout_m2_M2ParticleAnimationTrackVector2f_get_values_data(
10840                self.raw.as_ptr(),
10841            ) as *const crate::math::Vector2f;
10842            if p.is_null() || n == 0 {
10843                &[]
10844            } else {
10845                core::slice::from_raw_parts(p, n)
10846            }
10847        }
10848    }
10849
10850    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
10851    pub fn values_mut(&mut self) -> &mut [crate::math::Vector2f] {
10852        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
10853        unsafe {
10854            let n = ffi::whiteout_m2_M2ParticleAnimationTrackVector2f_get_values_count(
10855                self.raw.as_ptr(),
10856            );
10857            let p = ffi::whiteout_m2_M2ParticleAnimationTrackVector2f_get_values_data(
10858                self.raw.as_ptr(),
10859            ) as *const crate::math::Vector2f as *mut crate::math::Vector2f;
10860            if p.is_null() || n == 0 {
10861                &mut []
10862            } else {
10863                core::slice::from_raw_parts_mut(p, n)
10864            }
10865        }
10866    }
10867
10868    pub fn set_values(&mut self, values: &[crate::math::Vector2f]) {
10869        // SAFETY: the native side copies `values` before returning.
10870        unsafe {
10871            ffi::whiteout_m2_M2ParticleAnimationTrackVector2f_assign_values(
10872                self.raw.as_ptr(),
10873                values.as_ptr() as *const _,
10874                values.len(),
10875            )
10876        }
10877    }
10878
10879    pub fn resize_values(&mut self, count: usize) {
10880        // SAFETY: reallocation is safe here precisely because
10881        // `&mut self` means no slice borrow is outstanding.
10882        unsafe {
10883            ffi::whiteout_m2_M2ParticleAnimationTrackVector2f_resize_values(
10884                self.raw.as_ptr(),
10885                count,
10886            )
10887        }
10888    }
10889}
10890
10891impl Default for ParticleAnimationTrackVector2f {
10892    fn default() -> Self {
10893        Self::new()
10894    }
10895}
10896
10897#[doc(hidden)]
10898pub mod ffi {
10899    #![allow(missing_debug_implementations)]
10900
10901    #[allow(unused_imports)]
10902    use crate::support::{RawBytes, RawCString};
10903
10904    #[repr(C)]
10905    pub struct whiteout_M2CompatQuaternion {
10906        _private: [u8; 0],
10907    }
10908    #[repr(C)]
10909    pub struct whiteout_M2ColorBGRA {
10910        _private: [u8; 0],
10911    }
10912    #[repr(C)]
10913    pub struct whiteout_M2Extent {
10914        _private: [u8; 0],
10915    }
10916    #[repr(C)]
10917    pub struct whiteout_M2AnimationTrackBase {
10918        _private: [u8; 0],
10919    }
10920    #[repr(C)]
10921    pub struct whiteout_M2ParticleEmitterExtension {
10922        _private: [u8; 0],
10923    }
10924    #[repr(C)]
10925    pub struct whiteout_M2LodProfile {
10926        _private: [u8; 0],
10927    }
10928    #[repr(C)]
10929    pub struct whiteout_M2WaterfallData {
10930        _private: [u8; 0],
10931    }
10932    #[repr(C)]
10933    pub struct whiteout_M2ParticleGeosetData {
10934        _private: [u8; 0],
10935    }
10936    #[repr(C)]
10937    pub struct whiteout_M2EdgeFadeData {
10938        _private: [u8; 0],
10939    }
10940    #[repr(C)]
10941    pub struct whiteout_M2DistanceFadeData {
10942        _private: [u8; 0],
10943    }
10944    #[repr(C)]
10945    pub struct whiteout_M2DetailedLightData {
10946        _private: [u8; 0],
10947    }
10948    #[repr(C)]
10949    pub struct whiteout_M2DebugOcclusionData {
10950        _private: [u8; 0],
10951    }
10952    #[repr(C)]
10953    pub struct whiteout_M2TexturedLightData {
10954        _private: [u8; 0],
10955    }
10956    #[repr(C)]
10957    pub struct whiteout_M2PhysicsCollision {
10958        _private: [u8; 0],
10959    }
10960    #[repr(C)]
10961    pub struct whiteout_M2SkinSection {
10962        _private: [u8; 0],
10963    }
10964    #[repr(C)]
10965    pub struct whiteout_M2Batch {
10966        _private: [u8; 0],
10967    }
10968    #[repr(C)]
10969    pub struct whiteout_M2ShadowBatch {
10970        _private: [u8; 0],
10971    }
10972    #[repr(C)]
10973    pub struct whiteout_M2SkinProfile {
10974        _private: [u8; 0],
10975    }
10976    #[repr(C)]
10977    pub struct whiteout_M2GlobalFlags {
10978        _private: [u8; 0],
10979    }
10980    #[repr(C)]
10981    pub struct whiteout_M2GlobalSequence {
10982        _private: [u8; 0],
10983    }
10984    #[repr(C)]
10985    pub struct whiteout_M2Sequence {
10986        _private: [u8; 0],
10987    }
10988    #[repr(C)]
10989    pub struct whiteout_M2Vertex {
10990        _private: [u8; 0],
10991    }
10992    #[repr(C)]
10993    pub struct whiteout_M2Bone {
10994        _private: [u8; 0],
10995    }
10996    #[repr(C)]
10997    pub struct whiteout_M2Texture {
10998        _private: [u8; 0],
10999    }
11000    #[repr(C)]
11001    pub struct whiteout_M2Material {
11002        _private: [u8; 0],
11003    }
11004    #[repr(C)]
11005    pub struct whiteout_M2TextureWeight {
11006        _private: [u8; 0],
11007    }
11008    #[repr(C)]
11009    pub struct whiteout_M2TextureTransform {
11010        _private: [u8; 0],
11011    }
11012    #[repr(C)]
11013    pub struct whiteout_M2ColorAnimation {
11014        _private: [u8; 0],
11015    }
11016    #[repr(C)]
11017    pub struct whiteout_M2Light {
11018        _private: [u8; 0],
11019    }
11020    #[repr(C)]
11021    pub struct whiteout_M2CameraSpline {
11022        _private: [u8; 0],
11023    }
11024    #[repr(C)]
11025    pub struct whiteout_M2Camera {
11026        _private: [u8; 0],
11027    }
11028    #[repr(C)]
11029    pub struct whiteout_M2Attachment {
11030        _private: [u8; 0],
11031    }
11032    #[repr(C)]
11033    pub struct whiteout_M2RibbonEmitter {
11034        _private: [u8; 0],
11035    }
11036    #[repr(C)]
11037    pub struct whiteout_M2Box {
11038        _private: [u8; 0],
11039    }
11040    #[repr(C)]
11041    pub struct whiteout_M2ParticleEmitter {
11042        _private: [u8; 0],
11043    }
11044    #[repr(C)]
11045    pub struct whiteout_M2Event {
11046        _private: [u8; 0],
11047    }
11048    #[repr(C)]
11049    pub struct whiteout_M2Model {
11050        _private: [u8; 0],
11051    }
11052    #[repr(C)]
11053    pub struct whiteout_M2Parser {
11054        _private: [u8; 0],
11055    }
11056    #[repr(C)]
11057    pub struct whiteout_M2WriteOptions {
11058        _private: [u8; 0],
11059    }
11060    #[repr(C)]
11061    pub struct whiteout_M2SerializeResult {
11062        _private: [u8; 0],
11063    }
11064    #[repr(C)]
11065    pub struct whiteout_M2Writer {
11066        _private: [u8; 0],
11067    }
11068    #[repr(C)]
11069    pub struct whiteout_M2AnimationTrackVector3f {
11070        _private: [u8; 0],
11071    }
11072    #[repr(C)]
11073    pub struct whiteout_M2AnimationTrackM2CompatQuaternion {
11074        _private: [u8; 0],
11075    }
11076    #[repr(C)]
11077    pub struct whiteout_M2AnimationTrackI16 {
11078        _private: [u8; 0],
11079    }
11080    #[repr(C)]
11081    pub struct whiteout_M2AnimationTrackF32 {
11082        _private: [u8; 0],
11083    }
11084    #[repr(C)]
11085    pub struct whiteout_M2AnimationTrackU8 {
11086        _private: [u8; 0],
11087    }
11088    #[repr(C)]
11089    pub struct whiteout_M2AnimationTrackM2CameraSpline {
11090        _private: [u8; 0],
11091    }
11092    #[repr(C)]
11093    pub struct whiteout_M2AnimationTrackU16 {
11094        _private: [u8; 0],
11095    }
11096    #[repr(C)]
11097    pub struct whiteout_M2ParticleAnimationTrackVector3f {
11098        _private: [u8; 0],
11099    }
11100    #[repr(C)]
11101    pub struct whiteout_M2ParticleAnimationTrackVector2f {
11102        _private: [u8; 0],
11103    }
11104
11105    extern "C" {
11106        // CompatQuaternion
11107        pub fn whiteout_m2_M2CompatQuaternion_new() -> *mut whiteout_M2CompatQuaternion;
11108        pub fn whiteout_m2_M2CompatQuaternion_delete(self_: *mut whiteout_M2CompatQuaternion);
11109        // ColorBGRA
11110        pub fn whiteout_m2_M2ColorBGRA_new() -> *mut whiteout_M2ColorBGRA;
11111        pub fn whiteout_m2_M2ColorBGRA_delete(self_: *mut whiteout_M2ColorBGRA);
11112        // Extent
11113        pub fn whiteout_m2_M2Extent_new() -> *mut whiteout_M2Extent;
11114        pub fn whiteout_m2_M2Extent_delete(self_: *mut whiteout_M2Extent);
11115        pub fn whiteout_m2_M2Extent_get_minimum(
11116            self_: *mut whiteout_M2Extent,
11117        ) -> *mut core::ffi::c_void;
11118        pub fn whiteout_m2_M2Extent_set_minimum(
11119            self_: *mut whiteout_M2Extent,
11120            value: *const core::ffi::c_void,
11121        );
11122        pub fn whiteout_m2_M2Extent_get_maximum(
11123            self_: *mut whiteout_M2Extent,
11124        ) -> *mut core::ffi::c_void;
11125        pub fn whiteout_m2_M2Extent_set_maximum(
11126            self_: *mut whiteout_M2Extent,
11127            value: *const core::ffi::c_void,
11128        );
11129        pub fn whiteout_m2_M2Extent_get_sphereRadius(self_: *mut whiteout_M2Extent) -> f32;
11130        pub fn whiteout_m2_M2Extent_set_sphereRadius(self_: *mut whiteout_M2Extent, value: f32);
11131        // AnimationTrackBase
11132        pub fn whiteout_m2_M2AnimationTrackBase_new() -> *mut whiteout_M2AnimationTrackBase;
11133        pub fn whiteout_m2_M2AnimationTrackBase_delete(self_: *mut whiteout_M2AnimationTrackBase);
11134        pub fn whiteout_m2_M2AnimationTrackBase_get_interpolationType(
11135            self_: *mut whiteout_M2AnimationTrackBase,
11136        ) -> i32;
11137        pub fn whiteout_m2_M2AnimationTrackBase_set_interpolationType(
11138            self_: *mut whiteout_M2AnimationTrackBase,
11139            value: i32,
11140        );
11141        pub fn whiteout_m2_M2AnimationTrackBase_get_globalSequenceId(
11142            self_: *mut whiteout_M2AnimationTrackBase,
11143        ) -> u16;
11144        pub fn whiteout_m2_M2AnimationTrackBase_set_globalSequenceId(
11145            self_: *mut whiteout_M2AnimationTrackBase,
11146            value: u16,
11147        );
11148        pub fn whiteout_m2_M2AnimationTrackBase_get_timestamps_count(
11149            self_: *mut whiteout_M2AnimationTrackBase,
11150        ) -> usize;
11151        pub fn whiteout_m2_M2AnimationTrackBase_get_timestamps_inner_count(
11152            self_: *mut whiteout_M2AnimationTrackBase,
11153            outer: usize,
11154        ) -> usize;
11155        pub fn whiteout_m2_M2AnimationTrackBase_resize_timestamps(
11156            self_: *mut whiteout_M2AnimationTrackBase,
11157            count: usize,
11158        );
11159        pub fn whiteout_m2_M2AnimationTrackBase_resize_timestamps_inner(
11160            self_: *mut whiteout_M2AnimationTrackBase,
11161            outer: usize,
11162            count: usize,
11163        );
11164        pub fn whiteout_m2_M2AnimationTrackBase_get_timestamps_inner_data(
11165            self_: *mut whiteout_M2AnimationTrackBase,
11166            outer: usize,
11167        ) -> *const u32;
11168        pub fn whiteout_m2_M2AnimationTrackBase_assign_timestamps_inner(
11169            self_: *mut whiteout_M2AnimationTrackBase,
11170            outer: usize,
11171            data: *const u32,
11172            count: usize,
11173        );
11174        // ParticleEmitterExtension
11175        pub fn whiteout_m2_M2ParticleEmitterExtension_new(
11176        ) -> *mut whiteout_M2ParticleEmitterExtension;
11177        pub fn whiteout_m2_M2ParticleEmitterExtension_delete(
11178            self_: *mut whiteout_M2ParticleEmitterExtension,
11179        );
11180        pub fn whiteout_m2_M2ParticleEmitterExtension_get_zSource(
11181            self_: *mut whiteout_M2ParticleEmitterExtension,
11182        ) -> f32;
11183        pub fn whiteout_m2_M2ParticleEmitterExtension_set_zSource(
11184            self_: *mut whiteout_M2ParticleEmitterExtension,
11185            value: f32,
11186        );
11187        pub fn whiteout_m2_M2ParticleEmitterExtension_get_colorMult(
11188            self_: *mut whiteout_M2ParticleEmitterExtension,
11189        ) -> f32;
11190        pub fn whiteout_m2_M2ParticleEmitterExtension_set_colorMult(
11191            self_: *mut whiteout_M2ParticleEmitterExtension,
11192            value: f32,
11193        );
11194        pub fn whiteout_m2_M2ParticleEmitterExtension_get_alphaMult(
11195            self_: *mut whiteout_M2ParticleEmitterExtension,
11196        ) -> f32;
11197        pub fn whiteout_m2_M2ParticleEmitterExtension_set_alphaMult(
11198            self_: *mut whiteout_M2ParticleEmitterExtension,
11199            value: f32,
11200        );
11201        // LodProfile
11202        pub fn whiteout_m2_M2LodProfile_new() -> *mut whiteout_M2LodProfile;
11203        pub fn whiteout_m2_M2LodProfile_delete(self_: *mut whiteout_M2LodProfile);
11204        pub fn whiteout_m2_M2LodProfile_get_flags(self_: *mut whiteout_M2LodProfile) -> u16;
11205        pub fn whiteout_m2_M2LodProfile_set_flags(self_: *mut whiteout_M2LodProfile, value: u16);
11206        pub fn whiteout_m2_M2LodProfile_get_numLodLevels(self_: *mut whiteout_M2LodProfile) -> u16;
11207        pub fn whiteout_m2_M2LodProfile_set_numLodLevels(
11208            self_: *mut whiteout_M2LodProfile,
11209            value: u16,
11210        );
11211        pub fn whiteout_m2_M2LodProfile_get_lodDistance(self_: *mut whiteout_M2LodProfile) -> f32;
11212        pub fn whiteout_m2_M2LodProfile_set_lodDistance(
11213            self_: *mut whiteout_M2LodProfile,
11214            value: f32,
11215        );
11216        pub fn whiteout_m2_M2LodProfile_particleBoneLod_size() -> usize;
11217        pub fn whiteout_m2_M2LodProfile_get_particleBoneLod_at(
11218            self_: *mut whiteout_M2LodProfile,
11219            index: usize,
11220        ) -> u8;
11221        pub fn whiteout_m2_M2LodProfile_set_particleBoneLod_at(
11222            self_: *mut whiteout_M2LodProfile,
11223            index: usize,
11224            value: u8,
11225        );
11226        pub fn whiteout_m2_M2LodProfile_get_reserved0(self_: *mut whiteout_M2LodProfile) -> u8;
11227        pub fn whiteout_m2_M2LodProfile_set_reserved0(self_: *mut whiteout_M2LodProfile, value: u8);
11228        pub fn whiteout_m2_M2LodProfile_get_lodFlags(self_: *mut whiteout_M2LodProfile) -> u8;
11229        pub fn whiteout_m2_M2LodProfile_set_lodFlags(self_: *mut whiteout_M2LodProfile, value: u8);
11230        pub fn whiteout_m2_M2LodProfile_get_lodBatchCount(self_: *mut whiteout_M2LodProfile) -> u8;
11231        pub fn whiteout_m2_M2LodProfile_set_lodBatchCount(
11232            self_: *mut whiteout_M2LodProfile,
11233            value: u8,
11234        );
11235        pub fn whiteout_m2_M2LodProfile_get_reserved1(self_: *mut whiteout_M2LodProfile) -> u8;
11236        pub fn whiteout_m2_M2LodProfile_set_reserved1(self_: *mut whiteout_M2LodProfile, value: u8);
11237        // WaterfallData
11238        pub fn whiteout_m2_M2WaterfallData_new() -> *mut whiteout_M2WaterfallData;
11239        pub fn whiteout_m2_M2WaterfallData_delete(self_: *mut whiteout_M2WaterfallData);
11240        pub fn whiteout_m2_M2WaterfallData_get_bumpScale(
11241            self_: *mut whiteout_M2WaterfallData,
11242        ) -> f32;
11243        pub fn whiteout_m2_M2WaterfallData_set_bumpScale(
11244            self_: *mut whiteout_M2WaterfallData,
11245            value: f32,
11246        );
11247        pub fn whiteout_m2_M2WaterfallData_get_value0_x(
11248            self_: *mut whiteout_M2WaterfallData,
11249        ) -> f32;
11250        pub fn whiteout_m2_M2WaterfallData_set_value0_x(
11251            self_: *mut whiteout_M2WaterfallData,
11252            value: f32,
11253        );
11254        pub fn whiteout_m2_M2WaterfallData_get_value0_y(
11255            self_: *mut whiteout_M2WaterfallData,
11256        ) -> f32;
11257        pub fn whiteout_m2_M2WaterfallData_set_value0_y(
11258            self_: *mut whiteout_M2WaterfallData,
11259            value: f32,
11260        );
11261        pub fn whiteout_m2_M2WaterfallData_get_value0_z(
11262            self_: *mut whiteout_M2WaterfallData,
11263        ) -> f32;
11264        pub fn whiteout_m2_M2WaterfallData_set_value0_z(
11265            self_: *mut whiteout_M2WaterfallData,
11266            value: f32,
11267        );
11268        pub fn whiteout_m2_M2WaterfallData_get_value1_w(
11269            self_: *mut whiteout_M2WaterfallData,
11270        ) -> f32;
11271        pub fn whiteout_m2_M2WaterfallData_set_value1_w(
11272            self_: *mut whiteout_M2WaterfallData,
11273            value: f32,
11274        );
11275        pub fn whiteout_m2_M2WaterfallData_get_value0_w(
11276            self_: *mut whiteout_M2WaterfallData,
11277        ) -> f32;
11278        pub fn whiteout_m2_M2WaterfallData_set_value0_w(
11279            self_: *mut whiteout_M2WaterfallData,
11280            value: f32,
11281        );
11282        pub fn whiteout_m2_M2WaterfallData_get_value1_x(
11283            self_: *mut whiteout_M2WaterfallData,
11284        ) -> f32;
11285        pub fn whiteout_m2_M2WaterfallData_set_value1_x(
11286            self_: *mut whiteout_M2WaterfallData,
11287            value: f32,
11288        );
11289        pub fn whiteout_m2_M2WaterfallData_get_value1_y(
11290            self_: *mut whiteout_M2WaterfallData,
11291        ) -> f32;
11292        pub fn whiteout_m2_M2WaterfallData_set_value1_y(
11293            self_: *mut whiteout_M2WaterfallData,
11294            value: f32,
11295        );
11296        pub fn whiteout_m2_M2WaterfallData_get_value2_w(
11297            self_: *mut whiteout_M2WaterfallData,
11298        ) -> f32;
11299        pub fn whiteout_m2_M2WaterfallData_set_value2_w(
11300            self_: *mut whiteout_M2WaterfallData,
11301            value: f32,
11302        );
11303        pub fn whiteout_m2_M2WaterfallData_get_value3_y(
11304            self_: *mut whiteout_M2WaterfallData,
11305        ) -> f32;
11306        pub fn whiteout_m2_M2WaterfallData_set_value3_y(
11307            self_: *mut whiteout_M2WaterfallData,
11308            value: f32,
11309        );
11310        pub fn whiteout_m2_M2WaterfallData_get_value3_x(
11311            self_: *mut whiteout_M2WaterfallData,
11312        ) -> f32;
11313        pub fn whiteout_m2_M2WaterfallData_set_value3_x(
11314            self_: *mut whiteout_M2WaterfallData,
11315            value: f32,
11316        );
11317        pub fn whiteout_m2_M2WaterfallData_get_baseColor(
11318            self_: *mut whiteout_M2WaterfallData,
11319        ) -> *mut core::ffi::c_void;
11320        pub fn whiteout_m2_M2WaterfallData_set_baseColor(
11321            self_: *mut whiteout_M2WaterfallData,
11322            value: *const core::ffi::c_void,
11323        );
11324        pub fn whiteout_m2_M2WaterfallData_get_flags(self_: *mut whiteout_M2WaterfallData) -> u16;
11325        pub fn whiteout_m2_M2WaterfallData_set_flags(
11326            self_: *mut whiteout_M2WaterfallData,
11327            value: u16,
11328        );
11329        pub fn whiteout_m2_M2WaterfallData_get_unknown0(
11330            self_: *mut whiteout_M2WaterfallData,
11331        ) -> u16;
11332        pub fn whiteout_m2_M2WaterfallData_set_unknown0(
11333            self_: *mut whiteout_M2WaterfallData,
11334            value: u16,
11335        );
11336        pub fn whiteout_m2_M2WaterfallData_get_value3_w(
11337            self_: *mut whiteout_M2WaterfallData,
11338        ) -> f32;
11339        pub fn whiteout_m2_M2WaterfallData_set_value3_w(
11340            self_: *mut whiteout_M2WaterfallData,
11341            value: f32,
11342        );
11343        pub fn whiteout_m2_M2WaterfallData_get_value3_z(
11344            self_: *mut whiteout_M2WaterfallData,
11345        ) -> f32;
11346        pub fn whiteout_m2_M2WaterfallData_set_value3_z(
11347            self_: *mut whiteout_M2WaterfallData,
11348            value: f32,
11349        );
11350        pub fn whiteout_m2_M2WaterfallData_get_value4_y(
11351            self_: *mut whiteout_M2WaterfallData,
11352        ) -> f32;
11353        pub fn whiteout_m2_M2WaterfallData_set_value4_y(
11354            self_: *mut whiteout_M2WaterfallData,
11355            value: f32,
11356        );
11357        pub fn whiteout_m2_M2WaterfallData_get_unknown1(
11358            self_: *mut whiteout_M2WaterfallData,
11359        ) -> f32;
11360        pub fn whiteout_m2_M2WaterfallData_set_unknown1(
11361            self_: *mut whiteout_M2WaterfallData,
11362            value: f32,
11363        );
11364        pub fn whiteout_m2_M2WaterfallData_get_unknown2(
11365            self_: *mut whiteout_M2WaterfallData,
11366        ) -> f32;
11367        pub fn whiteout_m2_M2WaterfallData_set_unknown2(
11368            self_: *mut whiteout_M2WaterfallData,
11369            value: f32,
11370        );
11371        pub fn whiteout_m2_M2WaterfallData_get_unknown3(
11372            self_: *mut whiteout_M2WaterfallData,
11373        ) -> f32;
11374        pub fn whiteout_m2_M2WaterfallData_set_unknown3(
11375            self_: *mut whiteout_M2WaterfallData,
11376            value: f32,
11377        );
11378        pub fn whiteout_m2_M2WaterfallData_get_unknown4(
11379            self_: *mut whiteout_M2WaterfallData,
11380        ) -> f32;
11381        pub fn whiteout_m2_M2WaterfallData_set_unknown4(
11382            self_: *mut whiteout_M2WaterfallData,
11383            value: f32,
11384        );
11385        // ParticleGeosetData
11386        pub fn whiteout_m2_M2ParticleGeosetData_new() -> *mut whiteout_M2ParticleGeosetData;
11387        pub fn whiteout_m2_M2ParticleGeosetData_delete(self_: *mut whiteout_M2ParticleGeosetData);
11388        pub fn whiteout_m2_M2ParticleGeosetData_get_geoset(
11389            self_: *mut whiteout_M2ParticleGeosetData,
11390        ) -> u16;
11391        pub fn whiteout_m2_M2ParticleGeosetData_set_geoset(
11392            self_: *mut whiteout_M2ParticleGeosetData,
11393            value: u16,
11394        );
11395        // EdgeFadeData
11396        pub fn whiteout_m2_M2EdgeFadeData_new() -> *mut whiteout_M2EdgeFadeData;
11397        pub fn whiteout_m2_M2EdgeFadeData_delete(self_: *mut whiteout_M2EdgeFadeData);
11398        pub fn whiteout_m2_M2EdgeFadeData_value0_size() -> usize;
11399        pub fn whiteout_m2_M2EdgeFadeData_get_value0_at(
11400            self_: *mut whiteout_M2EdgeFadeData,
11401            index: usize,
11402        ) -> f32;
11403        pub fn whiteout_m2_M2EdgeFadeData_set_value0_at(
11404            self_: *mut whiteout_M2EdgeFadeData,
11405            index: usize,
11406            value: f32,
11407        );
11408        pub fn whiteout_m2_M2EdgeFadeData_get_value8(self_: *mut whiteout_M2EdgeFadeData) -> f32;
11409        pub fn whiteout_m2_M2EdgeFadeData_set_value8(
11410            self_: *mut whiteout_M2EdgeFadeData,
11411            value: f32,
11412        );
11413        pub fn whiteout_m2_M2EdgeFadeData_valueC_size() -> usize;
11414        pub fn whiteout_m2_M2EdgeFadeData_get_valueC_at(
11415            self_: *mut whiteout_M2EdgeFadeData,
11416            index: usize,
11417        ) -> u8;
11418        pub fn whiteout_m2_M2EdgeFadeData_set_valueC_at(
11419            self_: *mut whiteout_M2EdgeFadeData,
11420            index: usize,
11421            value: u8,
11422        );
11423        // DistanceFadeData
11424        pub fn whiteout_m2_M2DistanceFadeData_new() -> *mut whiteout_M2DistanceFadeData;
11425        pub fn whiteout_m2_M2DistanceFadeData_delete(self_: *mut whiteout_M2DistanceFadeData);
11426        pub fn whiteout_m2_M2DistanceFadeData_get_squaredFarDist(
11427            self_: *mut whiteout_M2DistanceFadeData,
11428        ) -> f32;
11429        pub fn whiteout_m2_M2DistanceFadeData_set_squaredFarDist(
11430            self_: *mut whiteout_M2DistanceFadeData,
11431            value: f32,
11432        );
11433        pub fn whiteout_m2_M2DistanceFadeData_get_squaredNearDist(
11434            self_: *mut whiteout_M2DistanceFadeData,
11435        ) -> f32;
11436        pub fn whiteout_m2_M2DistanceFadeData_set_squaredNearDist(
11437            self_: *mut whiteout_M2DistanceFadeData,
11438            value: f32,
11439        );
11440        pub fn whiteout_m2_M2DistanceFadeData_reserved_size() -> usize;
11441        pub fn whiteout_m2_M2DistanceFadeData_get_reserved_at(
11442            self_: *mut whiteout_M2DistanceFadeData,
11443            index: usize,
11444        ) -> u32;
11445        pub fn whiteout_m2_M2DistanceFadeData_set_reserved_at(
11446            self_: *mut whiteout_M2DistanceFadeData,
11447            index: usize,
11448            value: u32,
11449        );
11450        // DetailedLightData
11451        pub fn whiteout_m2_M2DetailedLightData_new() -> *mut whiteout_M2DetailedLightData;
11452        pub fn whiteout_m2_M2DetailedLightData_delete(self_: *mut whiteout_M2DetailedLightData);
11453        pub fn whiteout_m2_M2DetailedLightData_get_flags(
11454            self_: *mut whiteout_M2DetailedLightData,
11455        ) -> u16;
11456        pub fn whiteout_m2_M2DetailedLightData_set_flags(
11457            self_: *mut whiteout_M2DetailedLightData,
11458            value: u16,
11459        );
11460        pub fn whiteout_m2_M2DetailedLightData_get_unknown0(
11461            self_: *mut whiteout_M2DetailedLightData,
11462        ) -> u16;
11463        pub fn whiteout_m2_M2DetailedLightData_set_unknown0(
11464            self_: *mut whiteout_M2DetailedLightData,
11465            value: u16,
11466        );
11467        pub fn whiteout_m2_M2DetailedLightData_get_unknown1(
11468            self_: *mut whiteout_M2DetailedLightData,
11469        ) -> u32;
11470        pub fn whiteout_m2_M2DetailedLightData_set_unknown1(
11471            self_: *mut whiteout_M2DetailedLightData,
11472            value: u32,
11473        );
11474        // DebugOcclusionData
11475        pub fn whiteout_m2_M2DebugOcclusionData_new() -> *mut whiteout_M2DebugOcclusionData;
11476        pub fn whiteout_m2_M2DebugOcclusionData_delete(self_: *mut whiteout_M2DebugOcclusionData);
11477        pub fn whiteout_m2_M2DebugOcclusionData_get_unknown1_1(
11478            self_: *mut whiteout_M2DebugOcclusionData,
11479        ) -> f32;
11480        pub fn whiteout_m2_M2DebugOcclusionData_set_unknown1_1(
11481            self_: *mut whiteout_M2DebugOcclusionData,
11482            value: f32,
11483        );
11484        pub fn whiteout_m2_M2DebugOcclusionData_get_unknown1_2(
11485            self_: *mut whiteout_M2DebugOcclusionData,
11486        ) -> f32;
11487        pub fn whiteout_m2_M2DebugOcclusionData_set_unknown1_2(
11488            self_: *mut whiteout_M2DebugOcclusionData,
11489            value: f32,
11490        );
11491        pub fn whiteout_m2_M2DebugOcclusionData_get_unknown1_3(
11492            self_: *mut whiteout_M2DebugOcclusionData,
11493        ) -> u32;
11494        pub fn whiteout_m2_M2DebugOcclusionData_set_unknown1_3(
11495            self_: *mut whiteout_M2DebugOcclusionData,
11496            value: u32,
11497        );
11498        pub fn whiteout_m2_M2DebugOcclusionData_get_unknown1_4(
11499            self_: *mut whiteout_M2DebugOcclusionData,
11500        ) -> u32;
11501        pub fn whiteout_m2_M2DebugOcclusionData_set_unknown1_4(
11502            self_: *mut whiteout_M2DebugOcclusionData,
11503            value: u32,
11504        );
11505        // TexturedLightData
11506        pub fn whiteout_m2_M2TexturedLightData_new() -> *mut whiteout_M2TexturedLightData;
11507        pub fn whiteout_m2_M2TexturedLightData_delete(self_: *mut whiteout_M2TexturedLightData);
11508        pub fn whiteout_m2_M2TexturedLightData_get_unknown0(
11509            self_: *mut whiteout_M2TexturedLightData,
11510        ) -> f32;
11511        pub fn whiteout_m2_M2TexturedLightData_set_unknown0(
11512            self_: *mut whiteout_M2TexturedLightData,
11513            value: f32,
11514        );
11515        pub fn whiteout_m2_M2TexturedLightData_get_unknown1(
11516            self_: *mut whiteout_M2TexturedLightData,
11517        ) -> f32;
11518        pub fn whiteout_m2_M2TexturedLightData_set_unknown1(
11519            self_: *mut whiteout_M2TexturedLightData,
11520            value: f32,
11521        );
11522        pub fn whiteout_m2_M2TexturedLightData_get_textureLookup(
11523            self_: *mut whiteout_M2TexturedLightData,
11524        ) -> i32;
11525        pub fn whiteout_m2_M2TexturedLightData_set_textureLookup(
11526            self_: *mut whiteout_M2TexturedLightData,
11527            value: i32,
11528        );
11529        pub fn whiteout_m2_M2TexturedLightData_get_unknown2(
11530            self_: *mut whiteout_M2TexturedLightData,
11531        ) -> i32;
11532        pub fn whiteout_m2_M2TexturedLightData_set_unknown2(
11533            self_: *mut whiteout_M2TexturedLightData,
11534            value: i32,
11535        );
11536        // PhysicsCollision
11537        pub fn whiteout_m2_M2PhysicsCollision_new() -> *mut whiteout_M2PhysicsCollision;
11538        pub fn whiteout_m2_M2PhysicsCollision_delete(self_: *mut whiteout_M2PhysicsCollision);
11539        pub fn whiteout_m2_M2PhysicsCollision_get_vertexPositions_count(
11540            self_: *mut whiteout_M2PhysicsCollision,
11541        ) -> usize;
11542        pub fn whiteout_m2_M2PhysicsCollision_resize_vertexPositions(
11543            self_: *mut whiteout_M2PhysicsCollision,
11544            count: usize,
11545        );
11546        pub fn whiteout_m2_M2PhysicsCollision_get_vertexPositions_data(
11547            self_: *mut whiteout_M2PhysicsCollision,
11548        ) -> *const f32;
11549        pub fn whiteout_m2_M2PhysicsCollision_assign_vertexPositions(
11550            self_: *mut whiteout_M2PhysicsCollision,
11551            data: *const f32,
11552            count: usize,
11553        );
11554        pub fn whiteout_m2_M2PhysicsCollision_get_faceNormals_count(
11555            self_: *mut whiteout_M2PhysicsCollision,
11556        ) -> usize;
11557        pub fn whiteout_m2_M2PhysicsCollision_resize_faceNormals(
11558            self_: *mut whiteout_M2PhysicsCollision,
11559            count: usize,
11560        );
11561        pub fn whiteout_m2_M2PhysicsCollision_get_faceNormals_data(
11562            self_: *mut whiteout_M2PhysicsCollision,
11563        ) -> *const f32;
11564        pub fn whiteout_m2_M2PhysicsCollision_assign_faceNormals(
11565            self_: *mut whiteout_M2PhysicsCollision,
11566            data: *const f32,
11567            count: usize,
11568        );
11569        pub fn whiteout_m2_M2PhysicsCollision_get_indices_count(
11570            self_: *mut whiteout_M2PhysicsCollision,
11571        ) -> usize;
11572        pub fn whiteout_m2_M2PhysicsCollision_resize_indices(
11573            self_: *mut whiteout_M2PhysicsCollision,
11574            count: usize,
11575        );
11576        pub fn whiteout_m2_M2PhysicsCollision_get_indices_data(
11577            self_: *mut whiteout_M2PhysicsCollision,
11578        ) -> *const i16;
11579        pub fn whiteout_m2_M2PhysicsCollision_assign_indices(
11580            self_: *mut whiteout_M2PhysicsCollision,
11581            data: *const i16,
11582            count: usize,
11583        );
11584        pub fn whiteout_m2_M2PhysicsCollision_get_flags_count(
11585            self_: *mut whiteout_M2PhysicsCollision,
11586        ) -> usize;
11587        pub fn whiteout_m2_M2PhysicsCollision_resize_flags(
11588            self_: *mut whiteout_M2PhysicsCollision,
11589            count: usize,
11590        );
11591        pub fn whiteout_m2_M2PhysicsCollision_get_flags_data(
11592            self_: *mut whiteout_M2PhysicsCollision,
11593        ) -> *const i16;
11594        pub fn whiteout_m2_M2PhysicsCollision_assign_flags(
11595            self_: *mut whiteout_M2PhysicsCollision,
11596            data: *const i16,
11597            count: usize,
11598        );
11599        // SkinSection
11600        pub fn whiteout_m2_M2SkinSection_new() -> *mut whiteout_M2SkinSection;
11601        pub fn whiteout_m2_M2SkinSection_delete(self_: *mut whiteout_M2SkinSection);
11602        pub fn whiteout_m2_M2SkinSection_get_skinSectionId(
11603            self_: *mut whiteout_M2SkinSection,
11604        ) -> u16;
11605        pub fn whiteout_m2_M2SkinSection_set_skinSectionId(
11606            self_: *mut whiteout_M2SkinSection,
11607            value: u16,
11608        );
11609        pub fn whiteout_m2_M2SkinSection_get_level(self_: *mut whiteout_M2SkinSection) -> u16;
11610        pub fn whiteout_m2_M2SkinSection_set_level(self_: *mut whiteout_M2SkinSection, value: u16);
11611        pub fn whiteout_m2_M2SkinSection_get_vertexStart(self_: *mut whiteout_M2SkinSection)
11612            -> u16;
11613        pub fn whiteout_m2_M2SkinSection_set_vertexStart(
11614            self_: *mut whiteout_M2SkinSection,
11615            value: u16,
11616        );
11617        pub fn whiteout_m2_M2SkinSection_get_vertexCount(self_: *mut whiteout_M2SkinSection)
11618            -> u16;
11619        pub fn whiteout_m2_M2SkinSection_set_vertexCount(
11620            self_: *mut whiteout_M2SkinSection,
11621            value: u16,
11622        );
11623        pub fn whiteout_m2_M2SkinSection_get_indexStart(self_: *mut whiteout_M2SkinSection) -> u16;
11624        pub fn whiteout_m2_M2SkinSection_set_indexStart(
11625            self_: *mut whiteout_M2SkinSection,
11626            value: u16,
11627        );
11628        pub fn whiteout_m2_M2SkinSection_get_indexCount(self_: *mut whiteout_M2SkinSection) -> u16;
11629        pub fn whiteout_m2_M2SkinSection_set_indexCount(
11630            self_: *mut whiteout_M2SkinSection,
11631            value: u16,
11632        );
11633        pub fn whiteout_m2_M2SkinSection_get_boneCount(self_: *mut whiteout_M2SkinSection) -> u16;
11634        pub fn whiteout_m2_M2SkinSection_set_boneCount(
11635            self_: *mut whiteout_M2SkinSection,
11636            value: u16,
11637        );
11638        pub fn whiteout_m2_M2SkinSection_get_boneComboIndex(
11639            self_: *mut whiteout_M2SkinSection,
11640        ) -> u16;
11641        pub fn whiteout_m2_M2SkinSection_set_boneComboIndex(
11642            self_: *mut whiteout_M2SkinSection,
11643            value: u16,
11644        );
11645        pub fn whiteout_m2_M2SkinSection_get_boneInfluences(
11646            self_: *mut whiteout_M2SkinSection,
11647        ) -> u16;
11648        pub fn whiteout_m2_M2SkinSection_set_boneInfluences(
11649            self_: *mut whiteout_M2SkinSection,
11650            value: u16,
11651        );
11652        pub fn whiteout_m2_M2SkinSection_get_centerBoneIndex(
11653            self_: *mut whiteout_M2SkinSection,
11654        ) -> u16;
11655        pub fn whiteout_m2_M2SkinSection_set_centerBoneIndex(
11656            self_: *mut whiteout_M2SkinSection,
11657            value: u16,
11658        );
11659        pub fn whiteout_m2_M2SkinSection_get_centerPosition(
11660            self_: *mut whiteout_M2SkinSection,
11661        ) -> *mut core::ffi::c_void;
11662        pub fn whiteout_m2_M2SkinSection_set_centerPosition(
11663            self_: *mut whiteout_M2SkinSection,
11664            value: *const core::ffi::c_void,
11665        );
11666        pub fn whiteout_m2_M2SkinSection_get_sortCenterPosition(
11667            self_: *mut whiteout_M2SkinSection,
11668        ) -> *mut core::ffi::c_void;
11669        pub fn whiteout_m2_M2SkinSection_set_sortCenterPosition(
11670            self_: *mut whiteout_M2SkinSection,
11671            value: *const core::ffi::c_void,
11672        );
11673        pub fn whiteout_m2_M2SkinSection_get_sortRadius(self_: *mut whiteout_M2SkinSection) -> f32;
11674        pub fn whiteout_m2_M2SkinSection_set_sortRadius(
11675            self_: *mut whiteout_M2SkinSection,
11676            value: f32,
11677        );
11678        // Batch
11679        pub fn whiteout_m2_M2Batch_new() -> *mut whiteout_M2Batch;
11680        pub fn whiteout_m2_M2Batch_delete(self_: *mut whiteout_M2Batch);
11681        pub fn whiteout_m2_M2Batch_get_flags(self_: *mut whiteout_M2Batch) -> u8;
11682        pub fn whiteout_m2_M2Batch_set_flags(self_: *mut whiteout_M2Batch, value: u8);
11683        pub fn whiteout_m2_M2Batch_get_priorityPlane(self_: *mut whiteout_M2Batch) -> i8;
11684        pub fn whiteout_m2_M2Batch_set_priorityPlane(self_: *mut whiteout_M2Batch, value: i8);
11685        pub fn whiteout_m2_M2Batch_get_shaderId(self_: *mut whiteout_M2Batch) -> u16;
11686        pub fn whiteout_m2_M2Batch_set_shaderId(self_: *mut whiteout_M2Batch, value: u16);
11687        pub fn whiteout_m2_M2Batch_get_skinSectionIndex(self_: *mut whiteout_M2Batch) -> u16;
11688        pub fn whiteout_m2_M2Batch_set_skinSectionIndex(self_: *mut whiteout_M2Batch, value: u16);
11689        pub fn whiteout_m2_M2Batch_get_geosetIndex(self_: *mut whiteout_M2Batch) -> u16;
11690        pub fn whiteout_m2_M2Batch_set_geosetIndex(self_: *mut whiteout_M2Batch, value: u16);
11691        pub fn whiteout_m2_M2Batch_get_colorIndex(self_: *mut whiteout_M2Batch) -> i16;
11692        pub fn whiteout_m2_M2Batch_set_colorIndex(self_: *mut whiteout_M2Batch, value: i16);
11693        pub fn whiteout_m2_M2Batch_get_materialIndex(self_: *mut whiteout_M2Batch) -> u16;
11694        pub fn whiteout_m2_M2Batch_set_materialIndex(self_: *mut whiteout_M2Batch, value: u16);
11695        pub fn whiteout_m2_M2Batch_get_materialLayer(self_: *mut whiteout_M2Batch) -> u16;
11696        pub fn whiteout_m2_M2Batch_set_materialLayer(self_: *mut whiteout_M2Batch, value: u16);
11697        pub fn whiteout_m2_M2Batch_get_textureCount(self_: *mut whiteout_M2Batch) -> u16;
11698        pub fn whiteout_m2_M2Batch_set_textureCount(self_: *mut whiteout_M2Batch, value: u16);
11699        pub fn whiteout_m2_M2Batch_get_textureComboIndex(self_: *mut whiteout_M2Batch) -> u16;
11700        pub fn whiteout_m2_M2Batch_set_textureComboIndex(self_: *mut whiteout_M2Batch, value: u16);
11701        pub fn whiteout_m2_M2Batch_get_textureCoordComboIndex(self_: *mut whiteout_M2Batch) -> u16;
11702        pub fn whiteout_m2_M2Batch_set_textureCoordComboIndex(
11703            self_: *mut whiteout_M2Batch,
11704            value: u16,
11705        );
11706        pub fn whiteout_m2_M2Batch_get_textureWeightComboIndex(self_: *mut whiteout_M2Batch)
11707            -> u16;
11708        pub fn whiteout_m2_M2Batch_set_textureWeightComboIndex(
11709            self_: *mut whiteout_M2Batch,
11710            value: u16,
11711        );
11712        pub fn whiteout_m2_M2Batch_get_textureTransformComboIndex(
11713            self_: *mut whiteout_M2Batch,
11714        ) -> u16;
11715        pub fn whiteout_m2_M2Batch_set_textureTransformComboIndex(
11716            self_: *mut whiteout_M2Batch,
11717            value: u16,
11718        );
11719        // ShadowBatch
11720        pub fn whiteout_m2_M2ShadowBatch_new() -> *mut whiteout_M2ShadowBatch;
11721        pub fn whiteout_m2_M2ShadowBatch_delete(self_: *mut whiteout_M2ShadowBatch);
11722        pub fn whiteout_m2_M2ShadowBatch_get_flags(self_: *mut whiteout_M2ShadowBatch) -> u8;
11723        pub fn whiteout_m2_M2ShadowBatch_set_flags(self_: *mut whiteout_M2ShadowBatch, value: u8);
11724        pub fn whiteout_m2_M2ShadowBatch_get_flags2(self_: *mut whiteout_M2ShadowBatch) -> u8;
11725        pub fn whiteout_m2_M2ShadowBatch_set_flags2(self_: *mut whiteout_M2ShadowBatch, value: u8);
11726        pub fn whiteout_m2_M2ShadowBatch_get_unknown0(self_: *mut whiteout_M2ShadowBatch) -> u16;
11727        pub fn whiteout_m2_M2ShadowBatch_set_unknown0(
11728            self_: *mut whiteout_M2ShadowBatch,
11729            value: u16,
11730        );
11731        pub fn whiteout_m2_M2ShadowBatch_get_submeshId(self_: *mut whiteout_M2ShadowBatch) -> u16;
11732        pub fn whiteout_m2_M2ShadowBatch_set_submeshId(
11733            self_: *mut whiteout_M2ShadowBatch,
11734            value: u16,
11735        );
11736        pub fn whiteout_m2_M2ShadowBatch_get_textureId(self_: *mut whiteout_M2ShadowBatch) -> u16;
11737        pub fn whiteout_m2_M2ShadowBatch_set_textureId(
11738            self_: *mut whiteout_M2ShadowBatch,
11739            value: u16,
11740        );
11741        pub fn whiteout_m2_M2ShadowBatch_get_colorId(self_: *mut whiteout_M2ShadowBatch) -> u16;
11742        pub fn whiteout_m2_M2ShadowBatch_set_colorId(
11743            self_: *mut whiteout_M2ShadowBatch,
11744            value: u16,
11745        );
11746        pub fn whiteout_m2_M2ShadowBatch_get_transparencyId(
11747            self_: *mut whiteout_M2ShadowBatch,
11748        ) -> u16;
11749        pub fn whiteout_m2_M2ShadowBatch_set_transparencyId(
11750            self_: *mut whiteout_M2ShadowBatch,
11751            value: u16,
11752        );
11753        // SkinProfile
11754        pub fn whiteout_m2_M2SkinProfile_new() -> *mut whiteout_M2SkinProfile;
11755        pub fn whiteout_m2_M2SkinProfile_delete(self_: *mut whiteout_M2SkinProfile);
11756        pub fn whiteout_m2_M2SkinProfile_get_vertices_count(
11757            self_: *mut whiteout_M2SkinProfile,
11758        ) -> usize;
11759        pub fn whiteout_m2_M2SkinProfile_resize_vertices(
11760            self_: *mut whiteout_M2SkinProfile,
11761            count: usize,
11762        );
11763        pub fn whiteout_m2_M2SkinProfile_get_vertices_data(
11764            self_: *mut whiteout_M2SkinProfile,
11765        ) -> *const u16;
11766        pub fn whiteout_m2_M2SkinProfile_assign_vertices(
11767            self_: *mut whiteout_M2SkinProfile,
11768            data: *const u16,
11769            count: usize,
11770        );
11771        pub fn whiteout_m2_M2SkinProfile_get_indices_count(
11772            self_: *mut whiteout_M2SkinProfile,
11773        ) -> usize;
11774        pub fn whiteout_m2_M2SkinProfile_resize_indices(
11775            self_: *mut whiteout_M2SkinProfile,
11776            count: usize,
11777        );
11778        pub fn whiteout_m2_M2SkinProfile_get_indices_data(
11779            self_: *mut whiteout_M2SkinProfile,
11780        ) -> *const u16;
11781        pub fn whiteout_m2_M2SkinProfile_assign_indices(
11782            self_: *mut whiteout_M2SkinProfile,
11783            data: *const u16,
11784            count: usize,
11785        );
11786        pub fn whiteout_m2_M2SkinProfile_get_submeshes_count(
11787            self_: *mut whiteout_M2SkinProfile,
11788        ) -> usize;
11789        pub fn whiteout_m2_M2SkinProfile_resize_submeshes(
11790            self_: *mut whiteout_M2SkinProfile,
11791            count: usize,
11792        );
11793        pub fn whiteout_m2_M2SkinProfile_get_submeshes_at(
11794            self_: *mut whiteout_M2SkinProfile,
11795            index: usize,
11796        ) -> *mut whiteout_M2SkinSection;
11797        pub fn whiteout_m2_M2SkinProfile_get_batches_count(
11798            self_: *mut whiteout_M2SkinProfile,
11799        ) -> usize;
11800        pub fn whiteout_m2_M2SkinProfile_resize_batches(
11801            self_: *mut whiteout_M2SkinProfile,
11802            count: usize,
11803        );
11804        pub fn whiteout_m2_M2SkinProfile_get_batches_at(
11805            self_: *mut whiteout_M2SkinProfile,
11806            index: usize,
11807        ) -> *mut whiteout_M2Batch;
11808        pub fn whiteout_m2_M2SkinProfile_get_lodVertexBase(
11809            self_: *mut whiteout_M2SkinProfile,
11810        ) -> u32;
11811        pub fn whiteout_m2_M2SkinProfile_set_lodVertexBase(
11812            self_: *mut whiteout_M2SkinProfile,
11813            value: u32,
11814        );
11815        pub fn whiteout_m2_M2SkinProfile_get_shadowBatches_count(
11816            self_: *mut whiteout_M2SkinProfile,
11817        ) -> usize;
11818        pub fn whiteout_m2_M2SkinProfile_resize_shadowBatches(
11819            self_: *mut whiteout_M2SkinProfile,
11820            count: usize,
11821        );
11822        pub fn whiteout_m2_M2SkinProfile_get_shadowBatches_at(
11823            self_: *mut whiteout_M2SkinProfile,
11824            index: usize,
11825        ) -> *mut whiteout_M2ShadowBatch;
11826        // GlobalFlags
11827        pub fn whiteout_m2_M2GlobalFlags_new() -> *mut whiteout_M2GlobalFlags;
11828        pub fn whiteout_m2_M2GlobalFlags_delete(self_: *mut whiteout_M2GlobalFlags);
11829        pub fn whiteout_m2_M2GlobalFlags_get_value(self_: *mut whiteout_M2GlobalFlags) -> i32;
11830        pub fn whiteout_m2_M2GlobalFlags_set_value(self_: *mut whiteout_M2GlobalFlags, value: i32);
11831        // GlobalSequence
11832        pub fn whiteout_m2_M2GlobalSequence_new() -> *mut whiteout_M2GlobalSequence;
11833        pub fn whiteout_m2_M2GlobalSequence_delete(self_: *mut whiteout_M2GlobalSequence);
11834        pub fn whiteout_m2_M2GlobalSequence_get_timestamp(
11835            self_: *mut whiteout_M2GlobalSequence,
11836        ) -> u32;
11837        pub fn whiteout_m2_M2GlobalSequence_set_timestamp(
11838            self_: *mut whiteout_M2GlobalSequence,
11839            value: u32,
11840        );
11841        // Sequence
11842        pub fn whiteout_m2_M2Sequence_new() -> *mut whiteout_M2Sequence;
11843        pub fn whiteout_m2_M2Sequence_delete(self_: *mut whiteout_M2Sequence);
11844        pub fn whiteout_m2_M2Sequence_get_id(self_: *mut whiteout_M2Sequence) -> u16;
11845        pub fn whiteout_m2_M2Sequence_set_id(self_: *mut whiteout_M2Sequence, value: u16);
11846        pub fn whiteout_m2_M2Sequence_get_variationIndex(self_: *mut whiteout_M2Sequence) -> u16;
11847        pub fn whiteout_m2_M2Sequence_set_variationIndex(
11848            self_: *mut whiteout_M2Sequence,
11849            value: u16,
11850        );
11851        pub fn whiteout_m2_M2Sequence_get_duration(self_: *mut whiteout_M2Sequence) -> u32;
11852        pub fn whiteout_m2_M2Sequence_set_duration(self_: *mut whiteout_M2Sequence, value: u32);
11853        pub fn whiteout_m2_M2Sequence_get_movespeed(self_: *mut whiteout_M2Sequence) -> f32;
11854        pub fn whiteout_m2_M2Sequence_set_movespeed(self_: *mut whiteout_M2Sequence, value: f32);
11855        pub fn whiteout_m2_M2Sequence_get_flags(self_: *mut whiteout_M2Sequence) -> i32;
11856        pub fn whiteout_m2_M2Sequence_set_flags(self_: *mut whiteout_M2Sequence, value: i32);
11857        pub fn whiteout_m2_M2Sequence_get_frequency(self_: *mut whiteout_M2Sequence) -> i16;
11858        pub fn whiteout_m2_M2Sequence_set_frequency(self_: *mut whiteout_M2Sequence, value: i16);
11859        pub fn whiteout_m2_M2Sequence_get_padding(self_: *mut whiteout_M2Sequence) -> u16;
11860        pub fn whiteout_m2_M2Sequence_set_padding(self_: *mut whiteout_M2Sequence, value: u16);
11861        pub fn whiteout_m2_M2Sequence_get_replayMin(self_: *mut whiteout_M2Sequence) -> u32;
11862        pub fn whiteout_m2_M2Sequence_set_replayMin(self_: *mut whiteout_M2Sequence, value: u32);
11863        pub fn whiteout_m2_M2Sequence_get_replayMax(self_: *mut whiteout_M2Sequence) -> u32;
11864        pub fn whiteout_m2_M2Sequence_set_replayMax(self_: *mut whiteout_M2Sequence, value: u32);
11865        pub fn whiteout_m2_M2Sequence_get_blendTimeIn(self_: *mut whiteout_M2Sequence) -> u16;
11866        pub fn whiteout_m2_M2Sequence_set_blendTimeIn(self_: *mut whiteout_M2Sequence, value: u16);
11867        pub fn whiteout_m2_M2Sequence_get_blendTimeOut(self_: *mut whiteout_M2Sequence) -> u16;
11868        pub fn whiteout_m2_M2Sequence_set_blendTimeOut(self_: *mut whiteout_M2Sequence, value: u16);
11869        pub fn whiteout_m2_M2Sequence_get_bounding(
11870            self_: *mut whiteout_M2Sequence,
11871        ) -> *mut whiteout_M2Extent;
11872        pub fn whiteout_m2_M2Sequence_set_bounding(
11873            self_: *mut whiteout_M2Sequence,
11874            value: *const whiteout_M2Extent,
11875        );
11876        pub fn whiteout_m2_M2Sequence_get_variationNext(self_: *mut whiteout_M2Sequence) -> i16;
11877        pub fn whiteout_m2_M2Sequence_set_variationNext(
11878            self_: *mut whiteout_M2Sequence,
11879            value: i16,
11880        );
11881        pub fn whiteout_m2_M2Sequence_get_aliasNext(self_: *mut whiteout_M2Sequence) -> u16;
11882        pub fn whiteout_m2_M2Sequence_set_aliasNext(self_: *mut whiteout_M2Sequence, value: u16);
11883        // Vertex
11884        pub fn whiteout_m2_M2Vertex_new() -> *mut whiteout_M2Vertex;
11885        pub fn whiteout_m2_M2Vertex_delete(self_: *mut whiteout_M2Vertex);
11886        pub fn whiteout_m2_M2Vertex_get_position(
11887            self_: *mut whiteout_M2Vertex,
11888        ) -> *mut core::ffi::c_void;
11889        pub fn whiteout_m2_M2Vertex_set_position(
11890            self_: *mut whiteout_M2Vertex,
11891            value: *const core::ffi::c_void,
11892        );
11893        pub fn whiteout_m2_M2Vertex_boneWeights_size() -> usize;
11894        pub fn whiteout_m2_M2Vertex_get_boneWeights_at(
11895            self_: *mut whiteout_M2Vertex,
11896            index: usize,
11897        ) -> u8;
11898        pub fn whiteout_m2_M2Vertex_set_boneWeights_at(
11899            self_: *mut whiteout_M2Vertex,
11900            index: usize,
11901            value: u8,
11902        );
11903        pub fn whiteout_m2_M2Vertex_boneIndices_size() -> usize;
11904        pub fn whiteout_m2_M2Vertex_get_boneIndices_at(
11905            self_: *mut whiteout_M2Vertex,
11906            index: usize,
11907        ) -> u8;
11908        pub fn whiteout_m2_M2Vertex_set_boneIndices_at(
11909            self_: *mut whiteout_M2Vertex,
11910            index: usize,
11911            value: u8,
11912        );
11913        pub fn whiteout_m2_M2Vertex_get_normal(
11914            self_: *mut whiteout_M2Vertex,
11915        ) -> *mut core::ffi::c_void;
11916        pub fn whiteout_m2_M2Vertex_set_normal(
11917            self_: *mut whiteout_M2Vertex,
11918            value: *const core::ffi::c_void,
11919        );
11920        pub fn whiteout_m2_M2Vertex_texCoords_size() -> usize;
11921        pub fn whiteout_m2_M2Vertex_get_texCoords_at(
11922            self_: *mut whiteout_M2Vertex,
11923            index: usize,
11924        ) -> *mut core::ffi::c_void;
11925        // Bone
11926        pub fn whiteout_m2_M2Bone_new() -> *mut whiteout_M2Bone;
11927        pub fn whiteout_m2_M2Bone_delete(self_: *mut whiteout_M2Bone);
11928        pub fn whiteout_m2_M2Bone_get_keyBoneId(self_: *mut whiteout_M2Bone) -> i32;
11929        pub fn whiteout_m2_M2Bone_set_keyBoneId(self_: *mut whiteout_M2Bone, value: i32);
11930        pub fn whiteout_m2_M2Bone_get_flags(self_: *mut whiteout_M2Bone) -> u32;
11931        pub fn whiteout_m2_M2Bone_set_flags(self_: *mut whiteout_M2Bone, value: u32);
11932        pub fn whiteout_m2_M2Bone_get_parentBoneId(self_: *mut whiteout_M2Bone) -> i16;
11933        pub fn whiteout_m2_M2Bone_set_parentBoneId(self_: *mut whiteout_M2Bone, value: i16);
11934        pub fn whiteout_m2_M2Bone_get_submeshId(self_: *mut whiteout_M2Bone) -> u16;
11935        pub fn whiteout_m2_M2Bone_set_submeshId(self_: *mut whiteout_M2Bone, value: u16);
11936        pub fn whiteout_m2_M2Bone_get_boneNameCRC(self_: *mut whiteout_M2Bone) -> u32;
11937        pub fn whiteout_m2_M2Bone_set_boneNameCRC(self_: *mut whiteout_M2Bone, value: u32);
11938        pub fn whiteout_m2_M2Bone_get_translation(
11939            self_: *mut whiteout_M2Bone,
11940        ) -> *mut whiteout_M2AnimationTrackVector3f;
11941        pub fn whiteout_m2_M2Bone_set_translation(
11942            self_: *mut whiteout_M2Bone,
11943            value: *const whiteout_M2AnimationTrackVector3f,
11944        );
11945        pub fn whiteout_m2_M2Bone_get_rotation(
11946            self_: *mut whiteout_M2Bone,
11947        ) -> *mut whiteout_M2AnimationTrackM2CompatQuaternion;
11948        pub fn whiteout_m2_M2Bone_set_rotation(
11949            self_: *mut whiteout_M2Bone,
11950            value: *const whiteout_M2AnimationTrackM2CompatQuaternion,
11951        );
11952        pub fn whiteout_m2_M2Bone_get_scale(
11953            self_: *mut whiteout_M2Bone,
11954        ) -> *mut whiteout_M2AnimationTrackVector3f;
11955        pub fn whiteout_m2_M2Bone_set_scale(
11956            self_: *mut whiteout_M2Bone,
11957            value: *const whiteout_M2AnimationTrackVector3f,
11958        );
11959        pub fn whiteout_m2_M2Bone_get_pivot(self_: *mut whiteout_M2Bone) -> *mut core::ffi::c_void;
11960        pub fn whiteout_m2_M2Bone_set_pivot(
11961            self_: *mut whiteout_M2Bone,
11962            value: *const core::ffi::c_void,
11963        );
11964        // Texture
11965        pub fn whiteout_m2_M2Texture_new() -> *mut whiteout_M2Texture;
11966        pub fn whiteout_m2_M2Texture_delete(self_: *mut whiteout_M2Texture);
11967        pub fn whiteout_m2_M2Texture_get_type(self_: *mut whiteout_M2Texture) -> u32;
11968        pub fn whiteout_m2_M2Texture_set_type(self_: *mut whiteout_M2Texture, value: u32);
11969        pub fn whiteout_m2_M2Texture_get_flags(self_: *mut whiteout_M2Texture) -> u32;
11970        pub fn whiteout_m2_M2Texture_set_flags(self_: *mut whiteout_M2Texture, value: u32);
11971        pub fn whiteout_m2_M2Texture_get_filename(self_: *mut whiteout_M2Texture) -> RawCString;
11972        pub fn whiteout_m2_M2Texture_set_filename(
11973            self_: *mut whiteout_M2Texture,
11974            value: *const core::ffi::c_char,
11975        );
11976        // Material
11977        pub fn whiteout_m2_M2Material_new() -> *mut whiteout_M2Material;
11978        pub fn whiteout_m2_M2Material_delete(self_: *mut whiteout_M2Material);
11979        pub fn whiteout_m2_M2Material_get_flags(self_: *mut whiteout_M2Material) -> u16;
11980        pub fn whiteout_m2_M2Material_set_flags(self_: *mut whiteout_M2Material, value: u16);
11981        pub fn whiteout_m2_M2Material_get_blendingMode(self_: *mut whiteout_M2Material) -> u16;
11982        pub fn whiteout_m2_M2Material_set_blendingMode(self_: *mut whiteout_M2Material, value: u16);
11983        // TextureWeight
11984        pub fn whiteout_m2_M2TextureWeight_new() -> *mut whiteout_M2TextureWeight;
11985        pub fn whiteout_m2_M2TextureWeight_delete(self_: *mut whiteout_M2TextureWeight);
11986        pub fn whiteout_m2_M2TextureWeight_get_weight(
11987            self_: *mut whiteout_M2TextureWeight,
11988        ) -> *mut whiteout_M2AnimationTrackI16;
11989        pub fn whiteout_m2_M2TextureWeight_set_weight(
11990            self_: *mut whiteout_M2TextureWeight,
11991            value: *const whiteout_M2AnimationTrackI16,
11992        );
11993        // TextureTransform
11994        pub fn whiteout_m2_M2TextureTransform_new() -> *mut whiteout_M2TextureTransform;
11995        pub fn whiteout_m2_M2TextureTransform_delete(self_: *mut whiteout_M2TextureTransform);
11996        pub fn whiteout_m2_M2TextureTransform_get_translation(
11997            self_: *mut whiteout_M2TextureTransform,
11998        ) -> *mut whiteout_M2AnimationTrackVector3f;
11999        pub fn whiteout_m2_M2TextureTransform_set_translation(
12000            self_: *mut whiteout_M2TextureTransform,
12001            value: *const whiteout_M2AnimationTrackVector3f,
12002        );
12003        pub fn whiteout_m2_M2TextureTransform_get_rotation(
12004            self_: *mut whiteout_M2TextureTransform,
12005        ) -> *mut whiteout_M2AnimationTrackM2CompatQuaternion;
12006        pub fn whiteout_m2_M2TextureTransform_set_rotation(
12007            self_: *mut whiteout_M2TextureTransform,
12008            value: *const whiteout_M2AnimationTrackM2CompatQuaternion,
12009        );
12010        pub fn whiteout_m2_M2TextureTransform_get_scaling(
12011            self_: *mut whiteout_M2TextureTransform,
12012        ) -> *mut whiteout_M2AnimationTrackVector3f;
12013        pub fn whiteout_m2_M2TextureTransform_set_scaling(
12014            self_: *mut whiteout_M2TextureTransform,
12015            value: *const whiteout_M2AnimationTrackVector3f,
12016        );
12017        // ColorAnimation
12018        pub fn whiteout_m2_M2ColorAnimation_new() -> *mut whiteout_M2ColorAnimation;
12019        pub fn whiteout_m2_M2ColorAnimation_delete(self_: *mut whiteout_M2ColorAnimation);
12020        pub fn whiteout_m2_M2ColorAnimation_get_color(
12021            self_: *mut whiteout_M2ColorAnimation,
12022        ) -> *mut whiteout_M2AnimationTrackVector3f;
12023        pub fn whiteout_m2_M2ColorAnimation_set_color(
12024            self_: *mut whiteout_M2ColorAnimation,
12025            value: *const whiteout_M2AnimationTrackVector3f,
12026        );
12027        pub fn whiteout_m2_M2ColorAnimation_get_alpha(
12028            self_: *mut whiteout_M2ColorAnimation,
12029        ) -> *mut whiteout_M2AnimationTrackI16;
12030        pub fn whiteout_m2_M2ColorAnimation_set_alpha(
12031            self_: *mut whiteout_M2ColorAnimation,
12032            value: *const whiteout_M2AnimationTrackI16,
12033        );
12034        // Light
12035        pub fn whiteout_m2_M2Light_new() -> *mut whiteout_M2Light;
12036        pub fn whiteout_m2_M2Light_delete(self_: *mut whiteout_M2Light);
12037        pub fn whiteout_m2_M2Light_get_type(self_: *mut whiteout_M2Light) -> u16;
12038        pub fn whiteout_m2_M2Light_set_type(self_: *mut whiteout_M2Light, value: u16);
12039        pub fn whiteout_m2_M2Light_get_boneId(self_: *mut whiteout_M2Light) -> i16;
12040        pub fn whiteout_m2_M2Light_set_boneId(self_: *mut whiteout_M2Light, value: i16);
12041        pub fn whiteout_m2_M2Light_get_position(
12042            self_: *mut whiteout_M2Light,
12043        ) -> *mut core::ffi::c_void;
12044        pub fn whiteout_m2_M2Light_set_position(
12045            self_: *mut whiteout_M2Light,
12046            value: *const core::ffi::c_void,
12047        );
12048        pub fn whiteout_m2_M2Light_get_ambientColor(
12049            self_: *mut whiteout_M2Light,
12050        ) -> *mut whiteout_M2AnimationTrackVector3f;
12051        pub fn whiteout_m2_M2Light_set_ambientColor(
12052            self_: *mut whiteout_M2Light,
12053            value: *const whiteout_M2AnimationTrackVector3f,
12054        );
12055        pub fn whiteout_m2_M2Light_get_ambientIntensity(
12056            self_: *mut whiteout_M2Light,
12057        ) -> *mut whiteout_M2AnimationTrackF32;
12058        pub fn whiteout_m2_M2Light_set_ambientIntensity(
12059            self_: *mut whiteout_M2Light,
12060            value: *const whiteout_M2AnimationTrackF32,
12061        );
12062        pub fn whiteout_m2_M2Light_get_diffuseColor(
12063            self_: *mut whiteout_M2Light,
12064        ) -> *mut whiteout_M2AnimationTrackVector3f;
12065        pub fn whiteout_m2_M2Light_set_diffuseColor(
12066            self_: *mut whiteout_M2Light,
12067            value: *const whiteout_M2AnimationTrackVector3f,
12068        );
12069        pub fn whiteout_m2_M2Light_get_diffuseIntensity(
12070            self_: *mut whiteout_M2Light,
12071        ) -> *mut whiteout_M2AnimationTrackF32;
12072        pub fn whiteout_m2_M2Light_set_diffuseIntensity(
12073            self_: *mut whiteout_M2Light,
12074            value: *const whiteout_M2AnimationTrackF32,
12075        );
12076        pub fn whiteout_m2_M2Light_get_attenuationStart(
12077            self_: *mut whiteout_M2Light,
12078        ) -> *mut whiteout_M2AnimationTrackF32;
12079        pub fn whiteout_m2_M2Light_set_attenuationStart(
12080            self_: *mut whiteout_M2Light,
12081            value: *const whiteout_M2AnimationTrackF32,
12082        );
12083        pub fn whiteout_m2_M2Light_get_attenuationEnd(
12084            self_: *mut whiteout_M2Light,
12085        ) -> *mut whiteout_M2AnimationTrackF32;
12086        pub fn whiteout_m2_M2Light_set_attenuationEnd(
12087            self_: *mut whiteout_M2Light,
12088            value: *const whiteout_M2AnimationTrackF32,
12089        );
12090        pub fn whiteout_m2_M2Light_get_visibility(
12091            self_: *mut whiteout_M2Light,
12092        ) -> *mut whiteout_M2AnimationTrackU8;
12093        pub fn whiteout_m2_M2Light_set_visibility(
12094            self_: *mut whiteout_M2Light,
12095            value: *const whiteout_M2AnimationTrackU8,
12096        );
12097        // CameraSpline
12098        pub fn whiteout_m2_M2CameraSpline_new() -> *mut whiteout_M2CameraSpline;
12099        pub fn whiteout_m2_M2CameraSpline_delete(self_: *mut whiteout_M2CameraSpline);
12100        pub fn whiteout_m2_M2CameraSpline_get_value(
12101            self_: *mut whiteout_M2CameraSpline,
12102        ) -> *mut core::ffi::c_void;
12103        pub fn whiteout_m2_M2CameraSpline_set_value(
12104            self_: *mut whiteout_M2CameraSpline,
12105            value: *const core::ffi::c_void,
12106        );
12107        pub fn whiteout_m2_M2CameraSpline_get_inTangent(
12108            self_: *mut whiteout_M2CameraSpline,
12109        ) -> *mut core::ffi::c_void;
12110        pub fn whiteout_m2_M2CameraSpline_set_inTangent(
12111            self_: *mut whiteout_M2CameraSpline,
12112            value: *const core::ffi::c_void,
12113        );
12114        pub fn whiteout_m2_M2CameraSpline_get_outTangent(
12115            self_: *mut whiteout_M2CameraSpline,
12116        ) -> *mut core::ffi::c_void;
12117        pub fn whiteout_m2_M2CameraSpline_set_outTangent(
12118            self_: *mut whiteout_M2CameraSpline,
12119            value: *const core::ffi::c_void,
12120        );
12121        // Camera
12122        pub fn whiteout_m2_M2Camera_new() -> *mut whiteout_M2Camera;
12123        pub fn whiteout_m2_M2Camera_delete(self_: *mut whiteout_M2Camera);
12124        pub fn whiteout_m2_M2Camera_get_type(self_: *mut whiteout_M2Camera) -> u32;
12125        pub fn whiteout_m2_M2Camera_set_type(self_: *mut whiteout_M2Camera, value: u32);
12126        pub fn whiteout_m2_M2Camera_get_fieldOfView(self_: *mut whiteout_M2Camera) -> f32;
12127        pub fn whiteout_m2_M2Camera_set_fieldOfView(self_: *mut whiteout_M2Camera, value: f32);
12128        pub fn whiteout_m2_M2Camera_get_farClip(self_: *mut whiteout_M2Camera) -> f32;
12129        pub fn whiteout_m2_M2Camera_set_farClip(self_: *mut whiteout_M2Camera, value: f32);
12130        pub fn whiteout_m2_M2Camera_get_nearClip(self_: *mut whiteout_M2Camera) -> f32;
12131        pub fn whiteout_m2_M2Camera_set_nearClip(self_: *mut whiteout_M2Camera, value: f32);
12132        pub fn whiteout_m2_M2Camera_get_positions(
12133            self_: *mut whiteout_M2Camera,
12134        ) -> *mut whiteout_M2AnimationTrackM2CameraSpline;
12135        pub fn whiteout_m2_M2Camera_set_positions(
12136            self_: *mut whiteout_M2Camera,
12137            value: *const whiteout_M2AnimationTrackM2CameraSpline,
12138        );
12139        pub fn whiteout_m2_M2Camera_get_positionBase(
12140            self_: *mut whiteout_M2Camera,
12141        ) -> *mut core::ffi::c_void;
12142        pub fn whiteout_m2_M2Camera_set_positionBase(
12143            self_: *mut whiteout_M2Camera,
12144            value: *const core::ffi::c_void,
12145        );
12146        pub fn whiteout_m2_M2Camera_get_targetPositions(
12147            self_: *mut whiteout_M2Camera,
12148        ) -> *mut whiteout_M2AnimationTrackM2CameraSpline;
12149        pub fn whiteout_m2_M2Camera_set_targetPositions(
12150            self_: *mut whiteout_M2Camera,
12151            value: *const whiteout_M2AnimationTrackM2CameraSpline,
12152        );
12153        pub fn whiteout_m2_M2Camera_get_targetPositionBase(
12154            self_: *mut whiteout_M2Camera,
12155        ) -> *mut core::ffi::c_void;
12156        pub fn whiteout_m2_M2Camera_set_targetPositionBase(
12157            self_: *mut whiteout_M2Camera,
12158            value: *const core::ffi::c_void,
12159        );
12160        pub fn whiteout_m2_M2Camera_get_roll(
12161            self_: *mut whiteout_M2Camera,
12162        ) -> *mut whiteout_M2AnimationTrackF32;
12163        pub fn whiteout_m2_M2Camera_set_roll(
12164            self_: *mut whiteout_M2Camera,
12165            value: *const whiteout_M2AnimationTrackF32,
12166        );
12167        pub fn whiteout_m2_M2Camera_get_fieldOfViewTrack(
12168            self_: *mut whiteout_M2Camera,
12169        ) -> *mut whiteout_M2AnimationTrackF32;
12170        pub fn whiteout_m2_M2Camera_set_fieldOfViewTrack(
12171            self_: *mut whiteout_M2Camera,
12172            value: *const whiteout_M2AnimationTrackF32,
12173        );
12174        // Attachment
12175        pub fn whiteout_m2_M2Attachment_new() -> *mut whiteout_M2Attachment;
12176        pub fn whiteout_m2_M2Attachment_delete(self_: *mut whiteout_M2Attachment);
12177        pub fn whiteout_m2_M2Attachment_get_id(self_: *mut whiteout_M2Attachment) -> u32;
12178        pub fn whiteout_m2_M2Attachment_set_id(self_: *mut whiteout_M2Attachment, value: u32);
12179        pub fn whiteout_m2_M2Attachment_get_boneId(self_: *mut whiteout_M2Attachment) -> u16;
12180        pub fn whiteout_m2_M2Attachment_set_boneId(self_: *mut whiteout_M2Attachment, value: u16);
12181        pub fn whiteout_m2_M2Attachment_get_unknown(self_: *mut whiteout_M2Attachment) -> u16;
12182        pub fn whiteout_m2_M2Attachment_set_unknown(self_: *mut whiteout_M2Attachment, value: u16);
12183        pub fn whiteout_m2_M2Attachment_get_position(
12184            self_: *mut whiteout_M2Attachment,
12185        ) -> *mut core::ffi::c_void;
12186        pub fn whiteout_m2_M2Attachment_set_position(
12187            self_: *mut whiteout_M2Attachment,
12188            value: *const core::ffi::c_void,
12189        );
12190        pub fn whiteout_m2_M2Attachment_get_animate(
12191            self_: *mut whiteout_M2Attachment,
12192        ) -> *mut whiteout_M2AnimationTrackU8;
12193        pub fn whiteout_m2_M2Attachment_set_animate(
12194            self_: *mut whiteout_M2Attachment,
12195            value: *const whiteout_M2AnimationTrackU8,
12196        );
12197        // RibbonEmitter
12198        pub fn whiteout_m2_M2RibbonEmitter_new() -> *mut whiteout_M2RibbonEmitter;
12199        pub fn whiteout_m2_M2RibbonEmitter_delete(self_: *mut whiteout_M2RibbonEmitter);
12200        pub fn whiteout_m2_M2RibbonEmitter_get_ribbonId(
12201            self_: *mut whiteout_M2RibbonEmitter,
12202        ) -> u32;
12203        pub fn whiteout_m2_M2RibbonEmitter_set_ribbonId(
12204            self_: *mut whiteout_M2RibbonEmitter,
12205            value: u32,
12206        );
12207        pub fn whiteout_m2_M2RibbonEmitter_get_boneId(self_: *mut whiteout_M2RibbonEmitter) -> u32;
12208        pub fn whiteout_m2_M2RibbonEmitter_set_boneId(
12209            self_: *mut whiteout_M2RibbonEmitter,
12210            value: u32,
12211        );
12212        pub fn whiteout_m2_M2RibbonEmitter_get_position(
12213            self_: *mut whiteout_M2RibbonEmitter,
12214        ) -> *mut core::ffi::c_void;
12215        pub fn whiteout_m2_M2RibbonEmitter_set_position(
12216            self_: *mut whiteout_M2RibbonEmitter,
12217            value: *const core::ffi::c_void,
12218        );
12219        pub fn whiteout_m2_M2RibbonEmitter_get_textureIndices_count(
12220            self_: *mut whiteout_M2RibbonEmitter,
12221        ) -> usize;
12222        pub fn whiteout_m2_M2RibbonEmitter_resize_textureIndices(
12223            self_: *mut whiteout_M2RibbonEmitter,
12224            count: usize,
12225        );
12226        pub fn whiteout_m2_M2RibbonEmitter_get_textureIndices_data(
12227            self_: *mut whiteout_M2RibbonEmitter,
12228        ) -> *const u16;
12229        pub fn whiteout_m2_M2RibbonEmitter_assign_textureIndices(
12230            self_: *mut whiteout_M2RibbonEmitter,
12231            data: *const u16,
12232            count: usize,
12233        );
12234        pub fn whiteout_m2_M2RibbonEmitter_get_materialIndices_count(
12235            self_: *mut whiteout_M2RibbonEmitter,
12236        ) -> usize;
12237        pub fn whiteout_m2_M2RibbonEmitter_resize_materialIndices(
12238            self_: *mut whiteout_M2RibbonEmitter,
12239            count: usize,
12240        );
12241        pub fn whiteout_m2_M2RibbonEmitter_get_materialIndices_data(
12242            self_: *mut whiteout_M2RibbonEmitter,
12243        ) -> *const u16;
12244        pub fn whiteout_m2_M2RibbonEmitter_assign_materialIndices(
12245            self_: *mut whiteout_M2RibbonEmitter,
12246            data: *const u16,
12247            count: usize,
12248        );
12249        pub fn whiteout_m2_M2RibbonEmitter_get_colorTrack(
12250            self_: *mut whiteout_M2RibbonEmitter,
12251        ) -> *mut whiteout_M2AnimationTrackVector3f;
12252        pub fn whiteout_m2_M2RibbonEmitter_set_colorTrack(
12253            self_: *mut whiteout_M2RibbonEmitter,
12254            value: *const whiteout_M2AnimationTrackVector3f,
12255        );
12256        pub fn whiteout_m2_M2RibbonEmitter_get_alphaTrack(
12257            self_: *mut whiteout_M2RibbonEmitter,
12258        ) -> *mut whiteout_M2AnimationTrackI16;
12259        pub fn whiteout_m2_M2RibbonEmitter_set_alphaTrack(
12260            self_: *mut whiteout_M2RibbonEmitter,
12261            value: *const whiteout_M2AnimationTrackI16,
12262        );
12263        pub fn whiteout_m2_M2RibbonEmitter_get_heightAbove(
12264            self_: *mut whiteout_M2RibbonEmitter,
12265        ) -> *mut whiteout_M2AnimationTrackF32;
12266        pub fn whiteout_m2_M2RibbonEmitter_set_heightAbove(
12267            self_: *mut whiteout_M2RibbonEmitter,
12268            value: *const whiteout_M2AnimationTrackF32,
12269        );
12270        pub fn whiteout_m2_M2RibbonEmitter_get_heightBelow(
12271            self_: *mut whiteout_M2RibbonEmitter,
12272        ) -> *mut whiteout_M2AnimationTrackF32;
12273        pub fn whiteout_m2_M2RibbonEmitter_set_heightBelow(
12274            self_: *mut whiteout_M2RibbonEmitter,
12275            value: *const whiteout_M2AnimationTrackF32,
12276        );
12277        pub fn whiteout_m2_M2RibbonEmitter_get_edgesPerSecond(
12278            self_: *mut whiteout_M2RibbonEmitter,
12279        ) -> f32;
12280        pub fn whiteout_m2_M2RibbonEmitter_set_edgesPerSecond(
12281            self_: *mut whiteout_M2RibbonEmitter,
12282            value: f32,
12283        );
12284        pub fn whiteout_m2_M2RibbonEmitter_get_edgeLifetime(
12285            self_: *mut whiteout_M2RibbonEmitter,
12286        ) -> f32;
12287        pub fn whiteout_m2_M2RibbonEmitter_set_edgeLifetime(
12288            self_: *mut whiteout_M2RibbonEmitter,
12289            value: f32,
12290        );
12291        pub fn whiteout_m2_M2RibbonEmitter_get_gravity(self_: *mut whiteout_M2RibbonEmitter)
12292            -> f32;
12293        pub fn whiteout_m2_M2RibbonEmitter_set_gravity(
12294            self_: *mut whiteout_M2RibbonEmitter,
12295            value: f32,
12296        );
12297        pub fn whiteout_m2_M2RibbonEmitter_get_textureRows(
12298            self_: *mut whiteout_M2RibbonEmitter,
12299        ) -> u16;
12300        pub fn whiteout_m2_M2RibbonEmitter_set_textureRows(
12301            self_: *mut whiteout_M2RibbonEmitter,
12302            value: u16,
12303        );
12304        pub fn whiteout_m2_M2RibbonEmitter_get_textureCols(
12305            self_: *mut whiteout_M2RibbonEmitter,
12306        ) -> u16;
12307        pub fn whiteout_m2_M2RibbonEmitter_set_textureCols(
12308            self_: *mut whiteout_M2RibbonEmitter,
12309            value: u16,
12310        );
12311        pub fn whiteout_m2_M2RibbonEmitter_get_texSlot(
12312            self_: *mut whiteout_M2RibbonEmitter,
12313        ) -> *mut whiteout_M2AnimationTrackU16;
12314        pub fn whiteout_m2_M2RibbonEmitter_set_texSlot(
12315            self_: *mut whiteout_M2RibbonEmitter,
12316            value: *const whiteout_M2AnimationTrackU16,
12317        );
12318        pub fn whiteout_m2_M2RibbonEmitter_get_visibility(
12319            self_: *mut whiteout_M2RibbonEmitter,
12320        ) -> *mut whiteout_M2AnimationTrackU8;
12321        pub fn whiteout_m2_M2RibbonEmitter_set_visibility(
12322            self_: *mut whiteout_M2RibbonEmitter,
12323            value: *const whiteout_M2AnimationTrackU8,
12324        );
12325        pub fn whiteout_m2_M2RibbonEmitter_get_priorityPlane(
12326            self_: *mut whiteout_M2RibbonEmitter,
12327        ) -> i16;
12328        pub fn whiteout_m2_M2RibbonEmitter_set_priorityPlane(
12329            self_: *mut whiteout_M2RibbonEmitter,
12330            value: i16,
12331        );
12332        pub fn whiteout_m2_M2RibbonEmitter_get_ribbonColorIndex(
12333            self_: *mut whiteout_M2RibbonEmitter,
12334        ) -> i8;
12335        pub fn whiteout_m2_M2RibbonEmitter_set_ribbonColorIndex(
12336            self_: *mut whiteout_M2RibbonEmitter,
12337            value: i8,
12338        );
12339        pub fn whiteout_m2_M2RibbonEmitter_get_textureTransformIndex(
12340            self_: *mut whiteout_M2RibbonEmitter,
12341        ) -> i8;
12342        pub fn whiteout_m2_M2RibbonEmitter_set_textureTransformIndex(
12343            self_: *mut whiteout_M2RibbonEmitter,
12344            value: i8,
12345        );
12346        // Box
12347        pub fn whiteout_m2_M2Box_new() -> *mut whiteout_M2Box;
12348        pub fn whiteout_m2_M2Box_delete(self_: *mut whiteout_M2Box);
12349        pub fn whiteout_m2_M2Box_get_minimum(self_: *mut whiteout_M2Box) -> *mut core::ffi::c_void;
12350        pub fn whiteout_m2_M2Box_set_minimum(
12351            self_: *mut whiteout_M2Box,
12352            value: *const core::ffi::c_void,
12353        );
12354        pub fn whiteout_m2_M2Box_get_maximum(self_: *mut whiteout_M2Box) -> *mut core::ffi::c_void;
12355        pub fn whiteout_m2_M2Box_set_maximum(
12356            self_: *mut whiteout_M2Box,
12357            value: *const core::ffi::c_void,
12358        );
12359        // ParticleEmitter
12360        pub fn whiteout_m2_M2ParticleEmitter_new() -> *mut whiteout_M2ParticleEmitter;
12361        pub fn whiteout_m2_M2ParticleEmitter_delete(self_: *mut whiteout_M2ParticleEmitter);
12362        pub fn whiteout_m2_M2ParticleEmitter_get_particleId(
12363            self_: *mut whiteout_M2ParticleEmitter,
12364        ) -> u32;
12365        pub fn whiteout_m2_M2ParticleEmitter_set_particleId(
12366            self_: *mut whiteout_M2ParticleEmitter,
12367            value: u32,
12368        );
12369        pub fn whiteout_m2_M2ParticleEmitter_get_flags(
12370            self_: *mut whiteout_M2ParticleEmitter,
12371        ) -> i32;
12372        pub fn whiteout_m2_M2ParticleEmitter_set_flags(
12373            self_: *mut whiteout_M2ParticleEmitter,
12374            value: i32,
12375        );
12376        pub fn whiteout_m2_M2ParticleEmitter_get_position(
12377            self_: *mut whiteout_M2ParticleEmitter,
12378        ) -> *mut core::ffi::c_void;
12379        pub fn whiteout_m2_M2ParticleEmitter_set_position(
12380            self_: *mut whiteout_M2ParticleEmitter,
12381            value: *const core::ffi::c_void,
12382        );
12383        pub fn whiteout_m2_M2ParticleEmitter_get_boneId(
12384            self_: *mut whiteout_M2ParticleEmitter,
12385        ) -> u16;
12386        pub fn whiteout_m2_M2ParticleEmitter_set_boneId(
12387            self_: *mut whiteout_M2ParticleEmitter,
12388            value: u16,
12389        );
12390        pub fn whiteout_m2_M2ParticleEmitter_get_particleModelFilename(
12391            self_: *mut whiteout_M2ParticleEmitter,
12392        ) -> RawCString;
12393        pub fn whiteout_m2_M2ParticleEmitter_set_particleModelFilename(
12394            self_: *mut whiteout_M2ParticleEmitter,
12395            value: *const core::ffi::c_char,
12396        );
12397        pub fn whiteout_m2_M2ParticleEmitter_get_childEmittersModelFilename(
12398            self_: *mut whiteout_M2ParticleEmitter,
12399        ) -> RawCString;
12400        pub fn whiteout_m2_M2ParticleEmitter_set_childEmittersModelFilename(
12401            self_: *mut whiteout_M2ParticleEmitter,
12402            value: *const core::ffi::c_char,
12403        );
12404        pub fn whiteout_m2_M2ParticleEmitter_get_blendingType(
12405            self_: *mut whiteout_M2ParticleEmitter,
12406        ) -> i32;
12407        pub fn whiteout_m2_M2ParticleEmitter_set_blendingType(
12408            self_: *mut whiteout_M2ParticleEmitter,
12409            value: i32,
12410        );
12411        pub fn whiteout_m2_M2ParticleEmitter_get_emitterType(
12412            self_: *mut whiteout_M2ParticleEmitter,
12413        ) -> i32;
12414        pub fn whiteout_m2_M2ParticleEmitter_set_emitterType(
12415            self_: *mut whiteout_M2ParticleEmitter,
12416            value: i32,
12417        );
12418        pub fn whiteout_m2_M2ParticleEmitter_get_particleColorIndex(
12419            self_: *mut whiteout_M2ParticleEmitter,
12420        ) -> u16;
12421        pub fn whiteout_m2_M2ParticleEmitter_set_particleColorIndex(
12422            self_: *mut whiteout_M2ParticleEmitter,
12423            value: u16,
12424        );
12425        pub fn whiteout_m2_M2ParticleEmitter_get_textureTilerotation(
12426            self_: *mut whiteout_M2ParticleEmitter,
12427        ) -> i16;
12428        pub fn whiteout_m2_M2ParticleEmitter_set_textureTilerotation(
12429            self_: *mut whiteout_M2ParticleEmitter,
12430            value: i16,
12431        );
12432        pub fn whiteout_m2_M2ParticleEmitter_get_rows(
12433            self_: *mut whiteout_M2ParticleEmitter,
12434        ) -> u16;
12435        pub fn whiteout_m2_M2ParticleEmitter_set_rows(
12436            self_: *mut whiteout_M2ParticleEmitter,
12437            value: u16,
12438        );
12439        pub fn whiteout_m2_M2ParticleEmitter_get_columns(
12440            self_: *mut whiteout_M2ParticleEmitter,
12441        ) -> u16;
12442        pub fn whiteout_m2_M2ParticleEmitter_set_columns(
12443            self_: *mut whiteout_M2ParticleEmitter,
12444            value: u16,
12445        );
12446        pub fn whiteout_m2_M2ParticleEmitter_get_emissionSpeed(
12447            self_: *mut whiteout_M2ParticleEmitter,
12448        ) -> *mut whiteout_M2AnimationTrackF32;
12449        pub fn whiteout_m2_M2ParticleEmitter_set_emissionSpeed(
12450            self_: *mut whiteout_M2ParticleEmitter,
12451            value: *const whiteout_M2AnimationTrackF32,
12452        );
12453        pub fn whiteout_m2_M2ParticleEmitter_get_speedVariation(
12454            self_: *mut whiteout_M2ParticleEmitter,
12455        ) -> *mut whiteout_M2AnimationTrackF32;
12456        pub fn whiteout_m2_M2ParticleEmitter_set_speedVariation(
12457            self_: *mut whiteout_M2ParticleEmitter,
12458            value: *const whiteout_M2AnimationTrackF32,
12459        );
12460        pub fn whiteout_m2_M2ParticleEmitter_get_verticalRange(
12461            self_: *mut whiteout_M2ParticleEmitter,
12462        ) -> *mut whiteout_M2AnimationTrackF32;
12463        pub fn whiteout_m2_M2ParticleEmitter_set_verticalRange(
12464            self_: *mut whiteout_M2ParticleEmitter,
12465            value: *const whiteout_M2AnimationTrackF32,
12466        );
12467        pub fn whiteout_m2_M2ParticleEmitter_get_horizontalRange(
12468            self_: *mut whiteout_M2ParticleEmitter,
12469        ) -> *mut whiteout_M2AnimationTrackF32;
12470        pub fn whiteout_m2_M2ParticleEmitter_set_horizontalRange(
12471            self_: *mut whiteout_M2ParticleEmitter,
12472            value: *const whiteout_M2AnimationTrackF32,
12473        );
12474        pub fn whiteout_m2_M2ParticleEmitter_get_gravity(
12475            self_: *mut whiteout_M2ParticleEmitter,
12476        ) -> *mut whiteout_M2AnimationTrackF32;
12477        pub fn whiteout_m2_M2ParticleEmitter_set_gravity(
12478            self_: *mut whiteout_M2ParticleEmitter,
12479            value: *const whiteout_M2AnimationTrackF32,
12480        );
12481        pub fn whiteout_m2_M2ParticleEmitter_get_lifespan(
12482            self_: *mut whiteout_M2ParticleEmitter,
12483        ) -> *mut whiteout_M2AnimationTrackF32;
12484        pub fn whiteout_m2_M2ParticleEmitter_set_lifespan(
12485            self_: *mut whiteout_M2ParticleEmitter,
12486            value: *const whiteout_M2AnimationTrackF32,
12487        );
12488        pub fn whiteout_m2_M2ParticleEmitter_get_lifespanVariation(
12489            self_: *mut whiteout_M2ParticleEmitter,
12490        ) -> f32;
12491        pub fn whiteout_m2_M2ParticleEmitter_set_lifespanVariation(
12492            self_: *mut whiteout_M2ParticleEmitter,
12493            value: f32,
12494        );
12495        pub fn whiteout_m2_M2ParticleEmitter_get_emissionRate(
12496            self_: *mut whiteout_M2ParticleEmitter,
12497        ) -> *mut whiteout_M2AnimationTrackF32;
12498        pub fn whiteout_m2_M2ParticleEmitter_set_emissionRate(
12499            self_: *mut whiteout_M2ParticleEmitter,
12500            value: *const whiteout_M2AnimationTrackF32,
12501        );
12502        pub fn whiteout_m2_M2ParticleEmitter_get_emissionRateVariation(
12503            self_: *mut whiteout_M2ParticleEmitter,
12504        ) -> f32;
12505        pub fn whiteout_m2_M2ParticleEmitter_set_emissionRateVariation(
12506            self_: *mut whiteout_M2ParticleEmitter,
12507            value: f32,
12508        );
12509        pub fn whiteout_m2_M2ParticleEmitter_get_emissionAreaWidth(
12510            self_: *mut whiteout_M2ParticleEmitter,
12511        ) -> *mut whiteout_M2AnimationTrackF32;
12512        pub fn whiteout_m2_M2ParticleEmitter_set_emissionAreaWidth(
12513            self_: *mut whiteout_M2ParticleEmitter,
12514            value: *const whiteout_M2AnimationTrackF32,
12515        );
12516        pub fn whiteout_m2_M2ParticleEmitter_get_emissionAreaLength(
12517            self_: *mut whiteout_M2ParticleEmitter,
12518        ) -> *mut whiteout_M2AnimationTrackF32;
12519        pub fn whiteout_m2_M2ParticleEmitter_set_emissionAreaLength(
12520            self_: *mut whiteout_M2ParticleEmitter,
12521            value: *const whiteout_M2AnimationTrackF32,
12522        );
12523        pub fn whiteout_m2_M2ParticleEmitter_get_zSource(
12524            self_: *mut whiteout_M2ParticleEmitter,
12525        ) -> *mut whiteout_M2AnimationTrackF32;
12526        pub fn whiteout_m2_M2ParticleEmitter_set_zSource(
12527            self_: *mut whiteout_M2ParticleEmitter,
12528            value: *const whiteout_M2AnimationTrackF32,
12529        );
12530        pub fn whiteout_m2_M2ParticleEmitter_get_colorTrack(
12531            self_: *mut whiteout_M2ParticleEmitter,
12532        ) -> *mut whiteout_M2ParticleAnimationTrackVector3f;
12533        pub fn whiteout_m2_M2ParticleEmitter_set_colorTrack(
12534            self_: *mut whiteout_M2ParticleEmitter,
12535            value: *const whiteout_M2ParticleAnimationTrackVector3f,
12536        );
12537        pub fn whiteout_m2_M2ParticleEmitter_get_scaleTrack(
12538            self_: *mut whiteout_M2ParticleEmitter,
12539        ) -> *mut whiteout_M2ParticleAnimationTrackVector2f;
12540        pub fn whiteout_m2_M2ParticleEmitter_set_scaleTrack(
12541            self_: *mut whiteout_M2ParticleEmitter,
12542            value: *const whiteout_M2ParticleAnimationTrackVector2f,
12543        );
12544        pub fn whiteout_m2_M2ParticleEmitter_get_scaleVary(
12545            self_: *mut whiteout_M2ParticleEmitter,
12546        ) -> *mut core::ffi::c_void;
12547        pub fn whiteout_m2_M2ParticleEmitter_set_scaleVary(
12548            self_: *mut whiteout_M2ParticleEmitter,
12549            value: *const core::ffi::c_void,
12550        );
12551        pub fn whiteout_m2_M2ParticleEmitter_get_tailLength(
12552            self_: *mut whiteout_M2ParticleEmitter,
12553        ) -> f32;
12554        pub fn whiteout_m2_M2ParticleEmitter_set_tailLength(
12555            self_: *mut whiteout_M2ParticleEmitter,
12556            value: f32,
12557        );
12558        pub fn whiteout_m2_M2ParticleEmitter_get_twinkleSpeed(
12559            self_: *mut whiteout_M2ParticleEmitter,
12560        ) -> f32;
12561        pub fn whiteout_m2_M2ParticleEmitter_set_twinkleSpeed(
12562            self_: *mut whiteout_M2ParticleEmitter,
12563            value: f32,
12564        );
12565        pub fn whiteout_m2_M2ParticleEmitter_get_twinklePercent(
12566            self_: *mut whiteout_M2ParticleEmitter,
12567        ) -> f32;
12568        pub fn whiteout_m2_M2ParticleEmitter_set_twinklePercent(
12569            self_: *mut whiteout_M2ParticleEmitter,
12570            value: f32,
12571        );
12572        pub fn whiteout_m2_M2ParticleEmitter_get_twinkleScale(
12573            self_: *mut whiteout_M2ParticleEmitter,
12574        ) -> *mut core::ffi::c_void;
12575        pub fn whiteout_m2_M2ParticleEmitter_set_twinkleScale(
12576            self_: *mut whiteout_M2ParticleEmitter,
12577            value: *const core::ffi::c_void,
12578        );
12579        pub fn whiteout_m2_M2ParticleEmitter_get_inheritVelocityScale(
12580            self_: *mut whiteout_M2ParticleEmitter,
12581        ) -> f32;
12582        pub fn whiteout_m2_M2ParticleEmitter_set_inheritVelocityScale(
12583            self_: *mut whiteout_M2ParticleEmitter,
12584            value: f32,
12585        );
12586        pub fn whiteout_m2_M2ParticleEmitter_get_drag(
12587            self_: *mut whiteout_M2ParticleEmitter,
12588        ) -> f32;
12589        pub fn whiteout_m2_M2ParticleEmitter_set_drag(
12590            self_: *mut whiteout_M2ParticleEmitter,
12591            value: f32,
12592        );
12593        pub fn whiteout_m2_M2ParticleEmitter_get_baseSpin(
12594            self_: *mut whiteout_M2ParticleEmitter,
12595        ) -> f32;
12596        pub fn whiteout_m2_M2ParticleEmitter_set_baseSpin(
12597            self_: *mut whiteout_M2ParticleEmitter,
12598            value: f32,
12599        );
12600        pub fn whiteout_m2_M2ParticleEmitter_get_baseSpinVariation(
12601            self_: *mut whiteout_M2ParticleEmitter,
12602        ) -> f32;
12603        pub fn whiteout_m2_M2ParticleEmitter_set_baseSpinVariation(
12604            self_: *mut whiteout_M2ParticleEmitter,
12605            value: f32,
12606        );
12607        pub fn whiteout_m2_M2ParticleEmitter_get_spinSpeed(
12608            self_: *mut whiteout_M2ParticleEmitter,
12609        ) -> f32;
12610        pub fn whiteout_m2_M2ParticleEmitter_set_spinSpeed(
12611            self_: *mut whiteout_M2ParticleEmitter,
12612            value: f32,
12613        );
12614        pub fn whiteout_m2_M2ParticleEmitter_get_spinSpeedVariation(
12615            self_: *mut whiteout_M2ParticleEmitter,
12616        ) -> f32;
12617        pub fn whiteout_m2_M2ParticleEmitter_set_spinSpeedVariation(
12618            self_: *mut whiteout_M2ParticleEmitter,
12619            value: f32,
12620        );
12621        pub fn whiteout_m2_M2ParticleEmitter_get_tumble(
12622            self_: *mut whiteout_M2ParticleEmitter,
12623        ) -> *mut whiteout_M2Box;
12624        pub fn whiteout_m2_M2ParticleEmitter_set_tumble(
12625            self_: *mut whiteout_M2ParticleEmitter,
12626            value: *const whiteout_M2Box,
12627        );
12628        pub fn whiteout_m2_M2ParticleEmitter_get_windVector(
12629            self_: *mut whiteout_M2ParticleEmitter,
12630        ) -> *mut core::ffi::c_void;
12631        pub fn whiteout_m2_M2ParticleEmitter_set_windVector(
12632            self_: *mut whiteout_M2ParticleEmitter,
12633            value: *const core::ffi::c_void,
12634        );
12635        pub fn whiteout_m2_M2ParticleEmitter_get_windTime(
12636            self_: *mut whiteout_M2ParticleEmitter,
12637        ) -> f32;
12638        pub fn whiteout_m2_M2ParticleEmitter_set_windTime(
12639            self_: *mut whiteout_M2ParticleEmitter,
12640            value: f32,
12641        );
12642        pub fn whiteout_m2_M2ParticleEmitter_get_followSpeed1(
12643            self_: *mut whiteout_M2ParticleEmitter,
12644        ) -> f32;
12645        pub fn whiteout_m2_M2ParticleEmitter_set_followSpeed1(
12646            self_: *mut whiteout_M2ParticleEmitter,
12647            value: f32,
12648        );
12649        pub fn whiteout_m2_M2ParticleEmitter_get_followScale1(
12650            self_: *mut whiteout_M2ParticleEmitter,
12651        ) -> f32;
12652        pub fn whiteout_m2_M2ParticleEmitter_set_followScale1(
12653            self_: *mut whiteout_M2ParticleEmitter,
12654            value: f32,
12655        );
12656        pub fn whiteout_m2_M2ParticleEmitter_get_followSpeed2(
12657            self_: *mut whiteout_M2ParticleEmitter,
12658        ) -> f32;
12659        pub fn whiteout_m2_M2ParticleEmitter_set_followSpeed2(
12660            self_: *mut whiteout_M2ParticleEmitter,
12661            value: f32,
12662        );
12663        pub fn whiteout_m2_M2ParticleEmitter_get_followScale2(
12664            self_: *mut whiteout_M2ParticleEmitter,
12665        ) -> f32;
12666        pub fn whiteout_m2_M2ParticleEmitter_set_followScale2(
12667            self_: *mut whiteout_M2ParticleEmitter,
12668            value: f32,
12669        );
12670        pub fn whiteout_m2_M2ParticleEmitter_get_splinePoints_count(
12671            self_: *mut whiteout_M2ParticleEmitter,
12672        ) -> usize;
12673        pub fn whiteout_m2_M2ParticleEmitter_resize_splinePoints(
12674            self_: *mut whiteout_M2ParticleEmitter,
12675            count: usize,
12676        );
12677        pub fn whiteout_m2_M2ParticleEmitter_get_splinePoints_data(
12678            self_: *mut whiteout_M2ParticleEmitter,
12679        ) -> *const f32;
12680        pub fn whiteout_m2_M2ParticleEmitter_assign_splinePoints(
12681            self_: *mut whiteout_M2ParticleEmitter,
12682            data: *const f32,
12683            count: usize,
12684        );
12685        pub fn whiteout_m2_M2ParticleEmitter_get_enabledIn(
12686            self_: *mut whiteout_M2ParticleEmitter,
12687        ) -> *mut whiteout_M2AnimationTrackU8;
12688        pub fn whiteout_m2_M2ParticleEmitter_set_enabledIn(
12689            self_: *mut whiteout_M2ParticleEmitter,
12690            value: *const whiteout_M2AnimationTrackU8,
12691        );
12692        // Event
12693        pub fn whiteout_m2_M2Event_new() -> *mut whiteout_M2Event;
12694        pub fn whiteout_m2_M2Event_delete(self_: *mut whiteout_M2Event);
12695        pub fn whiteout_m2_M2Event_get_identifier(self_: *mut whiteout_M2Event) -> u32;
12696        pub fn whiteout_m2_M2Event_set_identifier(self_: *mut whiteout_M2Event, value: u32);
12697        pub fn whiteout_m2_M2Event_get_data(self_: *mut whiteout_M2Event) -> u32;
12698        pub fn whiteout_m2_M2Event_set_data(self_: *mut whiteout_M2Event, value: u32);
12699        pub fn whiteout_m2_M2Event_get_boneId(self_: *mut whiteout_M2Event) -> u32;
12700        pub fn whiteout_m2_M2Event_set_boneId(self_: *mut whiteout_M2Event, value: u32);
12701        pub fn whiteout_m2_M2Event_get_position(
12702            self_: *mut whiteout_M2Event,
12703        ) -> *mut core::ffi::c_void;
12704        pub fn whiteout_m2_M2Event_set_position(
12705            self_: *mut whiteout_M2Event,
12706            value: *const core::ffi::c_void,
12707        );
12708        pub fn whiteout_m2_M2Event_get_enabled(
12709            self_: *mut whiteout_M2Event,
12710        ) -> *mut whiteout_M2AnimationTrackBase;
12711        pub fn whiteout_m2_M2Event_set_enabled(
12712            self_: *mut whiteout_M2Event,
12713            value: *const whiteout_M2AnimationTrackBase,
12714        );
12715        // Model
12716        pub fn whiteout_m2_M2Model_new() -> *mut whiteout_M2Model;
12717        pub fn whiteout_m2_M2Model_delete(self_: *mut whiteout_M2Model);
12718        pub fn whiteout_m2_M2Model_get_modelName(self_: *mut whiteout_M2Model) -> RawCString;
12719        pub fn whiteout_m2_M2Model_set_modelName(
12720            self_: *mut whiteout_M2Model,
12721            value: *const core::ffi::c_char,
12722        );
12723        pub fn whiteout_m2_M2Model_get_globalFlags(
12724            self_: *mut whiteout_M2Model,
12725        ) -> *mut whiteout_M2GlobalFlags;
12726        pub fn whiteout_m2_M2Model_set_globalFlags(
12727            self_: *mut whiteout_M2Model,
12728            value: *const whiteout_M2GlobalFlags,
12729        );
12730        pub fn whiteout_m2_M2Model_get_globalLoops_count(self_: *mut whiteout_M2Model) -> usize;
12731        pub fn whiteout_m2_M2Model_resize_globalLoops(self_: *mut whiteout_M2Model, count: usize);
12732        pub fn whiteout_m2_M2Model_get_globalLoops_at(
12733            self_: *mut whiteout_M2Model,
12734            index: usize,
12735        ) -> *mut whiteout_M2GlobalSequence;
12736        pub fn whiteout_m2_M2Model_get_sequences_count(self_: *mut whiteout_M2Model) -> usize;
12737        pub fn whiteout_m2_M2Model_resize_sequences(self_: *mut whiteout_M2Model, count: usize);
12738        pub fn whiteout_m2_M2Model_get_sequences_at(
12739            self_: *mut whiteout_M2Model,
12740            index: usize,
12741        ) -> *mut whiteout_M2Sequence;
12742        pub fn whiteout_m2_M2Model_get_sequenceIdxHashById_count(
12743            self_: *mut whiteout_M2Model,
12744        ) -> usize;
12745        pub fn whiteout_m2_M2Model_resize_sequenceIdxHashById(
12746            self_: *mut whiteout_M2Model,
12747            count: usize,
12748        );
12749        pub fn whiteout_m2_M2Model_get_sequenceIdxHashById_data(
12750            self_: *mut whiteout_M2Model,
12751        ) -> *const u16;
12752        pub fn whiteout_m2_M2Model_assign_sequenceIdxHashById(
12753            self_: *mut whiteout_M2Model,
12754            data: *const u16,
12755            count: usize,
12756        );
12757        pub fn whiteout_m2_M2Model_get_bones_count(self_: *mut whiteout_M2Model) -> usize;
12758        pub fn whiteout_m2_M2Model_resize_bones(self_: *mut whiteout_M2Model, count: usize);
12759        pub fn whiteout_m2_M2Model_get_bones_at(
12760            self_: *mut whiteout_M2Model,
12761            index: usize,
12762        ) -> *mut whiteout_M2Bone;
12763        pub fn whiteout_m2_M2Model_get_keyBoneIds_count(self_: *mut whiteout_M2Model) -> usize;
12764        pub fn whiteout_m2_M2Model_resize_keyBoneIds(self_: *mut whiteout_M2Model, count: usize);
12765        pub fn whiteout_m2_M2Model_get_keyBoneIds_data(self_: *mut whiteout_M2Model) -> *const u16;
12766        pub fn whiteout_m2_M2Model_assign_keyBoneIds(
12767            self_: *mut whiteout_M2Model,
12768            data: *const u16,
12769            count: usize,
12770        );
12771        pub fn whiteout_m2_M2Model_get_vertices_count(self_: *mut whiteout_M2Model) -> usize;
12772        pub fn whiteout_m2_M2Model_resize_vertices(self_: *mut whiteout_M2Model, count: usize);
12773        pub fn whiteout_m2_M2Model_get_vertices_at(
12774            self_: *mut whiteout_M2Model,
12775            index: usize,
12776        ) -> *mut whiteout_M2Vertex;
12777        pub fn whiteout_m2_M2Model_get_skinProfiles_count(self_: *mut whiteout_M2Model) -> usize;
12778        pub fn whiteout_m2_M2Model_resize_skinProfiles(self_: *mut whiteout_M2Model, count: usize);
12779        pub fn whiteout_m2_M2Model_get_skinProfiles_at(
12780            self_: *mut whiteout_M2Model,
12781            index: usize,
12782        ) -> *mut whiteout_M2SkinProfile;
12783        pub fn whiteout_m2_M2Model_get_lodProfiles_count(self_: *mut whiteout_M2Model) -> usize;
12784        pub fn whiteout_m2_M2Model_resize_lodProfiles(self_: *mut whiteout_M2Model, count: usize);
12785        pub fn whiteout_m2_M2Model_get_lodProfiles_at(
12786            self_: *mut whiteout_M2Model,
12787            index: usize,
12788        ) -> *mut whiteout_M2SkinProfile;
12789        pub fn whiteout_m2_M2Model_get_numSkinProfiles(self_: *mut whiteout_M2Model) -> u32;
12790        pub fn whiteout_m2_M2Model_set_numSkinProfiles(self_: *mut whiteout_M2Model, value: u32);
12791        pub fn whiteout_m2_M2Model_get_colors_count(self_: *mut whiteout_M2Model) -> usize;
12792        pub fn whiteout_m2_M2Model_resize_colors(self_: *mut whiteout_M2Model, count: usize);
12793        pub fn whiteout_m2_M2Model_get_colors_at(
12794            self_: *mut whiteout_M2Model,
12795            index: usize,
12796        ) -> *mut whiteout_M2ColorAnimation;
12797        pub fn whiteout_m2_M2Model_get_textures_count(self_: *mut whiteout_M2Model) -> usize;
12798        pub fn whiteout_m2_M2Model_resize_textures(self_: *mut whiteout_M2Model, count: usize);
12799        pub fn whiteout_m2_M2Model_get_textures_at(
12800            self_: *mut whiteout_M2Model,
12801            index: usize,
12802        ) -> *mut whiteout_M2Texture;
12803        pub fn whiteout_m2_M2Model_get_textureWeights_count(self_: *mut whiteout_M2Model) -> usize;
12804        pub fn whiteout_m2_M2Model_resize_textureWeights(
12805            self_: *mut whiteout_M2Model,
12806            count: usize,
12807        );
12808        pub fn whiteout_m2_M2Model_get_textureWeights_at(
12809            self_: *mut whiteout_M2Model,
12810            index: usize,
12811        ) -> *mut whiteout_M2TextureWeight;
12812        pub fn whiteout_m2_M2Model_get_textureTransforms_count(
12813            self_: *mut whiteout_M2Model,
12814        ) -> usize;
12815        pub fn whiteout_m2_M2Model_resize_textureTransforms(
12816            self_: *mut whiteout_M2Model,
12817            count: usize,
12818        );
12819        pub fn whiteout_m2_M2Model_get_textureTransforms_at(
12820            self_: *mut whiteout_M2Model,
12821            index: usize,
12822        ) -> *mut whiteout_M2TextureTransform;
12823        pub fn whiteout_m2_M2Model_get_textureIndicesById_count(
12824            self_: *mut whiteout_M2Model,
12825        ) -> usize;
12826        pub fn whiteout_m2_M2Model_resize_textureIndicesById(
12827            self_: *mut whiteout_M2Model,
12828            count: usize,
12829        );
12830        pub fn whiteout_m2_M2Model_get_textureIndicesById_data(
12831            self_: *mut whiteout_M2Model,
12832        ) -> *const u16;
12833        pub fn whiteout_m2_M2Model_assign_textureIndicesById(
12834            self_: *mut whiteout_M2Model,
12835            data: *const u16,
12836            count: usize,
12837        );
12838        pub fn whiteout_m2_M2Model_get_materials_count(self_: *mut whiteout_M2Model) -> usize;
12839        pub fn whiteout_m2_M2Model_resize_materials(self_: *mut whiteout_M2Model, count: usize);
12840        pub fn whiteout_m2_M2Model_get_materials_at(
12841            self_: *mut whiteout_M2Model,
12842            index: usize,
12843        ) -> *mut whiteout_M2Material;
12844        pub fn whiteout_m2_M2Model_get_boneCombos_count(self_: *mut whiteout_M2Model) -> usize;
12845        pub fn whiteout_m2_M2Model_resize_boneCombos(self_: *mut whiteout_M2Model, count: usize);
12846        pub fn whiteout_m2_M2Model_get_boneCombos_data(self_: *mut whiteout_M2Model) -> *const u16;
12847        pub fn whiteout_m2_M2Model_assign_boneCombos(
12848            self_: *mut whiteout_M2Model,
12849            data: *const u16,
12850            count: usize,
12851        );
12852        pub fn whiteout_m2_M2Model_get_textureCombos_count(self_: *mut whiteout_M2Model) -> usize;
12853        pub fn whiteout_m2_M2Model_resize_textureCombos(self_: *mut whiteout_M2Model, count: usize);
12854        pub fn whiteout_m2_M2Model_get_textureCombos_data(
12855            self_: *mut whiteout_M2Model,
12856        ) -> *const u16;
12857        pub fn whiteout_m2_M2Model_assign_textureCombos(
12858            self_: *mut whiteout_M2Model,
12859            data: *const u16,
12860            count: usize,
12861        );
12862        pub fn whiteout_m2_M2Model_get_textureCoordCombos_count(
12863            self_: *mut whiteout_M2Model,
12864        ) -> usize;
12865        pub fn whiteout_m2_M2Model_resize_textureCoordCombos(
12866            self_: *mut whiteout_M2Model,
12867            count: usize,
12868        );
12869        pub fn whiteout_m2_M2Model_get_textureCoordCombos_data(
12870            self_: *mut whiteout_M2Model,
12871        ) -> *const u16;
12872        pub fn whiteout_m2_M2Model_assign_textureCoordCombos(
12873            self_: *mut whiteout_M2Model,
12874            data: *const u16,
12875            count: usize,
12876        );
12877        pub fn whiteout_m2_M2Model_get_textureWeightCombos_count(
12878            self_: *mut whiteout_M2Model,
12879        ) -> usize;
12880        pub fn whiteout_m2_M2Model_resize_textureWeightCombos(
12881            self_: *mut whiteout_M2Model,
12882            count: usize,
12883        );
12884        pub fn whiteout_m2_M2Model_get_textureWeightCombos_data(
12885            self_: *mut whiteout_M2Model,
12886        ) -> *const u16;
12887        pub fn whiteout_m2_M2Model_assign_textureWeightCombos(
12888            self_: *mut whiteout_M2Model,
12889            data: *const u16,
12890            count: usize,
12891        );
12892        pub fn whiteout_m2_M2Model_get_textureTransformCombos_count(
12893            self_: *mut whiteout_M2Model,
12894        ) -> usize;
12895        pub fn whiteout_m2_M2Model_resize_textureTransformCombos(
12896            self_: *mut whiteout_M2Model,
12897            count: usize,
12898        );
12899        pub fn whiteout_m2_M2Model_get_textureTransformCombos_data(
12900            self_: *mut whiteout_M2Model,
12901        ) -> *const u16;
12902        pub fn whiteout_m2_M2Model_assign_textureTransformCombos(
12903            self_: *mut whiteout_M2Model,
12904            data: *const u16,
12905            count: usize,
12906        );
12907        pub fn whiteout_m2_M2Model_get_bounding(
12908            self_: *mut whiteout_M2Model,
12909        ) -> *mut whiteout_M2Extent;
12910        pub fn whiteout_m2_M2Model_set_bounding(
12911            self_: *mut whiteout_M2Model,
12912            value: *const whiteout_M2Extent,
12913        );
12914        pub fn whiteout_m2_M2Model_get_collision(
12915            self_: *mut whiteout_M2Model,
12916        ) -> *mut whiteout_M2Extent;
12917        pub fn whiteout_m2_M2Model_set_collision(
12918            self_: *mut whiteout_M2Model,
12919            value: *const whiteout_M2Extent,
12920        );
12921        pub fn whiteout_m2_M2Model_get_collisionTriangleIndices_count(
12922            self_: *mut whiteout_M2Model,
12923        ) -> usize;
12924        pub fn whiteout_m2_M2Model_resize_collisionTriangleIndices(
12925            self_: *mut whiteout_M2Model,
12926            count: usize,
12927        );
12928        pub fn whiteout_m2_M2Model_get_collisionTriangleIndices_data(
12929            self_: *mut whiteout_M2Model,
12930        ) -> *const u16;
12931        pub fn whiteout_m2_M2Model_assign_collisionTriangleIndices(
12932            self_: *mut whiteout_M2Model,
12933            data: *const u16,
12934            count: usize,
12935        );
12936        pub fn whiteout_m2_M2Model_get_collisionVertices_count(
12937            self_: *mut whiteout_M2Model,
12938        ) -> usize;
12939        pub fn whiteout_m2_M2Model_resize_collisionVertices(
12940            self_: *mut whiteout_M2Model,
12941            count: usize,
12942        );
12943        pub fn whiteout_m2_M2Model_get_collisionVertices_data(
12944            self_: *mut whiteout_M2Model,
12945        ) -> *const f32;
12946        pub fn whiteout_m2_M2Model_assign_collisionVertices(
12947            self_: *mut whiteout_M2Model,
12948            data: *const f32,
12949            count: usize,
12950        );
12951        pub fn whiteout_m2_M2Model_get_collisionFaceNormals_count(
12952            self_: *mut whiteout_M2Model,
12953        ) -> usize;
12954        pub fn whiteout_m2_M2Model_resize_collisionFaceNormals(
12955            self_: *mut whiteout_M2Model,
12956            count: usize,
12957        );
12958        pub fn whiteout_m2_M2Model_get_collisionFaceNormals_data(
12959            self_: *mut whiteout_M2Model,
12960        ) -> *const f32;
12961        pub fn whiteout_m2_M2Model_assign_collisionFaceNormals(
12962            self_: *mut whiteout_M2Model,
12963            data: *const f32,
12964            count: usize,
12965        );
12966        pub fn whiteout_m2_M2Model_get_attachments_count(self_: *mut whiteout_M2Model) -> usize;
12967        pub fn whiteout_m2_M2Model_resize_attachments(self_: *mut whiteout_M2Model, count: usize);
12968        pub fn whiteout_m2_M2Model_get_attachments_at(
12969            self_: *mut whiteout_M2Model,
12970            index: usize,
12971        ) -> *mut whiteout_M2Attachment;
12972        pub fn whiteout_m2_M2Model_get_attachmentIndicesById_count(
12973            self_: *mut whiteout_M2Model,
12974        ) -> usize;
12975        pub fn whiteout_m2_M2Model_resize_attachmentIndicesById(
12976            self_: *mut whiteout_M2Model,
12977            count: usize,
12978        );
12979        pub fn whiteout_m2_M2Model_get_attachmentIndicesById_data(
12980            self_: *mut whiteout_M2Model,
12981        ) -> *const u16;
12982        pub fn whiteout_m2_M2Model_assign_attachmentIndicesById(
12983            self_: *mut whiteout_M2Model,
12984            data: *const u16,
12985            count: usize,
12986        );
12987        pub fn whiteout_m2_M2Model_get_events_count(self_: *mut whiteout_M2Model) -> usize;
12988        pub fn whiteout_m2_M2Model_resize_events(self_: *mut whiteout_M2Model, count: usize);
12989        pub fn whiteout_m2_M2Model_get_events_at(
12990            self_: *mut whiteout_M2Model,
12991            index: usize,
12992        ) -> *mut whiteout_M2Event;
12993        pub fn whiteout_m2_M2Model_get_lights_count(self_: *mut whiteout_M2Model) -> usize;
12994        pub fn whiteout_m2_M2Model_resize_lights(self_: *mut whiteout_M2Model, count: usize);
12995        pub fn whiteout_m2_M2Model_get_lights_at(
12996            self_: *mut whiteout_M2Model,
12997            index: usize,
12998        ) -> *mut whiteout_M2Light;
12999        pub fn whiteout_m2_M2Model_get_cameras_count(self_: *mut whiteout_M2Model) -> usize;
13000        pub fn whiteout_m2_M2Model_resize_cameras(self_: *mut whiteout_M2Model, count: usize);
13001        pub fn whiteout_m2_M2Model_get_cameras_at(
13002            self_: *mut whiteout_M2Model,
13003            index: usize,
13004        ) -> *mut whiteout_M2Camera;
13005        pub fn whiteout_m2_M2Model_get_cameraIndicesById_count(
13006            self_: *mut whiteout_M2Model,
13007        ) -> usize;
13008        pub fn whiteout_m2_M2Model_resize_cameraIndicesById(
13009            self_: *mut whiteout_M2Model,
13010            count: usize,
13011        );
13012        pub fn whiteout_m2_M2Model_get_cameraIndicesById_data(
13013            self_: *mut whiteout_M2Model,
13014        ) -> *const u16;
13015        pub fn whiteout_m2_M2Model_assign_cameraIndicesById(
13016            self_: *mut whiteout_M2Model,
13017            data: *const u16,
13018            count: usize,
13019        );
13020        pub fn whiteout_m2_M2Model_get_ribbonEmitters_count(self_: *mut whiteout_M2Model) -> usize;
13021        pub fn whiteout_m2_M2Model_resize_ribbonEmitters(
13022            self_: *mut whiteout_M2Model,
13023            count: usize,
13024        );
13025        pub fn whiteout_m2_M2Model_get_ribbonEmitters_at(
13026            self_: *mut whiteout_M2Model,
13027            index: usize,
13028        ) -> *mut whiteout_M2RibbonEmitter;
13029        pub fn whiteout_m2_M2Model_get_particleEmitters_count(
13030            self_: *mut whiteout_M2Model,
13031        ) -> usize;
13032        pub fn whiteout_m2_M2Model_resize_particleEmitters(
13033            self_: *mut whiteout_M2Model,
13034            count: usize,
13035        );
13036        pub fn whiteout_m2_M2Model_get_particleEmitters_at(
13037            self_: *mut whiteout_M2Model,
13038            index: usize,
13039        ) -> *mut whiteout_M2ParticleEmitter;
13040        pub fn whiteout_m2_M2Model_get_textureCombinerCombos_count(
13041            self_: *mut whiteout_M2Model,
13042        ) -> usize;
13043        pub fn whiteout_m2_M2Model_resize_textureCombinerCombos(
13044            self_: *mut whiteout_M2Model,
13045            count: usize,
13046        );
13047        pub fn whiteout_m2_M2Model_get_textureCombinerCombos_data(
13048            self_: *mut whiteout_M2Model,
13049        ) -> *const u16;
13050        pub fn whiteout_m2_M2Model_assign_textureCombinerCombos(
13051            self_: *mut whiteout_M2Model,
13052            data: *const u16,
13053            count: usize,
13054        );
13055        pub fn whiteout_m2_M2Model_get_texture_ids_count(self_: *mut whiteout_M2Model) -> usize;
13056        pub fn whiteout_m2_M2Model_resize_texture_ids(self_: *mut whiteout_M2Model, count: usize);
13057        pub fn whiteout_m2_M2Model_get_texture_ids_data(self_: *mut whiteout_M2Model)
13058            -> *const u32;
13059        pub fn whiteout_m2_M2Model_assign_texture_ids(
13060            self_: *mut whiteout_M2Model,
13061            data: *const u32,
13062            count: usize,
13063        );
13064        pub fn whiteout_m2_M2Model_get_parentSequenceReplacements_count(
13065            self_: *mut whiteout_M2Model,
13066        ) -> usize;
13067        pub fn whiteout_m2_M2Model_resize_parentSequenceReplacements(
13068            self_: *mut whiteout_M2Model,
13069            count: usize,
13070        );
13071        pub fn whiteout_m2_M2Model_get_parentSequenceReplacements_data(
13072            self_: *mut whiteout_M2Model,
13073        ) -> *const u16;
13074        pub fn whiteout_m2_M2Model_assign_parentSequenceReplacements(
13075            self_: *mut whiteout_M2Model,
13076            data: *const u16,
13077            count: usize,
13078        );
13079        pub fn whiteout_m2_M2Model_get_parentTextureWeights_count(
13080            self_: *mut whiteout_M2Model,
13081        ) -> usize;
13082        pub fn whiteout_m2_M2Model_resize_parentTextureWeights(
13083            self_: *mut whiteout_M2Model,
13084            count: usize,
13085        );
13086        pub fn whiteout_m2_M2Model_get_parentTextureWeights_at(
13087            self_: *mut whiteout_M2Model,
13088            index: usize,
13089        ) -> *mut whiteout_M2TextureWeight;
13090        pub fn whiteout_m2_M2Model_get_parentSequenceBounds_count(
13091            self_: *mut whiteout_M2Model,
13092        ) -> usize;
13093        pub fn whiteout_m2_M2Model_resize_parentSequenceBounds(
13094            self_: *mut whiteout_M2Model,
13095            count: usize,
13096        );
13097        pub fn whiteout_m2_M2Model_get_parentSequenceBounds_at(
13098            self_: *mut whiteout_M2Model,
13099            index: usize,
13100        ) -> *mut whiteout_M2Extent;
13101        pub fn whiteout_m2_M2Model_get_parentEventData_count(self_: *mut whiteout_M2Model)
13102            -> usize;
13103        pub fn whiteout_m2_M2Model_resize_parentEventData(
13104            self_: *mut whiteout_M2Model,
13105            count: usize,
13106        );
13107        pub fn whiteout_m2_M2Model_get_parentEventData_at(
13108            self_: *mut whiteout_M2Model,
13109            index: usize,
13110        ) -> *mut whiteout_M2AnimationTrackBase;
13111        pub fn whiteout_m2_M2Model_get_recursiveParticleModelIds_count(
13112            self_: *mut whiteout_M2Model,
13113        ) -> usize;
13114        pub fn whiteout_m2_M2Model_resize_recursiveParticleModelIds(
13115            self_: *mut whiteout_M2Model,
13116            count: usize,
13117        );
13118        pub fn whiteout_m2_M2Model_get_recursiveParticleModelIds_data(
13119            self_: *mut whiteout_M2Model,
13120        ) -> *const u32;
13121        pub fn whiteout_m2_M2Model_assign_recursiveParticleModelIds(
13122            self_: *mut whiteout_M2Model,
13123            data: *const u32,
13124            count: usize,
13125        );
13126        pub fn whiteout_m2_M2Model_get_geometryParticleModelIds_count(
13127            self_: *mut whiteout_M2Model,
13128        ) -> usize;
13129        pub fn whiteout_m2_M2Model_resize_geometryParticleModelIds(
13130            self_: *mut whiteout_M2Model,
13131            count: usize,
13132        );
13133        pub fn whiteout_m2_M2Model_get_geometryParticleModelIds_data(
13134            self_: *mut whiteout_M2Model,
13135        ) -> *const u32;
13136        pub fn whiteout_m2_M2Model_assign_geometryParticleModelIds(
13137            self_: *mut whiteout_M2Model,
13138            data: *const u32,
13139            count: usize,
13140        );
13141        pub fn whiteout_m2_M2Model_get_particleGeosets_count(self_: *mut whiteout_M2Model)
13142            -> usize;
13143        pub fn whiteout_m2_M2Model_resize_particleGeosets(
13144            self_: *mut whiteout_M2Model,
13145            count: usize,
13146        );
13147        pub fn whiteout_m2_M2Model_get_particleGeosets_at(
13148            self_: *mut whiteout_M2Model,
13149            index: usize,
13150        ) -> *mut whiteout_M2ParticleGeosetData;
13151        pub fn whiteout_m2_M2Model_get_physicsFileData_count(self_: *mut whiteout_M2Model)
13152            -> usize;
13153        pub fn whiteout_m2_M2Model_resize_physicsFileData(
13154            self_: *mut whiteout_M2Model,
13155            count: usize,
13156        );
13157        pub fn whiteout_m2_M2Model_get_physicsFileData_data(
13158            self_: *mut whiteout_M2Model,
13159        ) -> *const u8;
13160        pub fn whiteout_m2_M2Model_assign_physicsFileData(
13161            self_: *mut whiteout_M2Model,
13162            data: *const u8,
13163            count: usize,
13164        );
13165        pub fn whiteout_m2_M2Model_get_edgeFadeEntries_count(self_: *mut whiteout_M2Model)
13166            -> usize;
13167        pub fn whiteout_m2_M2Model_resize_edgeFadeEntries(
13168            self_: *mut whiteout_M2Model,
13169            count: usize,
13170        );
13171        pub fn whiteout_m2_M2Model_get_edgeFadeEntries_at(
13172            self_: *mut whiteout_M2Model,
13173            index: usize,
13174        ) -> *mut whiteout_M2EdgeFadeData;
13175        pub fn whiteout_m2_M2Model_get_nerfEntries_count(self_: *mut whiteout_M2Model) -> usize;
13176        pub fn whiteout_m2_M2Model_resize_nerfEntries(self_: *mut whiteout_M2Model, count: usize);
13177        pub fn whiteout_m2_M2Model_get_nerfEntries_at(
13178            self_: *mut whiteout_M2Model,
13179            index: usize,
13180        ) -> *mut whiteout_M2DistanceFadeData;
13181        pub fn whiteout_m2_M2Model_get_detailedLightEntries_count(
13182            self_: *mut whiteout_M2Model,
13183        ) -> usize;
13184        pub fn whiteout_m2_M2Model_resize_detailedLightEntries(
13185            self_: *mut whiteout_M2Model,
13186            count: usize,
13187        );
13188        pub fn whiteout_m2_M2Model_get_detailedLightEntries_at(
13189            self_: *mut whiteout_M2Model,
13190            index: usize,
13191        ) -> *mut whiteout_M2DetailedLightData;
13192        pub fn whiteout_m2_M2Model_get_debugOcclusionEntries_count(
13193            self_: *mut whiteout_M2Model,
13194        ) -> usize;
13195        pub fn whiteout_m2_M2Model_resize_debugOcclusionEntries(
13196            self_: *mut whiteout_M2Model,
13197            count: usize,
13198        );
13199        pub fn whiteout_m2_M2Model_get_debugOcclusionEntries_at(
13200            self_: *mut whiteout_M2Model,
13201            index: usize,
13202        ) -> *mut whiteout_M2DebugOcclusionData;
13203        pub fn whiteout_m2_M2Model_get_animFrameData_count(self_: *mut whiteout_M2Model) -> usize;
13204        pub fn whiteout_m2_M2Model_resize_animFrameData(self_: *mut whiteout_M2Model, count: usize);
13205        pub fn whiteout_m2_M2Model_get_animFrameData_data(
13206            self_: *mut whiteout_M2Model,
13207        ) -> *const u8;
13208        pub fn whiteout_m2_M2Model_assign_animFrameData(
13209            self_: *mut whiteout_M2Model,
13210            data: *const u8,
13211            count: usize,
13212        );
13213        pub fn whiteout_m2_M2Model_get_texturedLightEntries_count(
13214            self_: *mut whiteout_M2Model,
13215        ) -> usize;
13216        pub fn whiteout_m2_M2Model_resize_texturedLightEntries(
13217            self_: *mut whiteout_M2Model,
13218            count: usize,
13219        );
13220        pub fn whiteout_m2_M2Model_get_texturedLightEntries_at(
13221            self_: *mut whiteout_M2Model,
13222            index: usize,
13223        ) -> *mut whiteout_M2TexturedLightData;
13224        // Parser
13225        pub fn whiteout_m2_M2Parser_new() -> *mut whiteout_M2Parser;
13226        pub fn whiteout_m2_M2Parser_delete(self_: *mut whiteout_M2Parser);
13227        pub fn whiteout_m2_M2Parser_parse(
13228            self_: *mut whiteout_M2Parser,
13229            fs: *mut core::ffi::c_void,
13230            file_path: *const core::ffi::c_char,
13231        ) -> *mut whiteout_M2Model;
13232        pub fn whiteout_m2_M2Parser_parse_cascFs_buffer(
13233            self_: *mut whiteout_M2Parser,
13234            casc_fs: *const u8,
13235            casc_fs_size: usize,
13236            buffer: *const u8,
13237            buffer_size: usize,
13238        ) -> *mut whiteout_M2Model;
13239        pub fn whiteout_m2_M2Parser_hasIssues(self_: *mut whiteout_M2Parser) -> i32;
13240        pub fn whiteout_m2_M2Parser_getIssues_count(self_: *mut whiteout_M2Parser) -> usize;
13241        pub fn whiteout_m2_M2Parser_getIssues_at(
13242            self_: *mut whiteout_M2Parser,
13243            index: usize,
13244        ) -> RawCString;
13245        // WriteOptions
13246        pub fn whiteout_m2_M2WriteOptions_new() -> *mut whiteout_M2WriteOptions;
13247        pub fn whiteout_m2_M2WriteOptions_delete(self_: *mut whiteout_M2WriteOptions);
13248        pub fn whiteout_m2_M2WriteOptions_get_m2Version(self_: *mut whiteout_M2WriteOptions)
13249            -> u32;
13250        pub fn whiteout_m2_M2WriteOptions_set_m2Version(
13251            self_: *mut whiteout_M2WriteOptions,
13252            value: u32,
13253        );
13254        pub fn whiteout_m2_M2WriteOptions_get_emitSkeleton(
13255            self_: *mut whiteout_M2WriteOptions,
13256        ) -> i32;
13257        pub fn whiteout_m2_M2WriteOptions_set_emitSkeleton(
13258            self_: *mut whiteout_M2WriteOptions,
13259            value: i32,
13260        );
13261        pub fn whiteout_m2_M2WriteOptions_get_baseStem(
13262            self_: *mut whiteout_M2WriteOptions,
13263        ) -> RawCString;
13264        pub fn whiteout_m2_M2WriteOptions_set_baseStem(
13265            self_: *mut whiteout_M2WriteOptions,
13266            value: *const core::ffi::c_char,
13267        );
13268        // SerializeResult
13269        pub fn whiteout_m2_M2SerializeResult_new() -> *mut whiteout_M2SerializeResult;
13270        pub fn whiteout_m2_M2SerializeResult_delete(self_: *mut whiteout_M2SerializeResult);
13271        pub fn whiteout_m2_M2SerializeResult_get_m2Data_count(
13272            self_: *mut whiteout_M2SerializeResult,
13273        ) -> usize;
13274        pub fn whiteout_m2_M2SerializeResult_resize_m2Data(
13275            self_: *mut whiteout_M2SerializeResult,
13276            count: usize,
13277        );
13278        pub fn whiteout_m2_M2SerializeResult_get_m2Data_data(
13279            self_: *mut whiteout_M2SerializeResult,
13280        ) -> *const u8;
13281        pub fn whiteout_m2_M2SerializeResult_assign_m2Data(
13282            self_: *mut whiteout_M2SerializeResult,
13283            data: *const u8,
13284            count: usize,
13285        );
13286        // Writer
13287        pub fn whiteout_m2_M2Writer_new() -> *mut whiteout_M2Writer;
13288        pub fn whiteout_m2_M2Writer_new_options(
13289            _0: *mut core::ffi::c_void,
13290        ) -> *mut whiteout_M2Writer;
13291        pub fn whiteout_m2_M2Writer_delete(self_: *mut whiteout_M2Writer);
13292        pub fn whiteout_m2_M2Writer_write(
13293            self_: *mut whiteout_M2Writer,
13294            fs: *mut core::ffi::c_void,
13295            file_path: *const core::ffi::c_char,
13296            model: *mut whiteout_M2Model,
13297        );
13298        pub fn whiteout_m2_M2Writer_write_cascFs_model(
13299            self_: *mut whiteout_M2Writer,
13300            casc_fs: *mut core::ffi::c_void,
13301            model: *mut whiteout_M2Model,
13302        );
13303        pub fn whiteout_m2_M2Writer_write_model(
13304            self_: *mut whiteout_M2Writer,
13305            model: *mut whiteout_M2Model,
13306        ) -> *mut whiteout_M2SerializeResult;
13307        pub fn whiteout_m2_M2Writer_hasIssues(self_: *mut whiteout_M2Writer) -> i32;
13308        pub fn whiteout_m2_M2Writer_getIssues_count(self_: *mut whiteout_M2Writer) -> usize;
13309        pub fn whiteout_m2_M2Writer_getIssues_at(
13310            self_: *mut whiteout_M2Writer,
13311            index: usize,
13312        ) -> RawCString;
13313        // AnimationTrackVector3f
13314        pub fn whiteout_m2_M2AnimationTrackVector3f_new() -> *mut whiteout_M2AnimationTrackVector3f;
13315        pub fn whiteout_m2_M2AnimationTrackVector3f_delete(
13316            self_: *mut whiteout_M2AnimationTrackVector3f,
13317        );
13318        pub fn whiteout_m2_M2AnimationTrackVector3f_get_interpolationType(
13319            self_: *mut whiteout_M2AnimationTrackVector3f,
13320        ) -> i32;
13321        pub fn whiteout_m2_M2AnimationTrackVector3f_set_interpolationType(
13322            self_: *mut whiteout_M2AnimationTrackVector3f,
13323            value: i32,
13324        );
13325        pub fn whiteout_m2_M2AnimationTrackVector3f_get_globalSequenceId(
13326            self_: *mut whiteout_M2AnimationTrackVector3f,
13327        ) -> u16;
13328        pub fn whiteout_m2_M2AnimationTrackVector3f_set_globalSequenceId(
13329            self_: *mut whiteout_M2AnimationTrackVector3f,
13330            value: u16,
13331        );
13332        pub fn whiteout_m2_M2AnimationTrackVector3f_get_timestamps_count(
13333            self_: *mut whiteout_M2AnimationTrackVector3f,
13334        ) -> usize;
13335        pub fn whiteout_m2_M2AnimationTrackVector3f_get_timestamps_inner_count(
13336            self_: *mut whiteout_M2AnimationTrackVector3f,
13337            outer: usize,
13338        ) -> usize;
13339        pub fn whiteout_m2_M2AnimationTrackVector3f_resize_timestamps(
13340            self_: *mut whiteout_M2AnimationTrackVector3f,
13341            count: usize,
13342        );
13343        pub fn whiteout_m2_M2AnimationTrackVector3f_resize_timestamps_inner(
13344            self_: *mut whiteout_M2AnimationTrackVector3f,
13345            outer: usize,
13346            count: usize,
13347        );
13348        pub fn whiteout_m2_M2AnimationTrackVector3f_get_timestamps_inner_data(
13349            self_: *mut whiteout_M2AnimationTrackVector3f,
13350            outer: usize,
13351        ) -> *const u32;
13352        pub fn whiteout_m2_M2AnimationTrackVector3f_assign_timestamps_inner(
13353            self_: *mut whiteout_M2AnimationTrackVector3f,
13354            outer: usize,
13355            data: *const u32,
13356            count: usize,
13357        );
13358        pub fn whiteout_m2_M2AnimationTrackVector3f_get_values_count(
13359            self_: *mut whiteout_M2AnimationTrackVector3f,
13360        ) -> usize;
13361        pub fn whiteout_m2_M2AnimationTrackVector3f_get_values_inner_count(
13362            self_: *mut whiteout_M2AnimationTrackVector3f,
13363            outer: usize,
13364        ) -> usize;
13365        pub fn whiteout_m2_M2AnimationTrackVector3f_resize_values(
13366            self_: *mut whiteout_M2AnimationTrackVector3f,
13367            count: usize,
13368        );
13369        pub fn whiteout_m2_M2AnimationTrackVector3f_resize_values_inner(
13370            self_: *mut whiteout_M2AnimationTrackVector3f,
13371            outer: usize,
13372            count: usize,
13373        );
13374        pub fn whiteout_m2_M2AnimationTrackVector3f_get_values_inner_data(
13375            self_: *mut whiteout_M2AnimationTrackVector3f,
13376            outer: usize,
13377        ) -> *const f32;
13378        pub fn whiteout_m2_M2AnimationTrackVector3f_assign_values_inner(
13379            self_: *mut whiteout_M2AnimationTrackVector3f,
13380            outer: usize,
13381            data: *const f32,
13382            count: usize,
13383        );
13384        // AnimationTrackM2CompatQuaternion
13385        pub fn whiteout_m2_M2AnimationTrackM2CompatQuaternion_new(
13386        ) -> *mut whiteout_M2AnimationTrackM2CompatQuaternion;
13387        pub fn whiteout_m2_M2AnimationTrackM2CompatQuaternion_delete(
13388            self_: *mut whiteout_M2AnimationTrackM2CompatQuaternion,
13389        );
13390        pub fn whiteout_m2_M2AnimationTrackM2CompatQuaternion_get_interpolationType(
13391            self_: *mut whiteout_M2AnimationTrackM2CompatQuaternion,
13392        ) -> i32;
13393        pub fn whiteout_m2_M2AnimationTrackM2CompatQuaternion_set_interpolationType(
13394            self_: *mut whiteout_M2AnimationTrackM2CompatQuaternion,
13395            value: i32,
13396        );
13397        pub fn whiteout_m2_M2AnimationTrackM2CompatQuaternion_get_globalSequenceId(
13398            self_: *mut whiteout_M2AnimationTrackM2CompatQuaternion,
13399        ) -> u16;
13400        pub fn whiteout_m2_M2AnimationTrackM2CompatQuaternion_set_globalSequenceId(
13401            self_: *mut whiteout_M2AnimationTrackM2CompatQuaternion,
13402            value: u16,
13403        );
13404        pub fn whiteout_m2_M2AnimationTrackM2CompatQuaternion_get_timestamps_count(
13405            self_: *mut whiteout_M2AnimationTrackM2CompatQuaternion,
13406        ) -> usize;
13407        pub fn whiteout_m2_M2AnimationTrackM2CompatQuaternion_get_timestamps_inner_count(
13408            self_: *mut whiteout_M2AnimationTrackM2CompatQuaternion,
13409            outer: usize,
13410        ) -> usize;
13411        pub fn whiteout_m2_M2AnimationTrackM2CompatQuaternion_resize_timestamps(
13412            self_: *mut whiteout_M2AnimationTrackM2CompatQuaternion,
13413            count: usize,
13414        );
13415        pub fn whiteout_m2_M2AnimationTrackM2CompatQuaternion_resize_timestamps_inner(
13416            self_: *mut whiteout_M2AnimationTrackM2CompatQuaternion,
13417            outer: usize,
13418            count: usize,
13419        );
13420        pub fn whiteout_m2_M2AnimationTrackM2CompatQuaternion_get_timestamps_inner_data(
13421            self_: *mut whiteout_M2AnimationTrackM2CompatQuaternion,
13422            outer: usize,
13423        ) -> *const u32;
13424        pub fn whiteout_m2_M2AnimationTrackM2CompatQuaternion_assign_timestamps_inner(
13425            self_: *mut whiteout_M2AnimationTrackM2CompatQuaternion,
13426            outer: usize,
13427            data: *const u32,
13428            count: usize,
13429        );
13430        pub fn whiteout_m2_M2AnimationTrackM2CompatQuaternion_get_values_count(
13431            self_: *mut whiteout_M2AnimationTrackM2CompatQuaternion,
13432        ) -> usize;
13433        pub fn whiteout_m2_M2AnimationTrackM2CompatQuaternion_get_values_inner_count(
13434            self_: *mut whiteout_M2AnimationTrackM2CompatQuaternion,
13435            outer: usize,
13436        ) -> usize;
13437        pub fn whiteout_m2_M2AnimationTrackM2CompatQuaternion_resize_values(
13438            self_: *mut whiteout_M2AnimationTrackM2CompatQuaternion,
13439            count: usize,
13440        );
13441        pub fn whiteout_m2_M2AnimationTrackM2CompatQuaternion_resize_values_inner(
13442            self_: *mut whiteout_M2AnimationTrackM2CompatQuaternion,
13443            outer: usize,
13444            count: usize,
13445        );
13446        pub fn whiteout_m2_M2AnimationTrackM2CompatQuaternion_get_values_at(
13447            self_: *mut whiteout_M2AnimationTrackM2CompatQuaternion,
13448            outer: usize,
13449            inner: usize,
13450        ) -> *mut whiteout_M2CompatQuaternion;
13451        // AnimationTrackI16
13452        pub fn whiteout_m2_M2AnimationTrackI16_new() -> *mut whiteout_M2AnimationTrackI16;
13453        pub fn whiteout_m2_M2AnimationTrackI16_delete(self_: *mut whiteout_M2AnimationTrackI16);
13454        pub fn whiteout_m2_M2AnimationTrackI16_get_interpolationType(
13455            self_: *mut whiteout_M2AnimationTrackI16,
13456        ) -> i32;
13457        pub fn whiteout_m2_M2AnimationTrackI16_set_interpolationType(
13458            self_: *mut whiteout_M2AnimationTrackI16,
13459            value: i32,
13460        );
13461        pub fn whiteout_m2_M2AnimationTrackI16_get_globalSequenceId(
13462            self_: *mut whiteout_M2AnimationTrackI16,
13463        ) -> u16;
13464        pub fn whiteout_m2_M2AnimationTrackI16_set_globalSequenceId(
13465            self_: *mut whiteout_M2AnimationTrackI16,
13466            value: u16,
13467        );
13468        pub fn whiteout_m2_M2AnimationTrackI16_get_timestamps_count(
13469            self_: *mut whiteout_M2AnimationTrackI16,
13470        ) -> usize;
13471        pub fn whiteout_m2_M2AnimationTrackI16_get_timestamps_inner_count(
13472            self_: *mut whiteout_M2AnimationTrackI16,
13473            outer: usize,
13474        ) -> usize;
13475        pub fn whiteout_m2_M2AnimationTrackI16_resize_timestamps(
13476            self_: *mut whiteout_M2AnimationTrackI16,
13477            count: usize,
13478        );
13479        pub fn whiteout_m2_M2AnimationTrackI16_resize_timestamps_inner(
13480            self_: *mut whiteout_M2AnimationTrackI16,
13481            outer: usize,
13482            count: usize,
13483        );
13484        pub fn whiteout_m2_M2AnimationTrackI16_get_timestamps_inner_data(
13485            self_: *mut whiteout_M2AnimationTrackI16,
13486            outer: usize,
13487        ) -> *const u32;
13488        pub fn whiteout_m2_M2AnimationTrackI16_assign_timestamps_inner(
13489            self_: *mut whiteout_M2AnimationTrackI16,
13490            outer: usize,
13491            data: *const u32,
13492            count: usize,
13493        );
13494        pub fn whiteout_m2_M2AnimationTrackI16_get_values_count(
13495            self_: *mut whiteout_M2AnimationTrackI16,
13496        ) -> usize;
13497        pub fn whiteout_m2_M2AnimationTrackI16_get_values_inner_count(
13498            self_: *mut whiteout_M2AnimationTrackI16,
13499            outer: usize,
13500        ) -> usize;
13501        pub fn whiteout_m2_M2AnimationTrackI16_resize_values(
13502            self_: *mut whiteout_M2AnimationTrackI16,
13503            count: usize,
13504        );
13505        pub fn whiteout_m2_M2AnimationTrackI16_resize_values_inner(
13506            self_: *mut whiteout_M2AnimationTrackI16,
13507            outer: usize,
13508            count: usize,
13509        );
13510        pub fn whiteout_m2_M2AnimationTrackI16_get_values_inner_data(
13511            self_: *mut whiteout_M2AnimationTrackI16,
13512            outer: usize,
13513        ) -> *const i16;
13514        pub fn whiteout_m2_M2AnimationTrackI16_assign_values_inner(
13515            self_: *mut whiteout_M2AnimationTrackI16,
13516            outer: usize,
13517            data: *const i16,
13518            count: usize,
13519        );
13520        // AnimationTrackF32
13521        pub fn whiteout_m2_M2AnimationTrackF32_new() -> *mut whiteout_M2AnimationTrackF32;
13522        pub fn whiteout_m2_M2AnimationTrackF32_delete(self_: *mut whiteout_M2AnimationTrackF32);
13523        pub fn whiteout_m2_M2AnimationTrackF32_get_interpolationType(
13524            self_: *mut whiteout_M2AnimationTrackF32,
13525        ) -> i32;
13526        pub fn whiteout_m2_M2AnimationTrackF32_set_interpolationType(
13527            self_: *mut whiteout_M2AnimationTrackF32,
13528            value: i32,
13529        );
13530        pub fn whiteout_m2_M2AnimationTrackF32_get_globalSequenceId(
13531            self_: *mut whiteout_M2AnimationTrackF32,
13532        ) -> u16;
13533        pub fn whiteout_m2_M2AnimationTrackF32_set_globalSequenceId(
13534            self_: *mut whiteout_M2AnimationTrackF32,
13535            value: u16,
13536        );
13537        pub fn whiteout_m2_M2AnimationTrackF32_get_timestamps_count(
13538            self_: *mut whiteout_M2AnimationTrackF32,
13539        ) -> usize;
13540        pub fn whiteout_m2_M2AnimationTrackF32_get_timestamps_inner_count(
13541            self_: *mut whiteout_M2AnimationTrackF32,
13542            outer: usize,
13543        ) -> usize;
13544        pub fn whiteout_m2_M2AnimationTrackF32_resize_timestamps(
13545            self_: *mut whiteout_M2AnimationTrackF32,
13546            count: usize,
13547        );
13548        pub fn whiteout_m2_M2AnimationTrackF32_resize_timestamps_inner(
13549            self_: *mut whiteout_M2AnimationTrackF32,
13550            outer: usize,
13551            count: usize,
13552        );
13553        pub fn whiteout_m2_M2AnimationTrackF32_get_timestamps_inner_data(
13554            self_: *mut whiteout_M2AnimationTrackF32,
13555            outer: usize,
13556        ) -> *const u32;
13557        pub fn whiteout_m2_M2AnimationTrackF32_assign_timestamps_inner(
13558            self_: *mut whiteout_M2AnimationTrackF32,
13559            outer: usize,
13560            data: *const u32,
13561            count: usize,
13562        );
13563        pub fn whiteout_m2_M2AnimationTrackF32_get_values_count(
13564            self_: *mut whiteout_M2AnimationTrackF32,
13565        ) -> usize;
13566        pub fn whiteout_m2_M2AnimationTrackF32_get_values_inner_count(
13567            self_: *mut whiteout_M2AnimationTrackF32,
13568            outer: usize,
13569        ) -> usize;
13570        pub fn whiteout_m2_M2AnimationTrackF32_resize_values(
13571            self_: *mut whiteout_M2AnimationTrackF32,
13572            count: usize,
13573        );
13574        pub fn whiteout_m2_M2AnimationTrackF32_resize_values_inner(
13575            self_: *mut whiteout_M2AnimationTrackF32,
13576            outer: usize,
13577            count: usize,
13578        );
13579        pub fn whiteout_m2_M2AnimationTrackF32_get_values_inner_data(
13580            self_: *mut whiteout_M2AnimationTrackF32,
13581            outer: usize,
13582        ) -> *const f32;
13583        pub fn whiteout_m2_M2AnimationTrackF32_assign_values_inner(
13584            self_: *mut whiteout_M2AnimationTrackF32,
13585            outer: usize,
13586            data: *const f32,
13587            count: usize,
13588        );
13589        // AnimationTrackU8
13590        pub fn whiteout_m2_M2AnimationTrackU8_new() -> *mut whiteout_M2AnimationTrackU8;
13591        pub fn whiteout_m2_M2AnimationTrackU8_delete(self_: *mut whiteout_M2AnimationTrackU8);
13592        pub fn whiteout_m2_M2AnimationTrackU8_get_interpolationType(
13593            self_: *mut whiteout_M2AnimationTrackU8,
13594        ) -> i32;
13595        pub fn whiteout_m2_M2AnimationTrackU8_set_interpolationType(
13596            self_: *mut whiteout_M2AnimationTrackU8,
13597            value: i32,
13598        );
13599        pub fn whiteout_m2_M2AnimationTrackU8_get_globalSequenceId(
13600            self_: *mut whiteout_M2AnimationTrackU8,
13601        ) -> u16;
13602        pub fn whiteout_m2_M2AnimationTrackU8_set_globalSequenceId(
13603            self_: *mut whiteout_M2AnimationTrackU8,
13604            value: u16,
13605        );
13606        pub fn whiteout_m2_M2AnimationTrackU8_get_timestamps_count(
13607            self_: *mut whiteout_M2AnimationTrackU8,
13608        ) -> usize;
13609        pub fn whiteout_m2_M2AnimationTrackU8_get_timestamps_inner_count(
13610            self_: *mut whiteout_M2AnimationTrackU8,
13611            outer: usize,
13612        ) -> usize;
13613        pub fn whiteout_m2_M2AnimationTrackU8_resize_timestamps(
13614            self_: *mut whiteout_M2AnimationTrackU8,
13615            count: usize,
13616        );
13617        pub fn whiteout_m2_M2AnimationTrackU8_resize_timestamps_inner(
13618            self_: *mut whiteout_M2AnimationTrackU8,
13619            outer: usize,
13620            count: usize,
13621        );
13622        pub fn whiteout_m2_M2AnimationTrackU8_get_timestamps_inner_data(
13623            self_: *mut whiteout_M2AnimationTrackU8,
13624            outer: usize,
13625        ) -> *const u32;
13626        pub fn whiteout_m2_M2AnimationTrackU8_assign_timestamps_inner(
13627            self_: *mut whiteout_M2AnimationTrackU8,
13628            outer: usize,
13629            data: *const u32,
13630            count: usize,
13631        );
13632        pub fn whiteout_m2_M2AnimationTrackU8_get_values_count(
13633            self_: *mut whiteout_M2AnimationTrackU8,
13634        ) -> usize;
13635        pub fn whiteout_m2_M2AnimationTrackU8_get_values_inner_count(
13636            self_: *mut whiteout_M2AnimationTrackU8,
13637            outer: usize,
13638        ) -> usize;
13639        pub fn whiteout_m2_M2AnimationTrackU8_resize_values(
13640            self_: *mut whiteout_M2AnimationTrackU8,
13641            count: usize,
13642        );
13643        pub fn whiteout_m2_M2AnimationTrackU8_resize_values_inner(
13644            self_: *mut whiteout_M2AnimationTrackU8,
13645            outer: usize,
13646            count: usize,
13647        );
13648        pub fn whiteout_m2_M2AnimationTrackU8_get_values_inner_data(
13649            self_: *mut whiteout_M2AnimationTrackU8,
13650            outer: usize,
13651        ) -> *const u8;
13652        pub fn whiteout_m2_M2AnimationTrackU8_assign_values_inner(
13653            self_: *mut whiteout_M2AnimationTrackU8,
13654            outer: usize,
13655            data: *const u8,
13656            count: usize,
13657        );
13658        // AnimationTrackM2CameraSpline
13659        pub fn whiteout_m2_M2AnimationTrackM2CameraSpline_new(
13660        ) -> *mut whiteout_M2AnimationTrackM2CameraSpline;
13661        pub fn whiteout_m2_M2AnimationTrackM2CameraSpline_delete(
13662            self_: *mut whiteout_M2AnimationTrackM2CameraSpline,
13663        );
13664        pub fn whiteout_m2_M2AnimationTrackM2CameraSpline_get_interpolationType(
13665            self_: *mut whiteout_M2AnimationTrackM2CameraSpline,
13666        ) -> i32;
13667        pub fn whiteout_m2_M2AnimationTrackM2CameraSpline_set_interpolationType(
13668            self_: *mut whiteout_M2AnimationTrackM2CameraSpline,
13669            value: i32,
13670        );
13671        pub fn whiteout_m2_M2AnimationTrackM2CameraSpline_get_globalSequenceId(
13672            self_: *mut whiteout_M2AnimationTrackM2CameraSpline,
13673        ) -> u16;
13674        pub fn whiteout_m2_M2AnimationTrackM2CameraSpline_set_globalSequenceId(
13675            self_: *mut whiteout_M2AnimationTrackM2CameraSpline,
13676            value: u16,
13677        );
13678        pub fn whiteout_m2_M2AnimationTrackM2CameraSpline_get_timestamps_count(
13679            self_: *mut whiteout_M2AnimationTrackM2CameraSpline,
13680        ) -> usize;
13681        pub fn whiteout_m2_M2AnimationTrackM2CameraSpline_get_timestamps_inner_count(
13682            self_: *mut whiteout_M2AnimationTrackM2CameraSpline,
13683            outer: usize,
13684        ) -> usize;
13685        pub fn whiteout_m2_M2AnimationTrackM2CameraSpline_resize_timestamps(
13686            self_: *mut whiteout_M2AnimationTrackM2CameraSpline,
13687            count: usize,
13688        );
13689        pub fn whiteout_m2_M2AnimationTrackM2CameraSpline_resize_timestamps_inner(
13690            self_: *mut whiteout_M2AnimationTrackM2CameraSpline,
13691            outer: usize,
13692            count: usize,
13693        );
13694        pub fn whiteout_m2_M2AnimationTrackM2CameraSpline_get_timestamps_inner_data(
13695            self_: *mut whiteout_M2AnimationTrackM2CameraSpline,
13696            outer: usize,
13697        ) -> *const u32;
13698        pub fn whiteout_m2_M2AnimationTrackM2CameraSpline_assign_timestamps_inner(
13699            self_: *mut whiteout_M2AnimationTrackM2CameraSpline,
13700            outer: usize,
13701            data: *const u32,
13702            count: usize,
13703        );
13704        pub fn whiteout_m2_M2AnimationTrackM2CameraSpline_get_values_count(
13705            self_: *mut whiteout_M2AnimationTrackM2CameraSpline,
13706        ) -> usize;
13707        pub fn whiteout_m2_M2AnimationTrackM2CameraSpline_get_values_inner_count(
13708            self_: *mut whiteout_M2AnimationTrackM2CameraSpline,
13709            outer: usize,
13710        ) -> usize;
13711        pub fn whiteout_m2_M2AnimationTrackM2CameraSpline_resize_values(
13712            self_: *mut whiteout_M2AnimationTrackM2CameraSpline,
13713            count: usize,
13714        );
13715        pub fn whiteout_m2_M2AnimationTrackM2CameraSpline_resize_values_inner(
13716            self_: *mut whiteout_M2AnimationTrackM2CameraSpline,
13717            outer: usize,
13718            count: usize,
13719        );
13720        pub fn whiteout_m2_M2AnimationTrackM2CameraSpline_get_values_at(
13721            self_: *mut whiteout_M2AnimationTrackM2CameraSpline,
13722            outer: usize,
13723            inner: usize,
13724        ) -> *mut whiteout_M2CameraSpline;
13725        // AnimationTrackU16
13726        pub fn whiteout_m2_M2AnimationTrackU16_new() -> *mut whiteout_M2AnimationTrackU16;
13727        pub fn whiteout_m2_M2AnimationTrackU16_delete(self_: *mut whiteout_M2AnimationTrackU16);
13728        pub fn whiteout_m2_M2AnimationTrackU16_get_interpolationType(
13729            self_: *mut whiteout_M2AnimationTrackU16,
13730        ) -> i32;
13731        pub fn whiteout_m2_M2AnimationTrackU16_set_interpolationType(
13732            self_: *mut whiteout_M2AnimationTrackU16,
13733            value: i32,
13734        );
13735        pub fn whiteout_m2_M2AnimationTrackU16_get_globalSequenceId(
13736            self_: *mut whiteout_M2AnimationTrackU16,
13737        ) -> u16;
13738        pub fn whiteout_m2_M2AnimationTrackU16_set_globalSequenceId(
13739            self_: *mut whiteout_M2AnimationTrackU16,
13740            value: u16,
13741        );
13742        pub fn whiteout_m2_M2AnimationTrackU16_get_timestamps_count(
13743            self_: *mut whiteout_M2AnimationTrackU16,
13744        ) -> usize;
13745        pub fn whiteout_m2_M2AnimationTrackU16_get_timestamps_inner_count(
13746            self_: *mut whiteout_M2AnimationTrackU16,
13747            outer: usize,
13748        ) -> usize;
13749        pub fn whiteout_m2_M2AnimationTrackU16_resize_timestamps(
13750            self_: *mut whiteout_M2AnimationTrackU16,
13751            count: usize,
13752        );
13753        pub fn whiteout_m2_M2AnimationTrackU16_resize_timestamps_inner(
13754            self_: *mut whiteout_M2AnimationTrackU16,
13755            outer: usize,
13756            count: usize,
13757        );
13758        pub fn whiteout_m2_M2AnimationTrackU16_get_timestamps_inner_data(
13759            self_: *mut whiteout_M2AnimationTrackU16,
13760            outer: usize,
13761        ) -> *const u32;
13762        pub fn whiteout_m2_M2AnimationTrackU16_assign_timestamps_inner(
13763            self_: *mut whiteout_M2AnimationTrackU16,
13764            outer: usize,
13765            data: *const u32,
13766            count: usize,
13767        );
13768        pub fn whiteout_m2_M2AnimationTrackU16_get_values_count(
13769            self_: *mut whiteout_M2AnimationTrackU16,
13770        ) -> usize;
13771        pub fn whiteout_m2_M2AnimationTrackU16_get_values_inner_count(
13772            self_: *mut whiteout_M2AnimationTrackU16,
13773            outer: usize,
13774        ) -> usize;
13775        pub fn whiteout_m2_M2AnimationTrackU16_resize_values(
13776            self_: *mut whiteout_M2AnimationTrackU16,
13777            count: usize,
13778        );
13779        pub fn whiteout_m2_M2AnimationTrackU16_resize_values_inner(
13780            self_: *mut whiteout_M2AnimationTrackU16,
13781            outer: usize,
13782            count: usize,
13783        );
13784        pub fn whiteout_m2_M2AnimationTrackU16_get_values_inner_data(
13785            self_: *mut whiteout_M2AnimationTrackU16,
13786            outer: usize,
13787        ) -> *const u16;
13788        pub fn whiteout_m2_M2AnimationTrackU16_assign_values_inner(
13789            self_: *mut whiteout_M2AnimationTrackU16,
13790            outer: usize,
13791            data: *const u16,
13792            count: usize,
13793        );
13794        // ParticleAnimationTrackVector3f
13795        pub fn whiteout_m2_M2ParticleAnimationTrackVector3f_new(
13796        ) -> *mut whiteout_M2ParticleAnimationTrackVector3f;
13797        pub fn whiteout_m2_M2ParticleAnimationTrackVector3f_delete(
13798            self_: *mut whiteout_M2ParticleAnimationTrackVector3f,
13799        );
13800        pub fn whiteout_m2_M2ParticleAnimationTrackVector3f_get_values_count(
13801            self_: *mut whiteout_M2ParticleAnimationTrackVector3f,
13802        ) -> usize;
13803        pub fn whiteout_m2_M2ParticleAnimationTrackVector3f_resize_values(
13804            self_: *mut whiteout_M2ParticleAnimationTrackVector3f,
13805            count: usize,
13806        );
13807        pub fn whiteout_m2_M2ParticleAnimationTrackVector3f_get_values_data(
13808            self_: *mut whiteout_M2ParticleAnimationTrackVector3f,
13809        ) -> *const f32;
13810        pub fn whiteout_m2_M2ParticleAnimationTrackVector3f_assign_values(
13811            self_: *mut whiteout_M2ParticleAnimationTrackVector3f,
13812            data: *const f32,
13813            count: usize,
13814        );
13815        // ParticleAnimationTrackVector2f
13816        pub fn whiteout_m2_M2ParticleAnimationTrackVector2f_new(
13817        ) -> *mut whiteout_M2ParticleAnimationTrackVector2f;
13818        pub fn whiteout_m2_M2ParticleAnimationTrackVector2f_delete(
13819            self_: *mut whiteout_M2ParticleAnimationTrackVector2f,
13820        );
13821        pub fn whiteout_m2_M2ParticleAnimationTrackVector2f_get_values_count(
13822            self_: *mut whiteout_M2ParticleAnimationTrackVector2f,
13823        ) -> usize;
13824        pub fn whiteout_m2_M2ParticleAnimationTrackVector2f_resize_values(
13825            self_: *mut whiteout_M2ParticleAnimationTrackVector2f,
13826            count: usize,
13827        );
13828        pub fn whiteout_m2_M2ParticleAnimationTrackVector2f_get_values_data(
13829            self_: *mut whiteout_M2ParticleAnimationTrackVector2f,
13830        ) -> *const f32;
13831        pub fn whiteout_m2_M2ParticleAnimationTrackVector2f_assign_values(
13832            self_: *mut whiteout_M2ParticleAnimationTrackVector2f,
13833            data: *const f32,
13834            count: usize,
13835        );
13836    }
13837}