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    /// Number of elements — a fixed-size C++ array.
928    pub const fn particle_bone_lod_len() -> usize {
929        4
930    }
931
932    /// # Panics
933    /// If `index >= 4`, matching Rust slice indexing.
934    pub fn particle_bone_lod(&self, index: usize) -> u8 {
935        assert!(
936            index < 4,
937            "particle_bone_lod index {index} out of range (len 4)"
938        );
939        // SAFETY: index checked above; plain scalar read.
940        unsafe { ffi::whiteout_m2_M2LodProfile_get_particleBoneLod_at(self.raw.as_ptr(), index) }
941    }
942
943    /// # Panics
944    /// If `index >= 4`.
945    pub fn set_particle_bone_lod(&mut self, index: usize, value: u8) {
946        assert!(
947            index < 4,
948            "particle_bone_lod index {index} out of range (len 4)"
949        );
950        // SAFETY: index checked above.
951        unsafe {
952            ffi::whiteout_m2_M2LodProfile_set_particleBoneLod_at(self.raw.as_ptr(), index, value)
953        }
954    }
955
956    pub fn reserved_0(&self) -> u8 {
957        // SAFETY: plain scalar read through a live handle.
958        unsafe { ffi::whiteout_m2_M2LodProfile_get_reserved0(self.raw.as_ptr()) }
959    }
960
961    pub fn set_reserved_0(&mut self, value: u8) {
962        // SAFETY: plain scalar write through a live handle.
963        unsafe { ffi::whiteout_m2_M2LodProfile_set_reserved0(self.raw.as_ptr(), value) }
964    }
965
966    pub fn lod_flags(&self) -> u8 {
967        // SAFETY: plain scalar read through a live handle.
968        unsafe { ffi::whiteout_m2_M2LodProfile_get_lodFlags(self.raw.as_ptr()) }
969    }
970
971    pub fn set_lod_flags(&mut self, value: u8) {
972        // SAFETY: plain scalar write through a live handle.
973        unsafe { ffi::whiteout_m2_M2LodProfile_set_lodFlags(self.raw.as_ptr(), value) }
974    }
975
976    pub fn lod_batch_count(&self) -> u8 {
977        // SAFETY: plain scalar read through a live handle.
978        unsafe { ffi::whiteout_m2_M2LodProfile_get_lodBatchCount(self.raw.as_ptr()) }
979    }
980
981    pub fn set_lod_batch_count(&mut self, value: u8) {
982        // SAFETY: plain scalar write through a live handle.
983        unsafe { ffi::whiteout_m2_M2LodProfile_set_lodBatchCount(self.raw.as_ptr(), value) }
984    }
985
986    pub fn reserved_1(&self) -> u8 {
987        // SAFETY: plain scalar read through a live handle.
988        unsafe { ffi::whiteout_m2_M2LodProfile_get_reserved1(self.raw.as_ptr()) }
989    }
990
991    pub fn set_reserved_1(&mut self, value: u8) {
992        // SAFETY: plain scalar write through a live handle.
993        unsafe { ffi::whiteout_m2_M2LodProfile_set_reserved1(self.raw.as_ptr(), value) }
994    }
995}
996
997impl Default for LodProfile {
998    fn default() -> Self {
999        Self::new()
1000    }
1001}
1002
1003pub struct WaterfallData {
1004    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2WaterfallData>,
1005}
1006
1007impl Drop for WaterfallData {
1008    fn drop(&mut self) {
1009        // SAFETY: `raw` came from a native constructor and Drop runs once.
1010        unsafe { ffi::whiteout_m2_M2WaterfallData_delete(self.raw.as_ptr()) }
1011    }
1012}
1013
1014impl WaterfallData {
1015    /// # Safety
1016    /// `raw` must be a live handle this value takes ownership of.
1017    #[allow(dead_code)] // used by whichever methods return this type
1018    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2WaterfallData) -> Option<Self> {
1019        core::ptr::NonNull::new(raw).map(|raw| WaterfallData { raw })
1020    }
1021}
1022
1023// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
1024// is deliberately NOT implemented — the C++ types make no documented
1025// guarantee about concurrent use, and claiming one we haven't verified
1026// would be unsound. See `@bind thread_safe` in the plan.
1027unsafe impl Send for WaterfallData {}
1028
1029impl core::fmt::Debug for WaterfallData {
1030    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1031        f.debug_struct("WaterfallData").finish_non_exhaustive()
1032    }
1033}
1034
1035impl WaterfallData {
1036    /// # Panics
1037    /// Panics if the native allocation fails.
1038    pub fn new() -> Self {
1039        // SAFETY: the native constructor returns a live handle; a null here
1040        // means the library is unusable.
1041        unsafe {
1042            let raw = ffi::whiteout_m2_M2WaterfallData_new();
1043            Self::from_raw(raw).expect("native WaterfallData allocation failed")
1044        }
1045    }
1046
1047    pub fn bump_scale(&self) -> f32 {
1048        // SAFETY: plain scalar read through a live handle.
1049        unsafe { ffi::whiteout_m2_M2WaterfallData_get_bumpScale(self.raw.as_ptr()) }
1050    }
1051
1052    pub fn set_bump_scale(&mut self, value: f32) {
1053        // SAFETY: plain scalar write through a live handle.
1054        unsafe { ffi::whiteout_m2_M2WaterfallData_set_bumpScale(self.raw.as_ptr(), value) }
1055    }
1056
1057    pub fn value_0x(&self) -> f32 {
1058        // SAFETY: plain scalar read through a live handle.
1059        unsafe { ffi::whiteout_m2_M2WaterfallData_get_value0_x(self.raw.as_ptr()) }
1060    }
1061
1062    pub fn set_value_0x(&mut self, value: f32) {
1063        // SAFETY: plain scalar write through a live handle.
1064        unsafe { ffi::whiteout_m2_M2WaterfallData_set_value0_x(self.raw.as_ptr(), value) }
1065    }
1066
1067    pub fn value_0y(&self) -> f32 {
1068        // SAFETY: plain scalar read through a live handle.
1069        unsafe { ffi::whiteout_m2_M2WaterfallData_get_value0_y(self.raw.as_ptr()) }
1070    }
1071
1072    pub fn set_value_0y(&mut self, value: f32) {
1073        // SAFETY: plain scalar write through a live handle.
1074        unsafe { ffi::whiteout_m2_M2WaterfallData_set_value0_y(self.raw.as_ptr(), value) }
1075    }
1076
1077    pub fn value_0z(&self) -> f32 {
1078        // SAFETY: plain scalar read through a live handle.
1079        unsafe { ffi::whiteout_m2_M2WaterfallData_get_value0_z(self.raw.as_ptr()) }
1080    }
1081
1082    pub fn set_value_0z(&mut self, value: f32) {
1083        // SAFETY: plain scalar write through a live handle.
1084        unsafe { ffi::whiteout_m2_M2WaterfallData_set_value0_z(self.raw.as_ptr(), value) }
1085    }
1086
1087    pub fn value_1w(&self) -> f32 {
1088        // SAFETY: plain scalar read through a live handle.
1089        unsafe { ffi::whiteout_m2_M2WaterfallData_get_value1_w(self.raw.as_ptr()) }
1090    }
1091
1092    pub fn set_value_1w(&mut self, value: f32) {
1093        // SAFETY: plain scalar write through a live handle.
1094        unsafe { ffi::whiteout_m2_M2WaterfallData_set_value1_w(self.raw.as_ptr(), value) }
1095    }
1096
1097    pub fn value_0w(&self) -> f32 {
1098        // SAFETY: plain scalar read through a live handle.
1099        unsafe { ffi::whiteout_m2_M2WaterfallData_get_value0_w(self.raw.as_ptr()) }
1100    }
1101
1102    pub fn set_value_0w(&mut self, value: f32) {
1103        // SAFETY: plain scalar write through a live handle.
1104        unsafe { ffi::whiteout_m2_M2WaterfallData_set_value0_w(self.raw.as_ptr(), value) }
1105    }
1106
1107    pub fn value_1x(&self) -> f32 {
1108        // SAFETY: plain scalar read through a live handle.
1109        unsafe { ffi::whiteout_m2_M2WaterfallData_get_value1_x(self.raw.as_ptr()) }
1110    }
1111
1112    pub fn set_value_1x(&mut self, value: f32) {
1113        // SAFETY: plain scalar write through a live handle.
1114        unsafe { ffi::whiteout_m2_M2WaterfallData_set_value1_x(self.raw.as_ptr(), value) }
1115    }
1116
1117    pub fn value_1y(&self) -> f32 {
1118        // SAFETY: plain scalar read through a live handle.
1119        unsafe { ffi::whiteout_m2_M2WaterfallData_get_value1_y(self.raw.as_ptr()) }
1120    }
1121
1122    pub fn set_value_1y(&mut self, value: f32) {
1123        // SAFETY: plain scalar write through a live handle.
1124        unsafe { ffi::whiteout_m2_M2WaterfallData_set_value1_y(self.raw.as_ptr(), value) }
1125    }
1126
1127    pub fn value_2w(&self) -> f32 {
1128        // SAFETY: plain scalar read through a live handle.
1129        unsafe { ffi::whiteout_m2_M2WaterfallData_get_value2_w(self.raw.as_ptr()) }
1130    }
1131
1132    pub fn set_value_2w(&mut self, value: f32) {
1133        // SAFETY: plain scalar write through a live handle.
1134        unsafe { ffi::whiteout_m2_M2WaterfallData_set_value2_w(self.raw.as_ptr(), value) }
1135    }
1136
1137    pub fn value_3y(&self) -> f32 {
1138        // SAFETY: plain scalar read through a live handle.
1139        unsafe { ffi::whiteout_m2_M2WaterfallData_get_value3_y(self.raw.as_ptr()) }
1140    }
1141
1142    pub fn set_value_3y(&mut self, value: f32) {
1143        // SAFETY: plain scalar write through a live handle.
1144        unsafe { ffi::whiteout_m2_M2WaterfallData_set_value3_y(self.raw.as_ptr(), value) }
1145    }
1146
1147    pub fn value_3x(&self) -> f32 {
1148        // SAFETY: plain scalar read through a live handle.
1149        unsafe { ffi::whiteout_m2_M2WaterfallData_get_value3_x(self.raw.as_ptr()) }
1150    }
1151
1152    pub fn set_value_3x(&mut self, value: f32) {
1153        // SAFETY: plain scalar write through a live handle.
1154        unsafe { ffi::whiteout_m2_M2WaterfallData_set_value3_x(self.raw.as_ptr(), value) }
1155    }
1156
1157    pub fn base_color(&self) -> crate::math::Vector4f {
1158        // SAFETY: the getter returns an interior pointer to a
1159        // layout-identical POD; we copy it out immediately.
1160        unsafe {
1161            *(ffi::whiteout_m2_M2WaterfallData_get_baseColor(self.raw.as_ptr())
1162                as *const crate::math::Vector4f)
1163        }
1164    }
1165
1166    pub fn set_base_color(&mut self, value: crate::math::Vector4f) {
1167        // SAFETY: as above, in the other direction.
1168        unsafe {
1169            ffi::whiteout_m2_M2WaterfallData_set_baseColor(
1170                self.raw.as_ptr(),
1171                &value as *const crate::math::Vector4f as *const _,
1172            )
1173        }
1174    }
1175
1176    pub fn flags(&self) -> u16 {
1177        // SAFETY: plain scalar read through a live handle.
1178        unsafe { ffi::whiteout_m2_M2WaterfallData_get_flags(self.raw.as_ptr()) }
1179    }
1180
1181    pub fn set_flags(&mut self, value: u16) {
1182        // SAFETY: plain scalar write through a live handle.
1183        unsafe { ffi::whiteout_m2_M2WaterfallData_set_flags(self.raw.as_ptr(), value) }
1184    }
1185
1186    pub fn unknown_0(&self) -> u16 {
1187        // SAFETY: plain scalar read through a live handle.
1188        unsafe { ffi::whiteout_m2_M2WaterfallData_get_unknown0(self.raw.as_ptr()) }
1189    }
1190
1191    pub fn set_unknown_0(&mut self, value: u16) {
1192        // SAFETY: plain scalar write through a live handle.
1193        unsafe { ffi::whiteout_m2_M2WaterfallData_set_unknown0(self.raw.as_ptr(), value) }
1194    }
1195
1196    pub fn value_3w(&self) -> f32 {
1197        // SAFETY: plain scalar read through a live handle.
1198        unsafe { ffi::whiteout_m2_M2WaterfallData_get_value3_w(self.raw.as_ptr()) }
1199    }
1200
1201    pub fn set_value_3w(&mut self, value: f32) {
1202        // SAFETY: plain scalar write through a live handle.
1203        unsafe { ffi::whiteout_m2_M2WaterfallData_set_value3_w(self.raw.as_ptr(), value) }
1204    }
1205
1206    pub fn value_3z(&self) -> f32 {
1207        // SAFETY: plain scalar read through a live handle.
1208        unsafe { ffi::whiteout_m2_M2WaterfallData_get_value3_z(self.raw.as_ptr()) }
1209    }
1210
1211    pub fn set_value_3z(&mut self, value: f32) {
1212        // SAFETY: plain scalar write through a live handle.
1213        unsafe { ffi::whiteout_m2_M2WaterfallData_set_value3_z(self.raw.as_ptr(), value) }
1214    }
1215
1216    pub fn value_4y(&self) -> f32 {
1217        // SAFETY: plain scalar read through a live handle.
1218        unsafe { ffi::whiteout_m2_M2WaterfallData_get_value4_y(self.raw.as_ptr()) }
1219    }
1220
1221    pub fn set_value_4y(&mut self, value: f32) {
1222        // SAFETY: plain scalar write through a live handle.
1223        unsafe { ffi::whiteout_m2_M2WaterfallData_set_value4_y(self.raw.as_ptr(), value) }
1224    }
1225
1226    pub fn unknown_1(&self) -> f32 {
1227        // SAFETY: plain scalar read through a live handle.
1228        unsafe { ffi::whiteout_m2_M2WaterfallData_get_unknown1(self.raw.as_ptr()) }
1229    }
1230
1231    pub fn set_unknown_1(&mut self, value: f32) {
1232        // SAFETY: plain scalar write through a live handle.
1233        unsafe { ffi::whiteout_m2_M2WaterfallData_set_unknown1(self.raw.as_ptr(), value) }
1234    }
1235
1236    pub fn unknown_2(&self) -> f32 {
1237        // SAFETY: plain scalar read through a live handle.
1238        unsafe { ffi::whiteout_m2_M2WaterfallData_get_unknown2(self.raw.as_ptr()) }
1239    }
1240
1241    pub fn set_unknown_2(&mut self, value: f32) {
1242        // SAFETY: plain scalar write through a live handle.
1243        unsafe { ffi::whiteout_m2_M2WaterfallData_set_unknown2(self.raw.as_ptr(), value) }
1244    }
1245
1246    pub fn unknown_3(&self) -> f32 {
1247        // SAFETY: plain scalar read through a live handle.
1248        unsafe { ffi::whiteout_m2_M2WaterfallData_get_unknown3(self.raw.as_ptr()) }
1249    }
1250
1251    pub fn set_unknown_3(&mut self, value: f32) {
1252        // SAFETY: plain scalar write through a live handle.
1253        unsafe { ffi::whiteout_m2_M2WaterfallData_set_unknown3(self.raw.as_ptr(), value) }
1254    }
1255
1256    pub fn unknown_4(&self) -> f32 {
1257        // SAFETY: plain scalar read through a live handle.
1258        unsafe { ffi::whiteout_m2_M2WaterfallData_get_unknown4(self.raw.as_ptr()) }
1259    }
1260
1261    pub fn set_unknown_4(&mut self, value: f32) {
1262        // SAFETY: plain scalar write through a live handle.
1263        unsafe { ffi::whiteout_m2_M2WaterfallData_set_unknown4(self.raw.as_ptr(), value) }
1264    }
1265}
1266
1267impl Default for WaterfallData {
1268    fn default() -> Self {
1269        Self::new()
1270    }
1271}
1272
1273pub struct ParticleGeosetData {
1274    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2ParticleGeosetData>,
1275}
1276
1277impl Drop for ParticleGeosetData {
1278    fn drop(&mut self) {
1279        // SAFETY: `raw` came from a native constructor and Drop runs once.
1280        unsafe { ffi::whiteout_m2_M2ParticleGeosetData_delete(self.raw.as_ptr()) }
1281    }
1282}
1283
1284impl ParticleGeosetData {
1285    /// # Safety
1286    /// `raw` must be a live handle this value takes ownership of.
1287    #[allow(dead_code)] // used by whichever methods return this type
1288    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2ParticleGeosetData) -> Option<Self> {
1289        core::ptr::NonNull::new(raw).map(|raw| ParticleGeosetData { raw })
1290    }
1291}
1292
1293// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
1294// is deliberately NOT implemented — the C++ types make no documented
1295// guarantee about concurrent use, and claiming one we haven't verified
1296// would be unsound. See `@bind thread_safe` in the plan.
1297unsafe impl Send for ParticleGeosetData {}
1298
1299impl core::fmt::Debug for ParticleGeosetData {
1300    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1301        f.debug_struct("ParticleGeosetData").finish_non_exhaustive()
1302    }
1303}
1304
1305impl ParticleGeosetData {
1306    /// # Panics
1307    /// Panics if the native allocation fails.
1308    pub fn new() -> Self {
1309        // SAFETY: the native constructor returns a live handle; a null here
1310        // means the library is unusable.
1311        unsafe {
1312            let raw = ffi::whiteout_m2_M2ParticleGeosetData_new();
1313            Self::from_raw(raw).expect("native ParticleGeosetData allocation failed")
1314        }
1315    }
1316
1317    pub fn geoset(&self) -> u16 {
1318        // SAFETY: plain scalar read through a live handle.
1319        unsafe { ffi::whiteout_m2_M2ParticleGeosetData_get_geoset(self.raw.as_ptr()) }
1320    }
1321
1322    pub fn set_geoset(&mut self, value: u16) {
1323        // SAFETY: plain scalar write through a live handle.
1324        unsafe { ffi::whiteout_m2_M2ParticleGeosetData_set_geoset(self.raw.as_ptr(), value) }
1325    }
1326}
1327
1328impl Default for ParticleGeosetData {
1329    fn default() -> Self {
1330        Self::new()
1331    }
1332}
1333
1334pub struct EdgeFadeData {
1335    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2EdgeFadeData>,
1336}
1337
1338impl Drop for EdgeFadeData {
1339    fn drop(&mut self) {
1340        // SAFETY: `raw` came from a native constructor and Drop runs once.
1341        unsafe { ffi::whiteout_m2_M2EdgeFadeData_delete(self.raw.as_ptr()) }
1342    }
1343}
1344
1345impl EdgeFadeData {
1346    /// # Safety
1347    /// `raw` must be a live handle this value takes ownership of.
1348    #[allow(dead_code)] // used by whichever methods return this type
1349    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2EdgeFadeData) -> Option<Self> {
1350        core::ptr::NonNull::new(raw).map(|raw| EdgeFadeData { raw })
1351    }
1352}
1353
1354// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
1355// is deliberately NOT implemented — the C++ types make no documented
1356// guarantee about concurrent use, and claiming one we haven't verified
1357// would be unsound. See `@bind thread_safe` in the plan.
1358unsafe impl Send for EdgeFadeData {}
1359
1360impl core::fmt::Debug for EdgeFadeData {
1361    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1362        f.debug_struct("EdgeFadeData").finish_non_exhaustive()
1363    }
1364}
1365
1366impl EdgeFadeData {
1367    /// # Panics
1368    /// Panics if the native allocation fails.
1369    pub fn new() -> Self {
1370        // SAFETY: the native constructor returns a live handle; a null here
1371        // means the library is unusable.
1372        unsafe {
1373            let raw = ffi::whiteout_m2_M2EdgeFadeData_new();
1374            Self::from_raw(raw).expect("native EdgeFadeData allocation failed")
1375        }
1376    }
1377
1378    /// Number of elements — a fixed-size C++ array.
1379    pub const fn value_0_len() -> usize {
1380        2
1381    }
1382
1383    /// # Panics
1384    /// If `index >= 2`, matching Rust slice indexing.
1385    pub fn value_0(&self, index: usize) -> f32 {
1386        assert!(index < 2, "value_0 index {index} out of range (len 2)");
1387        // SAFETY: index checked above; plain scalar read.
1388        unsafe { ffi::whiteout_m2_M2EdgeFadeData_get_value0_at(self.raw.as_ptr(), index) }
1389    }
1390
1391    /// # Panics
1392    /// If `index >= 2`.
1393    pub fn set_value_0(&mut self, index: usize, value: f32) {
1394        assert!(index < 2, "value_0 index {index} out of range (len 2)");
1395        // SAFETY: index checked above.
1396        unsafe { ffi::whiteout_m2_M2EdgeFadeData_set_value0_at(self.raw.as_ptr(), index, value) }
1397    }
1398
1399    pub fn value_8(&self) -> f32 {
1400        // SAFETY: plain scalar read through a live handle.
1401        unsafe { ffi::whiteout_m2_M2EdgeFadeData_get_value8(self.raw.as_ptr()) }
1402    }
1403
1404    pub fn set_value_8(&mut self, value: f32) {
1405        // SAFETY: plain scalar write through a live handle.
1406        unsafe { ffi::whiteout_m2_M2EdgeFadeData_set_value8(self.raw.as_ptr(), value) }
1407    }
1408
1409    /// Number of elements — a fixed-size C++ array.
1410    pub const fn value_c_len() -> usize {
1411        12
1412    }
1413
1414    /// # Panics
1415    /// If `index >= 12`, matching Rust slice indexing.
1416    pub fn value_c(&self, index: usize) -> u8 {
1417        assert!(index < 12, "value_c index {index} out of range (len 12)");
1418        // SAFETY: index checked above; plain scalar read.
1419        unsafe { ffi::whiteout_m2_M2EdgeFadeData_get_valueC_at(self.raw.as_ptr(), index) }
1420    }
1421
1422    /// # Panics
1423    /// If `index >= 12`.
1424    pub fn set_value_c(&mut self, index: usize, value: u8) {
1425        assert!(index < 12, "value_c index {index} out of range (len 12)");
1426        // SAFETY: index checked above.
1427        unsafe { ffi::whiteout_m2_M2EdgeFadeData_set_valueC_at(self.raw.as_ptr(), index, value) }
1428    }
1429}
1430
1431impl Default for EdgeFadeData {
1432    fn default() -> Self {
1433        Self::new()
1434    }
1435}
1436
1437pub struct DistanceFadeData {
1438    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2DistanceFadeData>,
1439}
1440
1441impl Drop for DistanceFadeData {
1442    fn drop(&mut self) {
1443        // SAFETY: `raw` came from a native constructor and Drop runs once.
1444        unsafe { ffi::whiteout_m2_M2DistanceFadeData_delete(self.raw.as_ptr()) }
1445    }
1446}
1447
1448impl DistanceFadeData {
1449    /// # Safety
1450    /// `raw` must be a live handle this value takes ownership of.
1451    #[allow(dead_code)] // used by whichever methods return this type
1452    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2DistanceFadeData) -> Option<Self> {
1453        core::ptr::NonNull::new(raw).map(|raw| DistanceFadeData { raw })
1454    }
1455}
1456
1457// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
1458// is deliberately NOT implemented — the C++ types make no documented
1459// guarantee about concurrent use, and claiming one we haven't verified
1460// would be unsound. See `@bind thread_safe` in the plan.
1461unsafe impl Send for DistanceFadeData {}
1462
1463impl core::fmt::Debug for DistanceFadeData {
1464    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1465        f.debug_struct("DistanceFadeData").finish_non_exhaustive()
1466    }
1467}
1468
1469impl DistanceFadeData {
1470    /// # Panics
1471    /// Panics if the native allocation fails.
1472    pub fn new() -> Self {
1473        // SAFETY: the native constructor returns a live handle; a null here
1474        // means the library is unusable.
1475        unsafe {
1476            let raw = ffi::whiteout_m2_M2DistanceFadeData_new();
1477            Self::from_raw(raw).expect("native DistanceFadeData allocation failed")
1478        }
1479    }
1480
1481    pub fn squared_far_dist(&self) -> f32 {
1482        // SAFETY: plain scalar read through a live handle.
1483        unsafe { ffi::whiteout_m2_M2DistanceFadeData_get_squaredFarDist(self.raw.as_ptr()) }
1484    }
1485
1486    pub fn set_squared_far_dist(&mut self, value: f32) {
1487        // SAFETY: plain scalar write through a live handle.
1488        unsafe { ffi::whiteout_m2_M2DistanceFadeData_set_squaredFarDist(self.raw.as_ptr(), value) }
1489    }
1490
1491    pub fn squared_near_dist(&self) -> f32 {
1492        // SAFETY: plain scalar read through a live handle.
1493        unsafe { ffi::whiteout_m2_M2DistanceFadeData_get_squaredNearDist(self.raw.as_ptr()) }
1494    }
1495
1496    pub fn set_squared_near_dist(&mut self, value: f32) {
1497        // SAFETY: plain scalar write through a live handle.
1498        unsafe { ffi::whiteout_m2_M2DistanceFadeData_set_squaredNearDist(self.raw.as_ptr(), value) }
1499    }
1500
1501    /// Number of elements — a fixed-size C++ array.
1502    pub const fn reserved_len() -> usize {
1503        2
1504    }
1505
1506    /// # Panics
1507    /// If `index >= 2`, matching Rust slice indexing.
1508    pub fn reserved(&self, index: usize) -> u32 {
1509        assert!(index < 2, "reserved index {index} out of range (len 2)");
1510        // SAFETY: index checked above; plain scalar read.
1511        unsafe { ffi::whiteout_m2_M2DistanceFadeData_get_reserved_at(self.raw.as_ptr(), index) }
1512    }
1513
1514    /// # Panics
1515    /// If `index >= 2`.
1516    pub fn set_reserved(&mut self, index: usize, value: u32) {
1517        assert!(index < 2, "reserved index {index} out of range (len 2)");
1518        // SAFETY: index checked above.
1519        unsafe {
1520            ffi::whiteout_m2_M2DistanceFadeData_set_reserved_at(self.raw.as_ptr(), index, value)
1521        }
1522    }
1523}
1524
1525impl Default for DistanceFadeData {
1526    fn default() -> Self {
1527        Self::new()
1528    }
1529}
1530
1531pub struct DetailedLightData {
1532    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2DetailedLightData>,
1533}
1534
1535impl Drop for DetailedLightData {
1536    fn drop(&mut self) {
1537        // SAFETY: `raw` came from a native constructor and Drop runs once.
1538        unsafe { ffi::whiteout_m2_M2DetailedLightData_delete(self.raw.as_ptr()) }
1539    }
1540}
1541
1542impl DetailedLightData {
1543    /// # Safety
1544    /// `raw` must be a live handle this value takes ownership of.
1545    #[allow(dead_code)] // used by whichever methods return this type
1546    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2DetailedLightData) -> Option<Self> {
1547        core::ptr::NonNull::new(raw).map(|raw| DetailedLightData { raw })
1548    }
1549}
1550
1551// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
1552// is deliberately NOT implemented — the C++ types make no documented
1553// guarantee about concurrent use, and claiming one we haven't verified
1554// would be unsound. See `@bind thread_safe` in the plan.
1555unsafe impl Send for DetailedLightData {}
1556
1557impl core::fmt::Debug for DetailedLightData {
1558    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1559        f.debug_struct("DetailedLightData").finish_non_exhaustive()
1560    }
1561}
1562
1563impl DetailedLightData {
1564    /// # Panics
1565    /// Panics if the native allocation fails.
1566    pub fn new() -> Self {
1567        // SAFETY: the native constructor returns a live handle; a null here
1568        // means the library is unusable.
1569        unsafe {
1570            let raw = ffi::whiteout_m2_M2DetailedLightData_new();
1571            Self::from_raw(raw).expect("native DetailedLightData allocation failed")
1572        }
1573    }
1574
1575    pub fn flags(&self) -> u16 {
1576        // SAFETY: plain scalar read through a live handle.
1577        unsafe { ffi::whiteout_m2_M2DetailedLightData_get_flags(self.raw.as_ptr()) }
1578    }
1579
1580    pub fn set_flags(&mut self, value: u16) {
1581        // SAFETY: plain scalar write through a live handle.
1582        unsafe { ffi::whiteout_m2_M2DetailedLightData_set_flags(self.raw.as_ptr(), value) }
1583    }
1584
1585    pub fn unknown_0(&self) -> u16 {
1586        // SAFETY: plain scalar read through a live handle.
1587        unsafe { ffi::whiteout_m2_M2DetailedLightData_get_unknown0(self.raw.as_ptr()) }
1588    }
1589
1590    pub fn set_unknown_0(&mut self, value: u16) {
1591        // SAFETY: plain scalar write through a live handle.
1592        unsafe { ffi::whiteout_m2_M2DetailedLightData_set_unknown0(self.raw.as_ptr(), value) }
1593    }
1594
1595    pub fn unknown_1(&self) -> u32 {
1596        // SAFETY: plain scalar read through a live handle.
1597        unsafe { ffi::whiteout_m2_M2DetailedLightData_get_unknown1(self.raw.as_ptr()) }
1598    }
1599
1600    pub fn set_unknown_1(&mut self, value: u32) {
1601        // SAFETY: plain scalar write through a live handle.
1602        unsafe { ffi::whiteout_m2_M2DetailedLightData_set_unknown1(self.raw.as_ptr(), value) }
1603    }
1604}
1605
1606impl Default for DetailedLightData {
1607    fn default() -> Self {
1608        Self::new()
1609    }
1610}
1611
1612pub struct DebugOcclusionData {
1613    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2DebugOcclusionData>,
1614}
1615
1616impl Drop for DebugOcclusionData {
1617    fn drop(&mut self) {
1618        // SAFETY: `raw` came from a native constructor and Drop runs once.
1619        unsafe { ffi::whiteout_m2_M2DebugOcclusionData_delete(self.raw.as_ptr()) }
1620    }
1621}
1622
1623impl DebugOcclusionData {
1624    /// # Safety
1625    /// `raw` must be a live handle this value takes ownership of.
1626    #[allow(dead_code)] // used by whichever methods return this type
1627    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2DebugOcclusionData) -> Option<Self> {
1628        core::ptr::NonNull::new(raw).map(|raw| DebugOcclusionData { raw })
1629    }
1630}
1631
1632// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
1633// is deliberately NOT implemented — the C++ types make no documented
1634// guarantee about concurrent use, and claiming one we haven't verified
1635// would be unsound. See `@bind thread_safe` in the plan.
1636unsafe impl Send for DebugOcclusionData {}
1637
1638impl core::fmt::Debug for DebugOcclusionData {
1639    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1640        f.debug_struct("DebugOcclusionData").finish_non_exhaustive()
1641    }
1642}
1643
1644impl DebugOcclusionData {
1645    /// # Panics
1646    /// Panics if the native allocation fails.
1647    pub fn new() -> Self {
1648        // SAFETY: the native constructor returns a live handle; a null here
1649        // means the library is unusable.
1650        unsafe {
1651            let raw = ffi::whiteout_m2_M2DebugOcclusionData_new();
1652            Self::from_raw(raw).expect("native DebugOcclusionData allocation failed")
1653        }
1654    }
1655
1656    pub fn unknown_1_1(&self) -> f32 {
1657        // SAFETY: plain scalar read through a live handle.
1658        unsafe { ffi::whiteout_m2_M2DebugOcclusionData_get_unknown1_1(self.raw.as_ptr()) }
1659    }
1660
1661    pub fn set_unknown_1_1(&mut self, value: f32) {
1662        // SAFETY: plain scalar write through a live handle.
1663        unsafe { ffi::whiteout_m2_M2DebugOcclusionData_set_unknown1_1(self.raw.as_ptr(), value) }
1664    }
1665
1666    pub fn unknown_1_2(&self) -> f32 {
1667        // SAFETY: plain scalar read through a live handle.
1668        unsafe { ffi::whiteout_m2_M2DebugOcclusionData_get_unknown1_2(self.raw.as_ptr()) }
1669    }
1670
1671    pub fn set_unknown_1_2(&mut self, value: f32) {
1672        // SAFETY: plain scalar write through a live handle.
1673        unsafe { ffi::whiteout_m2_M2DebugOcclusionData_set_unknown1_2(self.raw.as_ptr(), value) }
1674    }
1675
1676    pub fn unknown_1_3(&self) -> u32 {
1677        // SAFETY: plain scalar read through a live handle.
1678        unsafe { ffi::whiteout_m2_M2DebugOcclusionData_get_unknown1_3(self.raw.as_ptr()) }
1679    }
1680
1681    pub fn set_unknown_1_3(&mut self, value: u32) {
1682        // SAFETY: plain scalar write through a live handle.
1683        unsafe { ffi::whiteout_m2_M2DebugOcclusionData_set_unknown1_3(self.raw.as_ptr(), value) }
1684    }
1685
1686    pub fn unknown_1_4(&self) -> u32 {
1687        // SAFETY: plain scalar read through a live handle.
1688        unsafe { ffi::whiteout_m2_M2DebugOcclusionData_get_unknown1_4(self.raw.as_ptr()) }
1689    }
1690
1691    pub fn set_unknown_1_4(&mut self, value: u32) {
1692        // SAFETY: plain scalar write through a live handle.
1693        unsafe { ffi::whiteout_m2_M2DebugOcclusionData_set_unknown1_4(self.raw.as_ptr(), value) }
1694    }
1695}
1696
1697impl Default for DebugOcclusionData {
1698    fn default() -> Self {
1699        Self::new()
1700    }
1701}
1702
1703pub struct TexturedLightData {
1704    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2TexturedLightData>,
1705}
1706
1707impl Drop for TexturedLightData {
1708    fn drop(&mut self) {
1709        // SAFETY: `raw` came from a native constructor and Drop runs once.
1710        unsafe { ffi::whiteout_m2_M2TexturedLightData_delete(self.raw.as_ptr()) }
1711    }
1712}
1713
1714impl TexturedLightData {
1715    /// # Safety
1716    /// `raw` must be a live handle this value takes ownership of.
1717    #[allow(dead_code)] // used by whichever methods return this type
1718    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2TexturedLightData) -> Option<Self> {
1719        core::ptr::NonNull::new(raw).map(|raw| TexturedLightData { raw })
1720    }
1721}
1722
1723// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
1724// is deliberately NOT implemented — the C++ types make no documented
1725// guarantee about concurrent use, and claiming one we haven't verified
1726// would be unsound. See `@bind thread_safe` in the plan.
1727unsafe impl Send for TexturedLightData {}
1728
1729impl core::fmt::Debug for TexturedLightData {
1730    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1731        f.debug_struct("TexturedLightData").finish_non_exhaustive()
1732    }
1733}
1734
1735impl TexturedLightData {
1736    /// # Panics
1737    /// Panics if the native allocation fails.
1738    pub fn new() -> Self {
1739        // SAFETY: the native constructor returns a live handle; a null here
1740        // means the library is unusable.
1741        unsafe {
1742            let raw = ffi::whiteout_m2_M2TexturedLightData_new();
1743            Self::from_raw(raw).expect("native TexturedLightData allocation failed")
1744        }
1745    }
1746
1747    pub fn unknown_0(&self) -> f32 {
1748        // SAFETY: plain scalar read through a live handle.
1749        unsafe { ffi::whiteout_m2_M2TexturedLightData_get_unknown0(self.raw.as_ptr()) }
1750    }
1751
1752    pub fn set_unknown_0(&mut self, value: f32) {
1753        // SAFETY: plain scalar write through a live handle.
1754        unsafe { ffi::whiteout_m2_M2TexturedLightData_set_unknown0(self.raw.as_ptr(), value) }
1755    }
1756
1757    pub fn unknown_1(&self) -> f32 {
1758        // SAFETY: plain scalar read through a live handle.
1759        unsafe { ffi::whiteout_m2_M2TexturedLightData_get_unknown1(self.raw.as_ptr()) }
1760    }
1761
1762    pub fn set_unknown_1(&mut self, value: f32) {
1763        // SAFETY: plain scalar write through a live handle.
1764        unsafe { ffi::whiteout_m2_M2TexturedLightData_set_unknown1(self.raw.as_ptr(), value) }
1765    }
1766
1767    pub fn texture_lookup(&self) -> i32 {
1768        // SAFETY: plain scalar read through a live handle.
1769        unsafe { ffi::whiteout_m2_M2TexturedLightData_get_textureLookup(self.raw.as_ptr()) }
1770    }
1771
1772    pub fn set_texture_lookup(&mut self, value: i32) {
1773        // SAFETY: plain scalar write through a live handle.
1774        unsafe { ffi::whiteout_m2_M2TexturedLightData_set_textureLookup(self.raw.as_ptr(), value) }
1775    }
1776
1777    pub fn unknown_2(&self) -> i32 {
1778        // SAFETY: plain scalar read through a live handle.
1779        unsafe { ffi::whiteout_m2_M2TexturedLightData_get_unknown2(self.raw.as_ptr()) }
1780    }
1781
1782    pub fn set_unknown_2(&mut self, value: i32) {
1783        // SAFETY: plain scalar write through a live handle.
1784        unsafe { ffi::whiteout_m2_M2TexturedLightData_set_unknown2(self.raw.as_ptr(), value) }
1785    }
1786}
1787
1788impl Default for TexturedLightData {
1789    fn default() -> Self {
1790        Self::new()
1791    }
1792}
1793
1794pub struct PhysicsCollision {
1795    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2PhysicsCollision>,
1796}
1797
1798impl Drop for PhysicsCollision {
1799    fn drop(&mut self) {
1800        // SAFETY: `raw` came from a native constructor and Drop runs once.
1801        unsafe { ffi::whiteout_m2_M2PhysicsCollision_delete(self.raw.as_ptr()) }
1802    }
1803}
1804
1805impl PhysicsCollision {
1806    /// # Safety
1807    /// `raw` must be a live handle this value takes ownership of.
1808    #[allow(dead_code)] // used by whichever methods return this type
1809    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2PhysicsCollision) -> Option<Self> {
1810        core::ptr::NonNull::new(raw).map(|raw| PhysicsCollision { raw })
1811    }
1812}
1813
1814// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
1815// is deliberately NOT implemented — the C++ types make no documented
1816// guarantee about concurrent use, and claiming one we haven't verified
1817// would be unsound. See `@bind thread_safe` in the plan.
1818unsafe impl Send for PhysicsCollision {}
1819
1820impl core::fmt::Debug for PhysicsCollision {
1821    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1822        f.debug_struct("PhysicsCollision").finish_non_exhaustive()
1823    }
1824}
1825
1826impl PhysicsCollision {
1827    /// # Panics
1828    /// Panics if the native allocation fails.
1829    pub fn new() -> Self {
1830        // SAFETY: the native constructor returns a live handle; a null here
1831        // means the library is unusable.
1832        unsafe {
1833            let raw = ffi::whiteout_m2_M2PhysicsCollision_new();
1834            Self::from_raw(raw).expect("native PhysicsCollision allocation failed")
1835        }
1836    }
1837
1838    /// Zero-copy view of the underlying `std::vector`.
1839    pub fn vertex_positions(&self) -> &[crate::math::Vector3f] {
1840        // SAFETY: `_data`/`_count` describe one contiguous C++
1841        // allocation, borrowed for as long as `self` is.
1842        unsafe {
1843            let n =
1844                ffi::whiteout_m2_M2PhysicsCollision_get_vertexPositions_count(self.raw.as_ptr());
1845            let p = ffi::whiteout_m2_M2PhysicsCollision_get_vertexPositions_data(self.raw.as_ptr())
1846                as *const crate::math::Vector3f;
1847            if p.is_null() || n == 0 {
1848                &[]
1849            } else {
1850                core::slice::from_raw_parts(p, n)
1851            }
1852        }
1853    }
1854
1855    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
1856    pub fn vertex_positions_mut(&mut self) -> &mut [crate::math::Vector3f] {
1857        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
1858        unsafe {
1859            let n =
1860                ffi::whiteout_m2_M2PhysicsCollision_get_vertexPositions_count(self.raw.as_ptr());
1861            let p = ffi::whiteout_m2_M2PhysicsCollision_get_vertexPositions_data(self.raw.as_ptr())
1862                as *const crate::math::Vector3f as *mut crate::math::Vector3f;
1863            if p.is_null() || n == 0 {
1864                &mut []
1865            } else {
1866                core::slice::from_raw_parts_mut(p, n)
1867            }
1868        }
1869    }
1870
1871    pub fn set_vertex_positions(&mut self, values: &[crate::math::Vector3f]) {
1872        // SAFETY: the native side copies `values` before returning.
1873        unsafe {
1874            ffi::whiteout_m2_M2PhysicsCollision_assign_vertexPositions(
1875                self.raw.as_ptr(),
1876                values.as_ptr() as *const _,
1877                values.len(),
1878            )
1879        }
1880    }
1881
1882    pub fn resize_vertex_positions(&mut self, count: usize) {
1883        // SAFETY: reallocation is safe here precisely because
1884        // `&mut self` means no slice borrow is outstanding.
1885        unsafe {
1886            ffi::whiteout_m2_M2PhysicsCollision_resize_vertexPositions(self.raw.as_ptr(), count)
1887        }
1888    }
1889
1890    /// Zero-copy view of the underlying `std::vector`.
1891    pub fn face_normals(&self) -> &[crate::math::Vector3f] {
1892        // SAFETY: `_data`/`_count` describe one contiguous C++
1893        // allocation, borrowed for as long as `self` is.
1894        unsafe {
1895            let n = ffi::whiteout_m2_M2PhysicsCollision_get_faceNormals_count(self.raw.as_ptr());
1896            let p = ffi::whiteout_m2_M2PhysicsCollision_get_faceNormals_data(self.raw.as_ptr())
1897                as *const crate::math::Vector3f;
1898            if p.is_null() || n == 0 {
1899                &[]
1900            } else {
1901                core::slice::from_raw_parts(p, n)
1902            }
1903        }
1904    }
1905
1906    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
1907    pub fn face_normals_mut(&mut self) -> &mut [crate::math::Vector3f] {
1908        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
1909        unsafe {
1910            let n = ffi::whiteout_m2_M2PhysicsCollision_get_faceNormals_count(self.raw.as_ptr());
1911            let p = ffi::whiteout_m2_M2PhysicsCollision_get_faceNormals_data(self.raw.as_ptr())
1912                as *const crate::math::Vector3f as *mut crate::math::Vector3f;
1913            if p.is_null() || n == 0 {
1914                &mut []
1915            } else {
1916                core::slice::from_raw_parts_mut(p, n)
1917            }
1918        }
1919    }
1920
1921    pub fn set_face_normals(&mut self, values: &[crate::math::Vector3f]) {
1922        // SAFETY: the native side copies `values` before returning.
1923        unsafe {
1924            ffi::whiteout_m2_M2PhysicsCollision_assign_faceNormals(
1925                self.raw.as_ptr(),
1926                values.as_ptr() as *const _,
1927                values.len(),
1928            )
1929        }
1930    }
1931
1932    pub fn resize_face_normals(&mut self, count: usize) {
1933        // SAFETY: reallocation is safe here precisely because
1934        // `&mut self` means no slice borrow is outstanding.
1935        unsafe { ffi::whiteout_m2_M2PhysicsCollision_resize_faceNormals(self.raw.as_ptr(), count) }
1936    }
1937
1938    /// Zero-copy view of the underlying `std::vector`.
1939    pub fn indices(&self) -> &[i16] {
1940        // SAFETY: `_data`/`_count` describe one contiguous C++
1941        // allocation, borrowed for as long as `self` is.
1942        unsafe {
1943            let n = ffi::whiteout_m2_M2PhysicsCollision_get_indices_count(self.raw.as_ptr());
1944            let p = ffi::whiteout_m2_M2PhysicsCollision_get_indices_data(self.raw.as_ptr());
1945            if p.is_null() || n == 0 {
1946                &[]
1947            } else {
1948                core::slice::from_raw_parts(p, n)
1949            }
1950        }
1951    }
1952
1953    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
1954    pub fn indices_mut(&mut self) -> &mut [i16] {
1955        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
1956        unsafe {
1957            let n = ffi::whiteout_m2_M2PhysicsCollision_get_indices_count(self.raw.as_ptr());
1958            let p =
1959                ffi::whiteout_m2_M2PhysicsCollision_get_indices_data(self.raw.as_ptr()) as *mut i16;
1960            if p.is_null() || n == 0 {
1961                &mut []
1962            } else {
1963                core::slice::from_raw_parts_mut(p, n)
1964            }
1965        }
1966    }
1967
1968    pub fn set_indices(&mut self, values: &[i16]) {
1969        // SAFETY: the native side copies `values` before returning.
1970        unsafe {
1971            ffi::whiteout_m2_M2PhysicsCollision_assign_indices(
1972                self.raw.as_ptr(),
1973                values.as_ptr() as *const _,
1974                values.len(),
1975            )
1976        }
1977    }
1978
1979    pub fn resize_indices(&mut self, count: usize) {
1980        // SAFETY: reallocation is safe here precisely because
1981        // `&mut self` means no slice borrow is outstanding.
1982        unsafe { ffi::whiteout_m2_M2PhysicsCollision_resize_indices(self.raw.as_ptr(), count) }
1983    }
1984
1985    /// Zero-copy view of the underlying `std::vector`.
1986    pub fn flags(&self) -> &[i16] {
1987        // SAFETY: `_data`/`_count` describe one contiguous C++
1988        // allocation, borrowed for as long as `self` is.
1989        unsafe {
1990            let n = ffi::whiteout_m2_M2PhysicsCollision_get_flags_count(self.raw.as_ptr());
1991            let p = ffi::whiteout_m2_M2PhysicsCollision_get_flags_data(self.raw.as_ptr());
1992            if p.is_null() || n == 0 {
1993                &[]
1994            } else {
1995                core::slice::from_raw_parts(p, n)
1996            }
1997        }
1998    }
1999
2000    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
2001    pub fn flags_mut(&mut self) -> &mut [i16] {
2002        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
2003        unsafe {
2004            let n = ffi::whiteout_m2_M2PhysicsCollision_get_flags_count(self.raw.as_ptr());
2005            let p =
2006                ffi::whiteout_m2_M2PhysicsCollision_get_flags_data(self.raw.as_ptr()) as *mut i16;
2007            if p.is_null() || n == 0 {
2008                &mut []
2009            } else {
2010                core::slice::from_raw_parts_mut(p, n)
2011            }
2012        }
2013    }
2014
2015    pub fn set_flags(&mut self, values: &[i16]) {
2016        // SAFETY: the native side copies `values` before returning.
2017        unsafe {
2018            ffi::whiteout_m2_M2PhysicsCollision_assign_flags(
2019                self.raw.as_ptr(),
2020                values.as_ptr() as *const _,
2021                values.len(),
2022            )
2023        }
2024    }
2025
2026    pub fn resize_flags(&mut self, count: usize) {
2027        // SAFETY: reallocation is safe here precisely because
2028        // `&mut self` means no slice borrow is outstanding.
2029        unsafe { ffi::whiteout_m2_M2PhysicsCollision_resize_flags(self.raw.as_ptr(), count) }
2030    }
2031}
2032
2033impl Default for PhysicsCollision {
2034    fn default() -> Self {
2035        Self::new()
2036    }
2037}
2038
2039pub struct SkinSection {
2040    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2SkinSection>,
2041}
2042
2043impl Drop for SkinSection {
2044    fn drop(&mut self) {
2045        // SAFETY: `raw` came from a native constructor and Drop runs once.
2046        unsafe { ffi::whiteout_m2_M2SkinSection_delete(self.raw.as_ptr()) }
2047    }
2048}
2049
2050impl SkinSection {
2051    /// # Safety
2052    /// `raw` must be a live handle this value takes ownership of.
2053    #[allow(dead_code)] // used by whichever methods return this type
2054    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2SkinSection) -> Option<Self> {
2055        core::ptr::NonNull::new(raw).map(|raw| SkinSection { raw })
2056    }
2057}
2058
2059// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
2060// is deliberately NOT implemented — the C++ types make no documented
2061// guarantee about concurrent use, and claiming one we haven't verified
2062// would be unsound. See `@bind thread_safe` in the plan.
2063unsafe impl Send for SkinSection {}
2064
2065impl core::fmt::Debug for SkinSection {
2066    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2067        f.debug_struct("SkinSection").finish_non_exhaustive()
2068    }
2069}
2070
2071impl SkinSection {
2072    /// # Panics
2073    /// Panics if the native allocation fails.
2074    pub fn new() -> Self {
2075        // SAFETY: the native constructor returns a live handle; a null here
2076        // means the library is unusable.
2077        unsafe {
2078            let raw = ffi::whiteout_m2_M2SkinSection_new();
2079            Self::from_raw(raw).expect("native SkinSection allocation failed")
2080        }
2081    }
2082
2083    pub fn skin_section_id(&self) -> u16 {
2084        // SAFETY: plain scalar read through a live handle.
2085        unsafe { ffi::whiteout_m2_M2SkinSection_get_skinSectionId(self.raw.as_ptr()) }
2086    }
2087
2088    pub fn set_skin_section_id(&mut self, value: u16) {
2089        // SAFETY: plain scalar write through a live handle.
2090        unsafe { ffi::whiteout_m2_M2SkinSection_set_skinSectionId(self.raw.as_ptr(), value) }
2091    }
2092
2093    pub fn level(&self) -> u16 {
2094        // SAFETY: plain scalar read through a live handle.
2095        unsafe { ffi::whiteout_m2_M2SkinSection_get_level(self.raw.as_ptr()) }
2096    }
2097
2098    pub fn set_level(&mut self, value: u16) {
2099        // SAFETY: plain scalar write through a live handle.
2100        unsafe { ffi::whiteout_m2_M2SkinSection_set_level(self.raw.as_ptr(), value) }
2101    }
2102
2103    pub fn vertex_start(&self) -> u16 {
2104        // SAFETY: plain scalar read through a live handle.
2105        unsafe { ffi::whiteout_m2_M2SkinSection_get_vertexStart(self.raw.as_ptr()) }
2106    }
2107
2108    pub fn set_vertex_start(&mut self, value: u16) {
2109        // SAFETY: plain scalar write through a live handle.
2110        unsafe { ffi::whiteout_m2_M2SkinSection_set_vertexStart(self.raw.as_ptr(), value) }
2111    }
2112
2113    pub fn vertex_count(&self) -> u16 {
2114        // SAFETY: plain scalar read through a live handle.
2115        unsafe { ffi::whiteout_m2_M2SkinSection_get_vertexCount(self.raw.as_ptr()) }
2116    }
2117
2118    pub fn set_vertex_count(&mut self, value: u16) {
2119        // SAFETY: plain scalar write through a live handle.
2120        unsafe { ffi::whiteout_m2_M2SkinSection_set_vertexCount(self.raw.as_ptr(), value) }
2121    }
2122
2123    pub fn index_start(&self) -> u16 {
2124        // SAFETY: plain scalar read through a live handle.
2125        unsafe { ffi::whiteout_m2_M2SkinSection_get_indexStart(self.raw.as_ptr()) }
2126    }
2127
2128    pub fn set_index_start(&mut self, value: u16) {
2129        // SAFETY: plain scalar write through a live handle.
2130        unsafe { ffi::whiteout_m2_M2SkinSection_set_indexStart(self.raw.as_ptr(), value) }
2131    }
2132
2133    pub fn index_count(&self) -> u16 {
2134        // SAFETY: plain scalar read through a live handle.
2135        unsafe { ffi::whiteout_m2_M2SkinSection_get_indexCount(self.raw.as_ptr()) }
2136    }
2137
2138    pub fn set_index_count(&mut self, value: u16) {
2139        // SAFETY: plain scalar write through a live handle.
2140        unsafe { ffi::whiteout_m2_M2SkinSection_set_indexCount(self.raw.as_ptr(), value) }
2141    }
2142
2143    pub fn bone_count(&self) -> u16 {
2144        // SAFETY: plain scalar read through a live handle.
2145        unsafe { ffi::whiteout_m2_M2SkinSection_get_boneCount(self.raw.as_ptr()) }
2146    }
2147
2148    pub fn set_bone_count(&mut self, value: u16) {
2149        // SAFETY: plain scalar write through a live handle.
2150        unsafe { ffi::whiteout_m2_M2SkinSection_set_boneCount(self.raw.as_ptr(), value) }
2151    }
2152
2153    pub fn bone_combo_index(&self) -> u16 {
2154        // SAFETY: plain scalar read through a live handle.
2155        unsafe { ffi::whiteout_m2_M2SkinSection_get_boneComboIndex(self.raw.as_ptr()) }
2156    }
2157
2158    pub fn set_bone_combo_index(&mut self, value: u16) {
2159        // SAFETY: plain scalar write through a live handle.
2160        unsafe { ffi::whiteout_m2_M2SkinSection_set_boneComboIndex(self.raw.as_ptr(), value) }
2161    }
2162
2163    pub fn bone_influences(&self) -> u16 {
2164        // SAFETY: plain scalar read through a live handle.
2165        unsafe { ffi::whiteout_m2_M2SkinSection_get_boneInfluences(self.raw.as_ptr()) }
2166    }
2167
2168    pub fn set_bone_influences(&mut self, value: u16) {
2169        // SAFETY: plain scalar write through a live handle.
2170        unsafe { ffi::whiteout_m2_M2SkinSection_set_boneInfluences(self.raw.as_ptr(), value) }
2171    }
2172
2173    pub fn center_bone_index(&self) -> u16 {
2174        // SAFETY: plain scalar read through a live handle.
2175        unsafe { ffi::whiteout_m2_M2SkinSection_get_centerBoneIndex(self.raw.as_ptr()) }
2176    }
2177
2178    pub fn set_center_bone_index(&mut self, value: u16) {
2179        // SAFETY: plain scalar write through a live handle.
2180        unsafe { ffi::whiteout_m2_M2SkinSection_set_centerBoneIndex(self.raw.as_ptr(), value) }
2181    }
2182
2183    pub fn center_position(&self) -> crate::math::Vector3f {
2184        // SAFETY: the getter returns an interior pointer to a
2185        // layout-identical POD; we copy it out immediately.
2186        unsafe {
2187            *(ffi::whiteout_m2_M2SkinSection_get_centerPosition(self.raw.as_ptr())
2188                as *const crate::math::Vector3f)
2189        }
2190    }
2191
2192    pub fn set_center_position(&mut self, value: crate::math::Vector3f) {
2193        // SAFETY: as above, in the other direction.
2194        unsafe {
2195            ffi::whiteout_m2_M2SkinSection_set_centerPosition(
2196                self.raw.as_ptr(),
2197                &value as *const crate::math::Vector3f as *const _,
2198            )
2199        }
2200    }
2201
2202    pub fn sort_center_position(&self) -> crate::math::Vector3f {
2203        // SAFETY: the getter returns an interior pointer to a
2204        // layout-identical POD; we copy it out immediately.
2205        unsafe {
2206            *(ffi::whiteout_m2_M2SkinSection_get_sortCenterPosition(self.raw.as_ptr())
2207                as *const crate::math::Vector3f)
2208        }
2209    }
2210
2211    pub fn set_sort_center_position(&mut self, value: crate::math::Vector3f) {
2212        // SAFETY: as above, in the other direction.
2213        unsafe {
2214            ffi::whiteout_m2_M2SkinSection_set_sortCenterPosition(
2215                self.raw.as_ptr(),
2216                &value as *const crate::math::Vector3f as *const _,
2217            )
2218        }
2219    }
2220
2221    pub fn sort_radius(&self) -> f32 {
2222        // SAFETY: plain scalar read through a live handle.
2223        unsafe { ffi::whiteout_m2_M2SkinSection_get_sortRadius(self.raw.as_ptr()) }
2224    }
2225
2226    pub fn set_sort_radius(&mut self, value: f32) {
2227        // SAFETY: plain scalar write through a live handle.
2228        unsafe { ffi::whiteout_m2_M2SkinSection_set_sortRadius(self.raw.as_ptr(), value) }
2229    }
2230}
2231
2232impl Default for SkinSection {
2233    fn default() -> Self {
2234        Self::new()
2235    }
2236}
2237
2238pub struct Batch {
2239    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2Batch>,
2240}
2241
2242impl Drop for Batch {
2243    fn drop(&mut self) {
2244        // SAFETY: `raw` came from a native constructor and Drop runs once.
2245        unsafe { ffi::whiteout_m2_M2Batch_delete(self.raw.as_ptr()) }
2246    }
2247}
2248
2249impl Batch {
2250    /// # Safety
2251    /// `raw` must be a live handle this value takes ownership of.
2252    #[allow(dead_code)] // used by whichever methods return this type
2253    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2Batch) -> Option<Self> {
2254        core::ptr::NonNull::new(raw).map(|raw| Batch { raw })
2255    }
2256}
2257
2258// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
2259// is deliberately NOT implemented — the C++ types make no documented
2260// guarantee about concurrent use, and claiming one we haven't verified
2261// would be unsound. See `@bind thread_safe` in the plan.
2262unsafe impl Send for Batch {}
2263
2264impl core::fmt::Debug for Batch {
2265    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2266        f.debug_struct("Batch").finish_non_exhaustive()
2267    }
2268}
2269
2270impl Batch {
2271    /// # Panics
2272    /// Panics if the native allocation fails.
2273    pub fn new() -> Self {
2274        // SAFETY: the native constructor returns a live handle; a null here
2275        // means the library is unusable.
2276        unsafe {
2277            let raw = ffi::whiteout_m2_M2Batch_new();
2278            Self::from_raw(raw).expect("native Batch allocation failed")
2279        }
2280    }
2281
2282    pub fn flags(&self) -> u8 {
2283        // SAFETY: plain scalar read through a live handle.
2284        unsafe { ffi::whiteout_m2_M2Batch_get_flags(self.raw.as_ptr()) }
2285    }
2286
2287    pub fn set_flags(&mut self, value: u8) {
2288        // SAFETY: plain scalar write through a live handle.
2289        unsafe { ffi::whiteout_m2_M2Batch_set_flags(self.raw.as_ptr(), value) }
2290    }
2291
2292    pub fn priority_plane(&self) -> i8 {
2293        // SAFETY: plain scalar read through a live handle.
2294        unsafe { ffi::whiteout_m2_M2Batch_get_priorityPlane(self.raw.as_ptr()) }
2295    }
2296
2297    pub fn set_priority_plane(&mut self, value: i8) {
2298        // SAFETY: plain scalar write through a live handle.
2299        unsafe { ffi::whiteout_m2_M2Batch_set_priorityPlane(self.raw.as_ptr(), value) }
2300    }
2301
2302    pub fn shader_id(&self) -> u16 {
2303        // SAFETY: plain scalar read through a live handle.
2304        unsafe { ffi::whiteout_m2_M2Batch_get_shaderId(self.raw.as_ptr()) }
2305    }
2306
2307    pub fn set_shader_id(&mut self, value: u16) {
2308        // SAFETY: plain scalar write through a live handle.
2309        unsafe { ffi::whiteout_m2_M2Batch_set_shaderId(self.raw.as_ptr(), value) }
2310    }
2311
2312    pub fn skin_section_index(&self) -> u16 {
2313        // SAFETY: plain scalar read through a live handle.
2314        unsafe { ffi::whiteout_m2_M2Batch_get_skinSectionIndex(self.raw.as_ptr()) }
2315    }
2316
2317    pub fn set_skin_section_index(&mut self, value: u16) {
2318        // SAFETY: plain scalar write through a live handle.
2319        unsafe { ffi::whiteout_m2_M2Batch_set_skinSectionIndex(self.raw.as_ptr(), value) }
2320    }
2321
2322    pub fn geoset_index(&self) -> u16 {
2323        // SAFETY: plain scalar read through a live handle.
2324        unsafe { ffi::whiteout_m2_M2Batch_get_geosetIndex(self.raw.as_ptr()) }
2325    }
2326
2327    pub fn set_geoset_index(&mut self, value: u16) {
2328        // SAFETY: plain scalar write through a live handle.
2329        unsafe { ffi::whiteout_m2_M2Batch_set_geosetIndex(self.raw.as_ptr(), value) }
2330    }
2331
2332    pub fn color_index(&self) -> i16 {
2333        // SAFETY: plain scalar read through a live handle.
2334        unsafe { ffi::whiteout_m2_M2Batch_get_colorIndex(self.raw.as_ptr()) }
2335    }
2336
2337    pub fn set_color_index(&mut self, value: i16) {
2338        // SAFETY: plain scalar write through a live handle.
2339        unsafe { ffi::whiteout_m2_M2Batch_set_colorIndex(self.raw.as_ptr(), value) }
2340    }
2341
2342    pub fn material_index(&self) -> u16 {
2343        // SAFETY: plain scalar read through a live handle.
2344        unsafe { ffi::whiteout_m2_M2Batch_get_materialIndex(self.raw.as_ptr()) }
2345    }
2346
2347    pub fn set_material_index(&mut self, value: u16) {
2348        // SAFETY: plain scalar write through a live handle.
2349        unsafe { ffi::whiteout_m2_M2Batch_set_materialIndex(self.raw.as_ptr(), value) }
2350    }
2351
2352    pub fn material_layer(&self) -> u16 {
2353        // SAFETY: plain scalar read through a live handle.
2354        unsafe { ffi::whiteout_m2_M2Batch_get_materialLayer(self.raw.as_ptr()) }
2355    }
2356
2357    pub fn set_material_layer(&mut self, value: u16) {
2358        // SAFETY: plain scalar write through a live handle.
2359        unsafe { ffi::whiteout_m2_M2Batch_set_materialLayer(self.raw.as_ptr(), value) }
2360    }
2361
2362    pub fn texture_count(&self) -> u16 {
2363        // SAFETY: plain scalar read through a live handle.
2364        unsafe { ffi::whiteout_m2_M2Batch_get_textureCount(self.raw.as_ptr()) }
2365    }
2366
2367    pub fn set_texture_count(&mut self, value: u16) {
2368        // SAFETY: plain scalar write through a live handle.
2369        unsafe { ffi::whiteout_m2_M2Batch_set_textureCount(self.raw.as_ptr(), value) }
2370    }
2371
2372    pub fn texture_combo_index(&self) -> u16 {
2373        // SAFETY: plain scalar read through a live handle.
2374        unsafe { ffi::whiteout_m2_M2Batch_get_textureComboIndex(self.raw.as_ptr()) }
2375    }
2376
2377    pub fn set_texture_combo_index(&mut self, value: u16) {
2378        // SAFETY: plain scalar write through a live handle.
2379        unsafe { ffi::whiteout_m2_M2Batch_set_textureComboIndex(self.raw.as_ptr(), value) }
2380    }
2381
2382    pub fn texture_coord_combo_index(&self) -> u16 {
2383        // SAFETY: plain scalar read through a live handle.
2384        unsafe { ffi::whiteout_m2_M2Batch_get_textureCoordComboIndex(self.raw.as_ptr()) }
2385    }
2386
2387    pub fn set_texture_coord_combo_index(&mut self, value: u16) {
2388        // SAFETY: plain scalar write through a live handle.
2389        unsafe { ffi::whiteout_m2_M2Batch_set_textureCoordComboIndex(self.raw.as_ptr(), value) }
2390    }
2391
2392    pub fn texture_weight_combo_index(&self) -> u16 {
2393        // SAFETY: plain scalar read through a live handle.
2394        unsafe { ffi::whiteout_m2_M2Batch_get_textureWeightComboIndex(self.raw.as_ptr()) }
2395    }
2396
2397    pub fn set_texture_weight_combo_index(&mut self, value: u16) {
2398        // SAFETY: plain scalar write through a live handle.
2399        unsafe { ffi::whiteout_m2_M2Batch_set_textureWeightComboIndex(self.raw.as_ptr(), value) }
2400    }
2401
2402    pub fn texture_transform_combo_index(&self) -> u16 {
2403        // SAFETY: plain scalar read through a live handle.
2404        unsafe { ffi::whiteout_m2_M2Batch_get_textureTransformComboIndex(self.raw.as_ptr()) }
2405    }
2406
2407    pub fn set_texture_transform_combo_index(&mut self, value: u16) {
2408        // SAFETY: plain scalar write through a live handle.
2409        unsafe { ffi::whiteout_m2_M2Batch_set_textureTransformComboIndex(self.raw.as_ptr(), value) }
2410    }
2411}
2412
2413impl Default for Batch {
2414    fn default() -> Self {
2415        Self::new()
2416    }
2417}
2418
2419pub struct ShadowBatch {
2420    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2ShadowBatch>,
2421}
2422
2423impl Drop for ShadowBatch {
2424    fn drop(&mut self) {
2425        // SAFETY: `raw` came from a native constructor and Drop runs once.
2426        unsafe { ffi::whiteout_m2_M2ShadowBatch_delete(self.raw.as_ptr()) }
2427    }
2428}
2429
2430impl ShadowBatch {
2431    /// # Safety
2432    /// `raw` must be a live handle this value takes ownership of.
2433    #[allow(dead_code)] // used by whichever methods return this type
2434    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2ShadowBatch) -> Option<Self> {
2435        core::ptr::NonNull::new(raw).map(|raw| ShadowBatch { raw })
2436    }
2437}
2438
2439// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
2440// is deliberately NOT implemented — the C++ types make no documented
2441// guarantee about concurrent use, and claiming one we haven't verified
2442// would be unsound. See `@bind thread_safe` in the plan.
2443unsafe impl Send for ShadowBatch {}
2444
2445impl core::fmt::Debug for ShadowBatch {
2446    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2447        f.debug_struct("ShadowBatch").finish_non_exhaustive()
2448    }
2449}
2450
2451impl ShadowBatch {
2452    /// # Panics
2453    /// Panics if the native allocation fails.
2454    pub fn new() -> Self {
2455        // SAFETY: the native constructor returns a live handle; a null here
2456        // means the library is unusable.
2457        unsafe {
2458            let raw = ffi::whiteout_m2_M2ShadowBatch_new();
2459            Self::from_raw(raw).expect("native ShadowBatch allocation failed")
2460        }
2461    }
2462
2463    pub fn flags(&self) -> u8 {
2464        // SAFETY: plain scalar read through a live handle.
2465        unsafe { ffi::whiteout_m2_M2ShadowBatch_get_flags(self.raw.as_ptr()) }
2466    }
2467
2468    pub fn set_flags(&mut self, value: u8) {
2469        // SAFETY: plain scalar write through a live handle.
2470        unsafe { ffi::whiteout_m2_M2ShadowBatch_set_flags(self.raw.as_ptr(), value) }
2471    }
2472
2473    pub fn flags_2(&self) -> u8 {
2474        // SAFETY: plain scalar read through a live handle.
2475        unsafe { ffi::whiteout_m2_M2ShadowBatch_get_flags2(self.raw.as_ptr()) }
2476    }
2477
2478    pub fn set_flags_2(&mut self, value: u8) {
2479        // SAFETY: plain scalar write through a live handle.
2480        unsafe { ffi::whiteout_m2_M2ShadowBatch_set_flags2(self.raw.as_ptr(), value) }
2481    }
2482
2483    pub fn unknown_0(&self) -> u16 {
2484        // SAFETY: plain scalar read through a live handle.
2485        unsafe { ffi::whiteout_m2_M2ShadowBatch_get_unknown0(self.raw.as_ptr()) }
2486    }
2487
2488    pub fn set_unknown_0(&mut self, value: u16) {
2489        // SAFETY: plain scalar write through a live handle.
2490        unsafe { ffi::whiteout_m2_M2ShadowBatch_set_unknown0(self.raw.as_ptr(), value) }
2491    }
2492
2493    pub fn submesh_id(&self) -> u16 {
2494        // SAFETY: plain scalar read through a live handle.
2495        unsafe { ffi::whiteout_m2_M2ShadowBatch_get_submeshId(self.raw.as_ptr()) }
2496    }
2497
2498    pub fn set_submesh_id(&mut self, value: u16) {
2499        // SAFETY: plain scalar write through a live handle.
2500        unsafe { ffi::whiteout_m2_M2ShadowBatch_set_submeshId(self.raw.as_ptr(), value) }
2501    }
2502
2503    pub fn texture_id(&self) -> u16 {
2504        // SAFETY: plain scalar read through a live handle.
2505        unsafe { ffi::whiteout_m2_M2ShadowBatch_get_textureId(self.raw.as_ptr()) }
2506    }
2507
2508    pub fn set_texture_id(&mut self, value: u16) {
2509        // SAFETY: plain scalar write through a live handle.
2510        unsafe { ffi::whiteout_m2_M2ShadowBatch_set_textureId(self.raw.as_ptr(), value) }
2511    }
2512
2513    pub fn color_id(&self) -> u16 {
2514        // SAFETY: plain scalar read through a live handle.
2515        unsafe { ffi::whiteout_m2_M2ShadowBatch_get_colorId(self.raw.as_ptr()) }
2516    }
2517
2518    pub fn set_color_id(&mut self, value: u16) {
2519        // SAFETY: plain scalar write through a live handle.
2520        unsafe { ffi::whiteout_m2_M2ShadowBatch_set_colorId(self.raw.as_ptr(), value) }
2521    }
2522
2523    pub fn transparency_id(&self) -> u16 {
2524        // SAFETY: plain scalar read through a live handle.
2525        unsafe { ffi::whiteout_m2_M2ShadowBatch_get_transparencyId(self.raw.as_ptr()) }
2526    }
2527
2528    pub fn set_transparency_id(&mut self, value: u16) {
2529        // SAFETY: plain scalar write through a live handle.
2530        unsafe { ffi::whiteout_m2_M2ShadowBatch_set_transparencyId(self.raw.as_ptr(), value) }
2531    }
2532}
2533
2534impl Default for ShadowBatch {
2535    fn default() -> Self {
2536        Self::new()
2537    }
2538}
2539
2540pub struct SkinProfile {
2541    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2SkinProfile>,
2542}
2543
2544impl Drop for SkinProfile {
2545    fn drop(&mut self) {
2546        // SAFETY: `raw` came from a native constructor and Drop runs once.
2547        unsafe { ffi::whiteout_m2_M2SkinProfile_delete(self.raw.as_ptr()) }
2548    }
2549}
2550
2551impl SkinProfile {
2552    /// # Safety
2553    /// `raw` must be a live handle this value takes ownership of.
2554    #[allow(dead_code)] // used by whichever methods return this type
2555    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2SkinProfile) -> Option<Self> {
2556        core::ptr::NonNull::new(raw).map(|raw| SkinProfile { raw })
2557    }
2558}
2559
2560// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
2561// is deliberately NOT implemented — the C++ types make no documented
2562// guarantee about concurrent use, and claiming one we haven't verified
2563// would be unsound. See `@bind thread_safe` in the plan.
2564unsafe impl Send for SkinProfile {}
2565
2566impl core::fmt::Debug for SkinProfile {
2567    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2568        f.debug_struct("SkinProfile").finish_non_exhaustive()
2569    }
2570}
2571
2572impl SkinProfile {
2573    /// # Panics
2574    /// Panics if the native allocation fails.
2575    pub fn new() -> Self {
2576        // SAFETY: the native constructor returns a live handle; a null here
2577        // means the library is unusable.
2578        unsafe {
2579            let raw = ffi::whiteout_m2_M2SkinProfile_new();
2580            Self::from_raw(raw).expect("native SkinProfile allocation failed")
2581        }
2582    }
2583
2584    /// Zero-copy view of the underlying `std::vector`.
2585    pub fn vertices(&self) -> &[u16] {
2586        // SAFETY: `_data`/`_count` describe one contiguous C++
2587        // allocation, borrowed for as long as `self` is.
2588        unsafe {
2589            let n = ffi::whiteout_m2_M2SkinProfile_get_vertices_count(self.raw.as_ptr());
2590            let p = ffi::whiteout_m2_M2SkinProfile_get_vertices_data(self.raw.as_ptr());
2591            if p.is_null() || n == 0 {
2592                &[]
2593            } else {
2594                core::slice::from_raw_parts(p, n)
2595            }
2596        }
2597    }
2598
2599    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
2600    pub fn vertices_mut(&mut self) -> &mut [u16] {
2601        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
2602        unsafe {
2603            let n = ffi::whiteout_m2_M2SkinProfile_get_vertices_count(self.raw.as_ptr());
2604            let p = ffi::whiteout_m2_M2SkinProfile_get_vertices_data(self.raw.as_ptr()) as *mut u16;
2605            if p.is_null() || n == 0 {
2606                &mut []
2607            } else {
2608                core::slice::from_raw_parts_mut(p, n)
2609            }
2610        }
2611    }
2612
2613    pub fn set_vertices(&mut self, values: &[u16]) {
2614        // SAFETY: the native side copies `values` before returning.
2615        unsafe {
2616            ffi::whiteout_m2_M2SkinProfile_assign_vertices(
2617                self.raw.as_ptr(),
2618                values.as_ptr() as *const _,
2619                values.len(),
2620            )
2621        }
2622    }
2623
2624    pub fn resize_vertices(&mut self, count: usize) {
2625        // SAFETY: reallocation is safe here precisely because
2626        // `&mut self` means no slice borrow is outstanding.
2627        unsafe { ffi::whiteout_m2_M2SkinProfile_resize_vertices(self.raw.as_ptr(), count) }
2628    }
2629
2630    /// Zero-copy view of the underlying `std::vector`.
2631    pub fn indices(&self) -> &[u16] {
2632        // SAFETY: `_data`/`_count` describe one contiguous C++
2633        // allocation, borrowed for as long as `self` is.
2634        unsafe {
2635            let n = ffi::whiteout_m2_M2SkinProfile_get_indices_count(self.raw.as_ptr());
2636            let p = ffi::whiteout_m2_M2SkinProfile_get_indices_data(self.raw.as_ptr());
2637            if p.is_null() || n == 0 {
2638                &[]
2639            } else {
2640                core::slice::from_raw_parts(p, n)
2641            }
2642        }
2643    }
2644
2645    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
2646    pub fn indices_mut(&mut self) -> &mut [u16] {
2647        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
2648        unsafe {
2649            let n = ffi::whiteout_m2_M2SkinProfile_get_indices_count(self.raw.as_ptr());
2650            let p = ffi::whiteout_m2_M2SkinProfile_get_indices_data(self.raw.as_ptr()) as *mut u16;
2651            if p.is_null() || n == 0 {
2652                &mut []
2653            } else {
2654                core::slice::from_raw_parts_mut(p, n)
2655            }
2656        }
2657    }
2658
2659    pub fn set_indices(&mut self, values: &[u16]) {
2660        // SAFETY: the native side copies `values` before returning.
2661        unsafe {
2662            ffi::whiteout_m2_M2SkinProfile_assign_indices(
2663                self.raw.as_ptr(),
2664                values.as_ptr() as *const _,
2665                values.len(),
2666            )
2667        }
2668    }
2669
2670    pub fn resize_indices(&mut self, count: usize) {
2671        // SAFETY: reallocation is safe here precisely because
2672        // `&mut self` means no slice borrow is outstanding.
2673        unsafe { ffi::whiteout_m2_M2SkinProfile_resize_indices(self.raw.as_ptr(), count) }
2674    }
2675
2676    pub fn submeshes_len(&self) -> usize {
2677        // SAFETY: scalar read through a live handle.
2678        unsafe { ffi::whiteout_m2_M2SkinProfile_get_submeshes_count(self.raw.as_ptr()) }
2679    }
2680
2681    /// Borrows element `index` in place. `None` when out of range.
2682    pub fn submeshes(&self, index: usize) -> Option<crate::support::Ref<'_, SkinSection>> {
2683        if index >= self.submeshes_len() {
2684            return None;
2685        }
2686        // SAFETY: index checked above; the pointer is interior to `self`.
2687        unsafe {
2688            Some(crate::support::Ref::new(SkinSection {
2689                raw: core::ptr::NonNull::new_unchecked(
2690                    ffi::whiteout_m2_M2SkinProfile_get_submeshes_at(self.raw.as_ptr(), index),
2691                ),
2692            }))
2693        }
2694    }
2695
2696    pub fn submeshes_mut(
2697        &mut self,
2698        index: usize,
2699    ) -> Option<crate::support::RefMut<'_, SkinSection>> {
2700        if index >= self.submeshes_len() {
2701            return None;
2702        }
2703        // SAFETY: as above; `&mut self` guarantees exclusivity.
2704        unsafe {
2705            Some(crate::support::RefMut::new(SkinSection {
2706                raw: core::ptr::NonNull::new_unchecked(
2707                    ffi::whiteout_m2_M2SkinProfile_get_submeshes_at(self.raw.as_ptr(), index),
2708                ),
2709            }))
2710        }
2711    }
2712
2713    /// Iterate the elements, borrowing each in turn.
2714    pub fn submeshes_iter(
2715        &self,
2716    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, SkinSection>> {
2717        (0..self.submeshes_len()).map(move |i| self.submeshes(i).expect("index below len"))
2718    }
2719
2720    pub fn resize_submeshes(&mut self, count: usize) {
2721        // SAFETY: exclusive access, so no borrow is outstanding.
2722        unsafe { ffi::whiteout_m2_M2SkinProfile_resize_submeshes(self.raw.as_ptr(), count) }
2723    }
2724
2725    pub fn batches_len(&self) -> usize {
2726        // SAFETY: scalar read through a live handle.
2727        unsafe { ffi::whiteout_m2_M2SkinProfile_get_batches_count(self.raw.as_ptr()) }
2728    }
2729
2730    /// Borrows element `index` in place. `None` when out of range.
2731    pub fn batches(&self, index: usize) -> Option<crate::support::Ref<'_, Batch>> {
2732        if index >= self.batches_len() {
2733            return None;
2734        }
2735        // SAFETY: index checked above; the pointer is interior to `self`.
2736        unsafe {
2737            Some(crate::support::Ref::new(Batch {
2738                raw: core::ptr::NonNull::new_unchecked(
2739                    ffi::whiteout_m2_M2SkinProfile_get_batches_at(self.raw.as_ptr(), index),
2740                ),
2741            }))
2742        }
2743    }
2744
2745    pub fn batches_mut(&mut self, index: usize) -> Option<crate::support::RefMut<'_, Batch>> {
2746        if index >= self.batches_len() {
2747            return None;
2748        }
2749        // SAFETY: as above; `&mut self` guarantees exclusivity.
2750        unsafe {
2751            Some(crate::support::RefMut::new(Batch {
2752                raw: core::ptr::NonNull::new_unchecked(
2753                    ffi::whiteout_m2_M2SkinProfile_get_batches_at(self.raw.as_ptr(), index),
2754                ),
2755            }))
2756        }
2757    }
2758
2759    /// Iterate the elements, borrowing each in turn.
2760    pub fn batches_iter(&self) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, Batch>> {
2761        (0..self.batches_len()).map(move |i| self.batches(i).expect("index below len"))
2762    }
2763
2764    pub fn resize_batches(&mut self, count: usize) {
2765        // SAFETY: exclusive access, so no borrow is outstanding.
2766        unsafe { ffi::whiteout_m2_M2SkinProfile_resize_batches(self.raw.as_ptr(), count) }
2767    }
2768
2769    pub fn lod_vertex_base(&self) -> u32 {
2770        // SAFETY: plain scalar read through a live handle.
2771        unsafe { ffi::whiteout_m2_M2SkinProfile_get_lodVertexBase(self.raw.as_ptr()) }
2772    }
2773
2774    pub fn set_lod_vertex_base(&mut self, value: u32) {
2775        // SAFETY: plain scalar write through a live handle.
2776        unsafe { ffi::whiteout_m2_M2SkinProfile_set_lodVertexBase(self.raw.as_ptr(), value) }
2777    }
2778
2779    pub fn shadow_batches_len(&self) -> usize {
2780        // SAFETY: scalar read through a live handle.
2781        unsafe { ffi::whiteout_m2_M2SkinProfile_get_shadowBatches_count(self.raw.as_ptr()) }
2782    }
2783
2784    /// Borrows element `index` in place. `None` when out of range.
2785    pub fn shadow_batches(&self, index: usize) -> Option<crate::support::Ref<'_, ShadowBatch>> {
2786        if index >= self.shadow_batches_len() {
2787            return None;
2788        }
2789        // SAFETY: index checked above; the pointer is interior to `self`.
2790        unsafe {
2791            Some(crate::support::Ref::new(ShadowBatch {
2792                raw: core::ptr::NonNull::new_unchecked(
2793                    ffi::whiteout_m2_M2SkinProfile_get_shadowBatches_at(self.raw.as_ptr(), index),
2794                ),
2795            }))
2796        }
2797    }
2798
2799    pub fn shadow_batches_mut(
2800        &mut self,
2801        index: usize,
2802    ) -> Option<crate::support::RefMut<'_, ShadowBatch>> {
2803        if index >= self.shadow_batches_len() {
2804            return None;
2805        }
2806        // SAFETY: as above; `&mut self` guarantees exclusivity.
2807        unsafe {
2808            Some(crate::support::RefMut::new(ShadowBatch {
2809                raw: core::ptr::NonNull::new_unchecked(
2810                    ffi::whiteout_m2_M2SkinProfile_get_shadowBatches_at(self.raw.as_ptr(), index),
2811                ),
2812            }))
2813        }
2814    }
2815
2816    /// Iterate the elements, borrowing each in turn.
2817    pub fn shadow_batches_iter(
2818        &self,
2819    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, ShadowBatch>> {
2820        (0..self.shadow_batches_len())
2821            .map(move |i| self.shadow_batches(i).expect("index below len"))
2822    }
2823
2824    pub fn resize_shadow_batches(&mut self, count: usize) {
2825        // SAFETY: exclusive access, so no borrow is outstanding.
2826        unsafe { ffi::whiteout_m2_M2SkinProfile_resize_shadowBatches(self.raw.as_ptr(), count) }
2827    }
2828}
2829
2830impl Default for SkinProfile {
2831    fn default() -> Self {
2832        Self::new()
2833    }
2834}
2835
2836pub struct GlobalFlags {
2837    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2GlobalFlags>,
2838}
2839
2840impl Drop for GlobalFlags {
2841    fn drop(&mut self) {
2842        // SAFETY: `raw` came from a native constructor and Drop runs once.
2843        unsafe { ffi::whiteout_m2_M2GlobalFlags_delete(self.raw.as_ptr()) }
2844    }
2845}
2846
2847impl GlobalFlags {
2848    /// # Safety
2849    /// `raw` must be a live handle this value takes ownership of.
2850    #[allow(dead_code)] // used by whichever methods return this type
2851    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2GlobalFlags) -> Option<Self> {
2852        core::ptr::NonNull::new(raw).map(|raw| GlobalFlags { raw })
2853    }
2854}
2855
2856// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
2857// is deliberately NOT implemented — the C++ types make no documented
2858// guarantee about concurrent use, and claiming one we haven't verified
2859// would be unsound. See `@bind thread_safe` in the plan.
2860unsafe impl Send for GlobalFlags {}
2861
2862impl core::fmt::Debug for GlobalFlags {
2863    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2864        f.debug_struct("GlobalFlags").finish_non_exhaustive()
2865    }
2866}
2867
2868impl GlobalFlags {
2869    /// # Panics
2870    /// Panics if the native allocation fails.
2871    pub fn new() -> Self {
2872        // SAFETY: the native constructor returns a live handle; a null here
2873        // means the library is unusable.
2874        unsafe {
2875            let raw = ffi::whiteout_m2_M2GlobalFlags_new();
2876            Self::from_raw(raw).expect("native GlobalFlags allocation failed")
2877        }
2878    }
2879
2880    pub fn value(&self) -> GlobalFlag {
2881        // SAFETY: scalar read; a flag set accepts any bits.
2882        GlobalFlag(unsafe { ffi::whiteout_m2_M2GlobalFlags_get_value(self.raw.as_ptr()) })
2883    }
2884
2885    pub fn set_value(&mut self, value: GlobalFlag) {
2886        // SAFETY: scalar write through a live handle.
2887        unsafe { ffi::whiteout_m2_M2GlobalFlags_set_value(self.raw.as_ptr(), value.0) }
2888    }
2889}
2890
2891impl Default for GlobalFlags {
2892    fn default() -> Self {
2893        Self::new()
2894    }
2895}
2896
2897pub struct GlobalSequence {
2898    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2GlobalSequence>,
2899}
2900
2901impl Drop for GlobalSequence {
2902    fn drop(&mut self) {
2903        // SAFETY: `raw` came from a native constructor and Drop runs once.
2904        unsafe { ffi::whiteout_m2_M2GlobalSequence_delete(self.raw.as_ptr()) }
2905    }
2906}
2907
2908impl GlobalSequence {
2909    /// # Safety
2910    /// `raw` must be a live handle this value takes ownership of.
2911    #[allow(dead_code)] // used by whichever methods return this type
2912    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2GlobalSequence) -> Option<Self> {
2913        core::ptr::NonNull::new(raw).map(|raw| GlobalSequence { raw })
2914    }
2915}
2916
2917// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
2918// is deliberately NOT implemented — the C++ types make no documented
2919// guarantee about concurrent use, and claiming one we haven't verified
2920// would be unsound. See `@bind thread_safe` in the plan.
2921unsafe impl Send for GlobalSequence {}
2922
2923impl core::fmt::Debug for GlobalSequence {
2924    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2925        f.debug_struct("GlobalSequence").finish_non_exhaustive()
2926    }
2927}
2928
2929impl GlobalSequence {
2930    /// # Panics
2931    /// Panics if the native allocation fails.
2932    pub fn new() -> Self {
2933        // SAFETY: the native constructor returns a live handle; a null here
2934        // means the library is unusable.
2935        unsafe {
2936            let raw = ffi::whiteout_m2_M2GlobalSequence_new();
2937            Self::from_raw(raw).expect("native GlobalSequence allocation failed")
2938        }
2939    }
2940
2941    pub fn timestamp(&self) -> u32 {
2942        // SAFETY: plain scalar read through a live handle.
2943        unsafe { ffi::whiteout_m2_M2GlobalSequence_get_timestamp(self.raw.as_ptr()) }
2944    }
2945
2946    pub fn set_timestamp(&mut self, value: u32) {
2947        // SAFETY: plain scalar write through a live handle.
2948        unsafe { ffi::whiteout_m2_M2GlobalSequence_set_timestamp(self.raw.as_ptr(), value) }
2949    }
2950}
2951
2952impl Default for GlobalSequence {
2953    fn default() -> Self {
2954        Self::new()
2955    }
2956}
2957
2958pub struct Sequence {
2959    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2Sequence>,
2960}
2961
2962impl Drop for Sequence {
2963    fn drop(&mut self) {
2964        // SAFETY: `raw` came from a native constructor and Drop runs once.
2965        unsafe { ffi::whiteout_m2_M2Sequence_delete(self.raw.as_ptr()) }
2966    }
2967}
2968
2969impl Sequence {
2970    /// # Safety
2971    /// `raw` must be a live handle this value takes ownership of.
2972    #[allow(dead_code)] // used by whichever methods return this type
2973    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2Sequence) -> Option<Self> {
2974        core::ptr::NonNull::new(raw).map(|raw| Sequence { raw })
2975    }
2976}
2977
2978// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
2979// is deliberately NOT implemented — the C++ types make no documented
2980// guarantee about concurrent use, and claiming one we haven't verified
2981// would be unsound. See `@bind thread_safe` in the plan.
2982unsafe impl Send for Sequence {}
2983
2984impl core::fmt::Debug for Sequence {
2985    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2986        f.debug_struct("Sequence").finish_non_exhaustive()
2987    }
2988}
2989
2990impl Sequence {
2991    /// # Panics
2992    /// Panics if the native allocation fails.
2993    pub fn new() -> Self {
2994        // SAFETY: the native constructor returns a live handle; a null here
2995        // means the library is unusable.
2996        unsafe {
2997            let raw = ffi::whiteout_m2_M2Sequence_new();
2998            Self::from_raw(raw).expect("native Sequence allocation failed")
2999        }
3000    }
3001
3002    pub fn id(&self) -> u16 {
3003        // SAFETY: plain scalar read through a live handle.
3004        unsafe { ffi::whiteout_m2_M2Sequence_get_id(self.raw.as_ptr()) }
3005    }
3006
3007    pub fn set_id(&mut self, value: u16) {
3008        // SAFETY: plain scalar write through a live handle.
3009        unsafe { ffi::whiteout_m2_M2Sequence_set_id(self.raw.as_ptr(), value) }
3010    }
3011
3012    pub fn variation_index(&self) -> u16 {
3013        // SAFETY: plain scalar read through a live handle.
3014        unsafe { ffi::whiteout_m2_M2Sequence_get_variationIndex(self.raw.as_ptr()) }
3015    }
3016
3017    pub fn set_variation_index(&mut self, value: u16) {
3018        // SAFETY: plain scalar write through a live handle.
3019        unsafe { ffi::whiteout_m2_M2Sequence_set_variationIndex(self.raw.as_ptr(), value) }
3020    }
3021
3022    pub fn duration(&self) -> u32 {
3023        // SAFETY: plain scalar read through a live handle.
3024        unsafe { ffi::whiteout_m2_M2Sequence_get_duration(self.raw.as_ptr()) }
3025    }
3026
3027    pub fn set_duration(&mut self, value: u32) {
3028        // SAFETY: plain scalar write through a live handle.
3029        unsafe { ffi::whiteout_m2_M2Sequence_set_duration(self.raw.as_ptr(), value) }
3030    }
3031
3032    pub fn movespeed(&self) -> f32 {
3033        // SAFETY: plain scalar read through a live handle.
3034        unsafe { ffi::whiteout_m2_M2Sequence_get_movespeed(self.raw.as_ptr()) }
3035    }
3036
3037    pub fn set_movespeed(&mut self, value: f32) {
3038        // SAFETY: plain scalar write through a live handle.
3039        unsafe { ffi::whiteout_m2_M2Sequence_set_movespeed(self.raw.as_ptr(), value) }
3040    }
3041
3042    pub fn flags(&self) -> SequenceFlag {
3043        // SAFETY: scalar read; a flag set accepts any bits.
3044        SequenceFlag(unsafe { ffi::whiteout_m2_M2Sequence_get_flags(self.raw.as_ptr()) })
3045    }
3046
3047    pub fn set_flags(&mut self, value: SequenceFlag) {
3048        // SAFETY: scalar write through a live handle.
3049        unsafe { ffi::whiteout_m2_M2Sequence_set_flags(self.raw.as_ptr(), value.0) }
3050    }
3051
3052    pub fn frequency(&self) -> i16 {
3053        // SAFETY: plain scalar read through a live handle.
3054        unsafe { ffi::whiteout_m2_M2Sequence_get_frequency(self.raw.as_ptr()) }
3055    }
3056
3057    pub fn set_frequency(&mut self, value: i16) {
3058        // SAFETY: plain scalar write through a live handle.
3059        unsafe { ffi::whiteout_m2_M2Sequence_set_frequency(self.raw.as_ptr(), value) }
3060    }
3061
3062    pub fn padding(&self) -> u16 {
3063        // SAFETY: plain scalar read through a live handle.
3064        unsafe { ffi::whiteout_m2_M2Sequence_get_padding(self.raw.as_ptr()) }
3065    }
3066
3067    pub fn set_padding(&mut self, value: u16) {
3068        // SAFETY: plain scalar write through a live handle.
3069        unsafe { ffi::whiteout_m2_M2Sequence_set_padding(self.raw.as_ptr(), value) }
3070    }
3071
3072    pub fn replay_min(&self) -> u32 {
3073        // SAFETY: plain scalar read through a live handle.
3074        unsafe { ffi::whiteout_m2_M2Sequence_get_replayMin(self.raw.as_ptr()) }
3075    }
3076
3077    pub fn set_replay_min(&mut self, value: u32) {
3078        // SAFETY: plain scalar write through a live handle.
3079        unsafe { ffi::whiteout_m2_M2Sequence_set_replayMin(self.raw.as_ptr(), value) }
3080    }
3081
3082    pub fn replay_max(&self) -> u32 {
3083        // SAFETY: plain scalar read through a live handle.
3084        unsafe { ffi::whiteout_m2_M2Sequence_get_replayMax(self.raw.as_ptr()) }
3085    }
3086
3087    pub fn set_replay_max(&mut self, value: u32) {
3088        // SAFETY: plain scalar write through a live handle.
3089        unsafe { ffi::whiteout_m2_M2Sequence_set_replayMax(self.raw.as_ptr(), value) }
3090    }
3091
3092    pub fn blend_time_in(&self) -> u16 {
3093        // SAFETY: plain scalar read through a live handle.
3094        unsafe { ffi::whiteout_m2_M2Sequence_get_blendTimeIn(self.raw.as_ptr()) }
3095    }
3096
3097    pub fn set_blend_time_in(&mut self, value: u16) {
3098        // SAFETY: plain scalar write through a live handle.
3099        unsafe { ffi::whiteout_m2_M2Sequence_set_blendTimeIn(self.raw.as_ptr(), value) }
3100    }
3101
3102    pub fn blend_time_out(&self) -> u16 {
3103        // SAFETY: plain scalar read through a live handle.
3104        unsafe { ffi::whiteout_m2_M2Sequence_get_blendTimeOut(self.raw.as_ptr()) }
3105    }
3106
3107    pub fn set_blend_time_out(&mut self, value: u16) {
3108        // SAFETY: plain scalar write through a live handle.
3109        unsafe { ffi::whiteout_m2_M2Sequence_set_blendTimeOut(self.raw.as_ptr(), value) }
3110    }
3111
3112    /// Borrows the field in place — no copy, no allocation.
3113    pub fn bounding(&self) -> crate::support::Ref<'_, Extent> {
3114        // SAFETY: an interior pointer into `self`, valid for this
3115        // borrow and never freed by the `Ref`.
3116        unsafe {
3117            crate::support::Ref::new(Extent {
3118                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Sequence_get_bounding(
3119                    self.raw.as_ptr(),
3120                )),
3121            })
3122        }
3123    }
3124
3125    pub fn bounding_mut(&mut self) -> crate::support::RefMut<'_, Extent> {
3126        // SAFETY: as above; `&mut self` guarantees exclusivity.
3127        unsafe {
3128            crate::support::RefMut::new(Extent {
3129                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Sequence_get_bounding(
3130                    self.raw.as_ptr(),
3131                )),
3132            })
3133        }
3134    }
3135
3136    pub fn variation_next(&self) -> i16 {
3137        // SAFETY: plain scalar read through a live handle.
3138        unsafe { ffi::whiteout_m2_M2Sequence_get_variationNext(self.raw.as_ptr()) }
3139    }
3140
3141    pub fn set_variation_next(&mut self, value: i16) {
3142        // SAFETY: plain scalar write through a live handle.
3143        unsafe { ffi::whiteout_m2_M2Sequence_set_variationNext(self.raw.as_ptr(), value) }
3144    }
3145
3146    pub fn alias_next(&self) -> u16 {
3147        // SAFETY: plain scalar read through a live handle.
3148        unsafe { ffi::whiteout_m2_M2Sequence_get_aliasNext(self.raw.as_ptr()) }
3149    }
3150
3151    pub fn set_alias_next(&mut self, value: u16) {
3152        // SAFETY: plain scalar write through a live handle.
3153        unsafe { ffi::whiteout_m2_M2Sequence_set_aliasNext(self.raw.as_ptr(), value) }
3154    }
3155}
3156
3157impl Default for Sequence {
3158    fn default() -> Self {
3159        Self::new()
3160    }
3161}
3162
3163pub struct Vertex {
3164    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2Vertex>,
3165}
3166
3167impl Drop for Vertex {
3168    fn drop(&mut self) {
3169        // SAFETY: `raw` came from a native constructor and Drop runs once.
3170        unsafe { ffi::whiteout_m2_M2Vertex_delete(self.raw.as_ptr()) }
3171    }
3172}
3173
3174impl Vertex {
3175    /// # Safety
3176    /// `raw` must be a live handle this value takes ownership of.
3177    #[allow(dead_code)] // used by whichever methods return this type
3178    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2Vertex) -> Option<Self> {
3179        core::ptr::NonNull::new(raw).map(|raw| Vertex { raw })
3180    }
3181}
3182
3183// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
3184// is deliberately NOT implemented — the C++ types make no documented
3185// guarantee about concurrent use, and claiming one we haven't verified
3186// would be unsound. See `@bind thread_safe` in the plan.
3187unsafe impl Send for Vertex {}
3188
3189impl core::fmt::Debug for Vertex {
3190    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3191        f.debug_struct("Vertex").finish_non_exhaustive()
3192    }
3193}
3194
3195impl Vertex {
3196    /// # Panics
3197    /// Panics if the native allocation fails.
3198    pub fn new() -> Self {
3199        // SAFETY: the native constructor returns a live handle; a null here
3200        // means the library is unusable.
3201        unsafe {
3202            let raw = ffi::whiteout_m2_M2Vertex_new();
3203            Self::from_raw(raw).expect("native Vertex allocation failed")
3204        }
3205    }
3206
3207    pub fn position(&self) -> crate::math::Vector3f {
3208        // SAFETY: the getter returns an interior pointer to a
3209        // layout-identical POD; we copy it out immediately.
3210        unsafe {
3211            *(ffi::whiteout_m2_M2Vertex_get_position(self.raw.as_ptr())
3212                as *const crate::math::Vector3f)
3213        }
3214    }
3215
3216    pub fn set_position(&mut self, value: crate::math::Vector3f) {
3217        // SAFETY: as above, in the other direction.
3218        unsafe {
3219            ffi::whiteout_m2_M2Vertex_set_position(
3220                self.raw.as_ptr(),
3221                &value as *const crate::math::Vector3f as *const _,
3222            )
3223        }
3224    }
3225
3226    /// Number of elements — a fixed-size C++ array.
3227    pub const fn bone_weights_len() -> usize {
3228        4
3229    }
3230
3231    /// # Panics
3232    /// If `index >= 4`, matching Rust slice indexing.
3233    pub fn bone_weights(&self, index: usize) -> u8 {
3234        assert!(index < 4, "bone_weights index {index} out of range (len 4)");
3235        // SAFETY: index checked above; plain scalar read.
3236        unsafe { ffi::whiteout_m2_M2Vertex_get_boneWeights_at(self.raw.as_ptr(), index) }
3237    }
3238
3239    /// # Panics
3240    /// If `index >= 4`.
3241    pub fn set_bone_weights(&mut self, index: usize, value: u8) {
3242        assert!(index < 4, "bone_weights index {index} out of range (len 4)");
3243        // SAFETY: index checked above.
3244        unsafe { ffi::whiteout_m2_M2Vertex_set_boneWeights_at(self.raw.as_ptr(), index, value) }
3245    }
3246
3247    /// Number of elements — a fixed-size C++ array.
3248    pub const fn bone_indices_len() -> usize {
3249        4
3250    }
3251
3252    /// # Panics
3253    /// If `index >= 4`, matching Rust slice indexing.
3254    pub fn bone_indices(&self, index: usize) -> u8 {
3255        assert!(index < 4, "bone_indices index {index} out of range (len 4)");
3256        // SAFETY: index checked above; plain scalar read.
3257        unsafe { ffi::whiteout_m2_M2Vertex_get_boneIndices_at(self.raw.as_ptr(), index) }
3258    }
3259
3260    /// # Panics
3261    /// If `index >= 4`.
3262    pub fn set_bone_indices(&mut self, index: usize, value: u8) {
3263        assert!(index < 4, "bone_indices index {index} out of range (len 4)");
3264        // SAFETY: index checked above.
3265        unsafe { ffi::whiteout_m2_M2Vertex_set_boneIndices_at(self.raw.as_ptr(), index, value) }
3266    }
3267
3268    pub fn normal(&self) -> crate::math::Vector3f {
3269        // SAFETY: the getter returns an interior pointer to a
3270        // layout-identical POD; we copy it out immediately.
3271        unsafe {
3272            *(ffi::whiteout_m2_M2Vertex_get_normal(self.raw.as_ptr())
3273                as *const crate::math::Vector3f)
3274        }
3275    }
3276
3277    pub fn set_normal(&mut self, value: crate::math::Vector3f) {
3278        // SAFETY: as above, in the other direction.
3279        unsafe {
3280            ffi::whiteout_m2_M2Vertex_set_normal(
3281                self.raw.as_ptr(),
3282                &value as *const crate::math::Vector3f as *const _,
3283            )
3284        }
3285    }
3286
3287    /// Number of elements — a fixed-size C++ array.
3288    pub const fn tex_coords_len() -> usize {
3289        2
3290    }
3291
3292    /// # Panics
3293    /// If `index >= 2`, matching Rust slice indexing. The
3294    /// native accessor does no bounds checking of its own, so
3295    /// this check is what keeps the method safe to call.
3296    pub fn tex_coords(&self, index: usize) -> crate::math::Vector2f {
3297        assert!(index < 2, "tex_coords index {index} out of range (len 2)");
3298        // SAFETY: index checked above; the getter returns an
3299        // interior pointer to a layout-identical POD, copied
3300        // out immediately.
3301        unsafe {
3302            *(ffi::whiteout_m2_M2Vertex_get_texCoords_at(self.raw.as_ptr(), index)
3303                as *const crate::math::Vector2f)
3304        }
3305    }
3306}
3307
3308impl Default for Vertex {
3309    fn default() -> Self {
3310        Self::new()
3311    }
3312}
3313
3314pub struct Bone {
3315    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2Bone>,
3316}
3317
3318impl Drop for Bone {
3319    fn drop(&mut self) {
3320        // SAFETY: `raw` came from a native constructor and Drop runs once.
3321        unsafe { ffi::whiteout_m2_M2Bone_delete(self.raw.as_ptr()) }
3322    }
3323}
3324
3325impl Bone {
3326    /// # Safety
3327    /// `raw` must be a live handle this value takes ownership of.
3328    #[allow(dead_code)] // used by whichever methods return this type
3329    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2Bone) -> Option<Self> {
3330        core::ptr::NonNull::new(raw).map(|raw| Bone { raw })
3331    }
3332}
3333
3334// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
3335// is deliberately NOT implemented — the C++ types make no documented
3336// guarantee about concurrent use, and claiming one we haven't verified
3337// would be unsound. See `@bind thread_safe` in the plan.
3338unsafe impl Send for Bone {}
3339
3340impl core::fmt::Debug for Bone {
3341    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3342        f.debug_struct("Bone").finish_non_exhaustive()
3343    }
3344}
3345
3346impl Bone {
3347    /// # Panics
3348    /// Panics if the native allocation fails.
3349    pub fn new() -> Self {
3350        // SAFETY: the native constructor returns a live handle; a null here
3351        // means the library is unusable.
3352        unsafe {
3353            let raw = ffi::whiteout_m2_M2Bone_new();
3354            Self::from_raw(raw).expect("native Bone allocation failed")
3355        }
3356    }
3357
3358    pub fn key_bone_id(&self) -> i32 {
3359        // SAFETY: plain scalar read through a live handle.
3360        unsafe { ffi::whiteout_m2_M2Bone_get_keyBoneId(self.raw.as_ptr()) }
3361    }
3362
3363    pub fn set_key_bone_id(&mut self, value: i32) {
3364        // SAFETY: plain scalar write through a live handle.
3365        unsafe { ffi::whiteout_m2_M2Bone_set_keyBoneId(self.raw.as_ptr(), value) }
3366    }
3367
3368    pub fn flags(&self) -> u32 {
3369        // SAFETY: plain scalar read through a live handle.
3370        unsafe { ffi::whiteout_m2_M2Bone_get_flags(self.raw.as_ptr()) }
3371    }
3372
3373    pub fn set_flags(&mut self, value: u32) {
3374        // SAFETY: plain scalar write through a live handle.
3375        unsafe { ffi::whiteout_m2_M2Bone_set_flags(self.raw.as_ptr(), value) }
3376    }
3377
3378    pub fn parent_bone_id(&self) -> i16 {
3379        // SAFETY: plain scalar read through a live handle.
3380        unsafe { ffi::whiteout_m2_M2Bone_get_parentBoneId(self.raw.as_ptr()) }
3381    }
3382
3383    pub fn set_parent_bone_id(&mut self, value: i16) {
3384        // SAFETY: plain scalar write through a live handle.
3385        unsafe { ffi::whiteout_m2_M2Bone_set_parentBoneId(self.raw.as_ptr(), value) }
3386    }
3387
3388    pub fn submesh_id(&self) -> u16 {
3389        // SAFETY: plain scalar read through a live handle.
3390        unsafe { ffi::whiteout_m2_M2Bone_get_submeshId(self.raw.as_ptr()) }
3391    }
3392
3393    pub fn set_submesh_id(&mut self, value: u16) {
3394        // SAFETY: plain scalar write through a live handle.
3395        unsafe { ffi::whiteout_m2_M2Bone_set_submeshId(self.raw.as_ptr(), value) }
3396    }
3397
3398    pub fn bone_name_crc(&self) -> u32 {
3399        // SAFETY: plain scalar read through a live handle.
3400        unsafe { ffi::whiteout_m2_M2Bone_get_boneNameCRC(self.raw.as_ptr()) }
3401    }
3402
3403    pub fn set_bone_name_crc(&mut self, value: u32) {
3404        // SAFETY: plain scalar write through a live handle.
3405        unsafe { ffi::whiteout_m2_M2Bone_set_boneNameCRC(self.raw.as_ptr(), value) }
3406    }
3407
3408    /// Borrows the field in place — no copy, no allocation.
3409    pub fn translation(&self) -> crate::support::Ref<'_, AnimationTrackVector3f> {
3410        // SAFETY: an interior pointer into `self`, valid for this
3411        // borrow and never freed by the `Ref`.
3412        unsafe {
3413            crate::support::Ref::new(AnimationTrackVector3f {
3414                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Bone_get_translation(
3415                    self.raw.as_ptr(),
3416                )),
3417            })
3418        }
3419    }
3420
3421    pub fn translation_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackVector3f> {
3422        // SAFETY: as above; `&mut self` guarantees exclusivity.
3423        unsafe {
3424            crate::support::RefMut::new(AnimationTrackVector3f {
3425                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Bone_get_translation(
3426                    self.raw.as_ptr(),
3427                )),
3428            })
3429        }
3430    }
3431
3432    /// Borrows the field in place — no copy, no allocation.
3433    pub fn rotation(&self) -> crate::support::Ref<'_, AnimationTrackM2CompatQuaternion> {
3434        // SAFETY: an interior pointer into `self`, valid for this
3435        // borrow and never freed by the `Ref`.
3436        unsafe {
3437            crate::support::Ref::new(AnimationTrackM2CompatQuaternion {
3438                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Bone_get_rotation(
3439                    self.raw.as_ptr(),
3440                )),
3441            })
3442        }
3443    }
3444
3445    pub fn rotation_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackM2CompatQuaternion> {
3446        // SAFETY: as above; `&mut self` guarantees exclusivity.
3447        unsafe {
3448            crate::support::RefMut::new(AnimationTrackM2CompatQuaternion {
3449                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Bone_get_rotation(
3450                    self.raw.as_ptr(),
3451                )),
3452            })
3453        }
3454    }
3455
3456    /// Borrows the field in place — no copy, no allocation.
3457    pub fn scale(&self) -> crate::support::Ref<'_, AnimationTrackVector3f> {
3458        // SAFETY: an interior pointer into `self`, valid for this
3459        // borrow and never freed by the `Ref`.
3460        unsafe {
3461            crate::support::Ref::new(AnimationTrackVector3f {
3462                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Bone_get_scale(
3463                    self.raw.as_ptr(),
3464                )),
3465            })
3466        }
3467    }
3468
3469    pub fn scale_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackVector3f> {
3470        // SAFETY: as above; `&mut self` guarantees exclusivity.
3471        unsafe {
3472            crate::support::RefMut::new(AnimationTrackVector3f {
3473                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Bone_get_scale(
3474                    self.raw.as_ptr(),
3475                )),
3476            })
3477        }
3478    }
3479
3480    pub fn pivot(&self) -> crate::math::Vector3f {
3481        // SAFETY: the getter returns an interior pointer to a
3482        // layout-identical POD; we copy it out immediately.
3483        unsafe {
3484            *(ffi::whiteout_m2_M2Bone_get_pivot(self.raw.as_ptr()) as *const crate::math::Vector3f)
3485        }
3486    }
3487
3488    pub fn set_pivot(&mut self, value: crate::math::Vector3f) {
3489        // SAFETY: as above, in the other direction.
3490        unsafe {
3491            ffi::whiteout_m2_M2Bone_set_pivot(
3492                self.raw.as_ptr(),
3493                &value as *const crate::math::Vector3f as *const _,
3494            )
3495        }
3496    }
3497}
3498
3499impl Default for Bone {
3500    fn default() -> Self {
3501        Self::new()
3502    }
3503}
3504
3505pub struct Texture {
3506    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2Texture>,
3507}
3508
3509impl Drop for Texture {
3510    fn drop(&mut self) {
3511        // SAFETY: `raw` came from a native constructor and Drop runs once.
3512        unsafe { ffi::whiteout_m2_M2Texture_delete(self.raw.as_ptr()) }
3513    }
3514}
3515
3516impl Texture {
3517    /// # Safety
3518    /// `raw` must be a live handle this value takes ownership of.
3519    #[allow(dead_code)] // used by whichever methods return this type
3520    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2Texture) -> Option<Self> {
3521        core::ptr::NonNull::new(raw).map(|raw| Texture { raw })
3522    }
3523}
3524
3525// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
3526// is deliberately NOT implemented — the C++ types make no documented
3527// guarantee about concurrent use, and claiming one we haven't verified
3528// would be unsound. See `@bind thread_safe` in the plan.
3529unsafe impl Send for Texture {}
3530
3531impl core::fmt::Debug for Texture {
3532    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3533        f.debug_struct("Texture").finish_non_exhaustive()
3534    }
3535}
3536
3537impl Texture {
3538    /// # Panics
3539    /// Panics if the native allocation fails.
3540    pub fn new() -> Self {
3541        // SAFETY: the native constructor returns a live handle; a null here
3542        // means the library is unusable.
3543        unsafe {
3544            let raw = ffi::whiteout_m2_M2Texture_new();
3545            Self::from_raw(raw).expect("native Texture allocation failed")
3546        }
3547    }
3548
3549    pub fn type_(&self) -> u32 {
3550        // SAFETY: plain scalar read through a live handle.
3551        unsafe { ffi::whiteout_m2_M2Texture_get_type(self.raw.as_ptr()) }
3552    }
3553
3554    pub fn set_type_(&mut self, value: u32) {
3555        // SAFETY: plain scalar write through a live handle.
3556        unsafe { ffi::whiteout_m2_M2Texture_set_type(self.raw.as_ptr(), value) }
3557    }
3558
3559    pub fn flags(&self) -> u32 {
3560        // SAFETY: plain scalar read through a live handle.
3561        unsafe { ffi::whiteout_m2_M2Texture_get_flags(self.raw.as_ptr()) }
3562    }
3563
3564    pub fn set_flags(&mut self, value: u32) {
3565        // SAFETY: plain scalar write through a live handle.
3566        unsafe { ffi::whiteout_m2_M2Texture_set_flags(self.raw.as_ptr(), value) }
3567    }
3568
3569    pub fn filename(&self) -> String {
3570        // SAFETY: the native side hands over an owned CString.
3571        unsafe {
3572            crate::support::take_string(ffi::whiteout_m2_M2Texture_get_filename(self.raw.as_ptr()))
3573        }
3574    }
3575
3576    pub fn set_filename(&mut self, value: &str) {
3577        let value = std::ffi::CString::new(value).unwrap_or_default();
3578        // SAFETY: the pointer outlives the call.
3579        unsafe { ffi::whiteout_m2_M2Texture_set_filename(self.raw.as_ptr(), value.as_ptr()) }
3580    }
3581}
3582
3583impl Default for Texture {
3584    fn default() -> Self {
3585        Self::new()
3586    }
3587}
3588
3589pub struct Material {
3590    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2Material>,
3591}
3592
3593impl Drop for Material {
3594    fn drop(&mut self) {
3595        // SAFETY: `raw` came from a native constructor and Drop runs once.
3596        unsafe { ffi::whiteout_m2_M2Material_delete(self.raw.as_ptr()) }
3597    }
3598}
3599
3600impl Material {
3601    /// # Safety
3602    /// `raw` must be a live handle this value takes ownership of.
3603    #[allow(dead_code)] // used by whichever methods return this type
3604    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2Material) -> Option<Self> {
3605        core::ptr::NonNull::new(raw).map(|raw| Material { raw })
3606    }
3607}
3608
3609// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
3610// is deliberately NOT implemented — the C++ types make no documented
3611// guarantee about concurrent use, and claiming one we haven't verified
3612// would be unsound. See `@bind thread_safe` in the plan.
3613unsafe impl Send for Material {}
3614
3615impl core::fmt::Debug for Material {
3616    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3617        f.debug_struct("Material").finish_non_exhaustive()
3618    }
3619}
3620
3621impl Material {
3622    /// # Panics
3623    /// Panics if the native allocation fails.
3624    pub fn new() -> Self {
3625        // SAFETY: the native constructor returns a live handle; a null here
3626        // means the library is unusable.
3627        unsafe {
3628            let raw = ffi::whiteout_m2_M2Material_new();
3629            Self::from_raw(raw).expect("native Material allocation failed")
3630        }
3631    }
3632
3633    pub fn flags(&self) -> u16 {
3634        // SAFETY: plain scalar read through a live handle.
3635        unsafe { ffi::whiteout_m2_M2Material_get_flags(self.raw.as_ptr()) }
3636    }
3637
3638    pub fn set_flags(&mut self, value: u16) {
3639        // SAFETY: plain scalar write through a live handle.
3640        unsafe { ffi::whiteout_m2_M2Material_set_flags(self.raw.as_ptr(), value) }
3641    }
3642
3643    pub fn blending_mode(&self) -> u16 {
3644        // SAFETY: plain scalar read through a live handle.
3645        unsafe { ffi::whiteout_m2_M2Material_get_blendingMode(self.raw.as_ptr()) }
3646    }
3647
3648    pub fn set_blending_mode(&mut self, value: u16) {
3649        // SAFETY: plain scalar write through a live handle.
3650        unsafe { ffi::whiteout_m2_M2Material_set_blendingMode(self.raw.as_ptr(), value) }
3651    }
3652}
3653
3654impl Default for Material {
3655    fn default() -> Self {
3656        Self::new()
3657    }
3658}
3659
3660pub struct TextureWeight {
3661    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2TextureWeight>,
3662}
3663
3664impl Drop for TextureWeight {
3665    fn drop(&mut self) {
3666        // SAFETY: `raw` came from a native constructor and Drop runs once.
3667        unsafe { ffi::whiteout_m2_M2TextureWeight_delete(self.raw.as_ptr()) }
3668    }
3669}
3670
3671impl TextureWeight {
3672    /// # Safety
3673    /// `raw` must be a live handle this value takes ownership of.
3674    #[allow(dead_code)] // used by whichever methods return this type
3675    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2TextureWeight) -> Option<Self> {
3676        core::ptr::NonNull::new(raw).map(|raw| TextureWeight { raw })
3677    }
3678}
3679
3680// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
3681// is deliberately NOT implemented — the C++ types make no documented
3682// guarantee about concurrent use, and claiming one we haven't verified
3683// would be unsound. See `@bind thread_safe` in the plan.
3684unsafe impl Send for TextureWeight {}
3685
3686impl core::fmt::Debug for TextureWeight {
3687    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3688        f.debug_struct("TextureWeight").finish_non_exhaustive()
3689    }
3690}
3691
3692impl TextureWeight {
3693    /// # Panics
3694    /// Panics if the native allocation fails.
3695    pub fn new() -> Self {
3696        // SAFETY: the native constructor returns a live handle; a null here
3697        // means the library is unusable.
3698        unsafe {
3699            let raw = ffi::whiteout_m2_M2TextureWeight_new();
3700            Self::from_raw(raw).expect("native TextureWeight allocation failed")
3701        }
3702    }
3703
3704    /// Borrows the field in place — no copy, no allocation.
3705    pub fn weight(&self) -> crate::support::Ref<'_, AnimationTrackI16> {
3706        // SAFETY: an interior pointer into `self`, valid for this
3707        // borrow and never freed by the `Ref`.
3708        unsafe {
3709            crate::support::Ref::new(AnimationTrackI16 {
3710                raw: core::ptr::NonNull::new_unchecked(
3711                    ffi::whiteout_m2_M2TextureWeight_get_weight(self.raw.as_ptr()),
3712                ),
3713            })
3714        }
3715    }
3716
3717    pub fn weight_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackI16> {
3718        // SAFETY: as above; `&mut self` guarantees exclusivity.
3719        unsafe {
3720            crate::support::RefMut::new(AnimationTrackI16 {
3721                raw: core::ptr::NonNull::new_unchecked(
3722                    ffi::whiteout_m2_M2TextureWeight_get_weight(self.raw.as_ptr()),
3723                ),
3724            })
3725        }
3726    }
3727}
3728
3729impl Default for TextureWeight {
3730    fn default() -> Self {
3731        Self::new()
3732    }
3733}
3734
3735pub struct TextureTransform {
3736    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2TextureTransform>,
3737}
3738
3739impl Drop for TextureTransform {
3740    fn drop(&mut self) {
3741        // SAFETY: `raw` came from a native constructor and Drop runs once.
3742        unsafe { ffi::whiteout_m2_M2TextureTransform_delete(self.raw.as_ptr()) }
3743    }
3744}
3745
3746impl TextureTransform {
3747    /// # Safety
3748    /// `raw` must be a live handle this value takes ownership of.
3749    #[allow(dead_code)] // used by whichever methods return this type
3750    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2TextureTransform) -> Option<Self> {
3751        core::ptr::NonNull::new(raw).map(|raw| TextureTransform { raw })
3752    }
3753}
3754
3755// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
3756// is deliberately NOT implemented — the C++ types make no documented
3757// guarantee about concurrent use, and claiming one we haven't verified
3758// would be unsound. See `@bind thread_safe` in the plan.
3759unsafe impl Send for TextureTransform {}
3760
3761impl core::fmt::Debug for TextureTransform {
3762    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3763        f.debug_struct("TextureTransform").finish_non_exhaustive()
3764    }
3765}
3766
3767impl TextureTransform {
3768    /// # Panics
3769    /// Panics if the native allocation fails.
3770    pub fn new() -> Self {
3771        // SAFETY: the native constructor returns a live handle; a null here
3772        // means the library is unusable.
3773        unsafe {
3774            let raw = ffi::whiteout_m2_M2TextureTransform_new();
3775            Self::from_raw(raw).expect("native TextureTransform allocation failed")
3776        }
3777    }
3778
3779    /// Borrows the field in place — no copy, no allocation.
3780    pub fn translation(&self) -> crate::support::Ref<'_, AnimationTrackVector3f> {
3781        // SAFETY: an interior pointer into `self`, valid for this
3782        // borrow and never freed by the `Ref`.
3783        unsafe {
3784            crate::support::Ref::new(AnimationTrackVector3f {
3785                raw: core::ptr::NonNull::new_unchecked(
3786                    ffi::whiteout_m2_M2TextureTransform_get_translation(self.raw.as_ptr()),
3787                ),
3788            })
3789        }
3790    }
3791
3792    pub fn translation_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackVector3f> {
3793        // SAFETY: as above; `&mut self` guarantees exclusivity.
3794        unsafe {
3795            crate::support::RefMut::new(AnimationTrackVector3f {
3796                raw: core::ptr::NonNull::new_unchecked(
3797                    ffi::whiteout_m2_M2TextureTransform_get_translation(self.raw.as_ptr()),
3798                ),
3799            })
3800        }
3801    }
3802
3803    /// Borrows the field in place — no copy, no allocation.
3804    pub fn rotation(&self) -> crate::support::Ref<'_, AnimationTrackM2CompatQuaternion> {
3805        // SAFETY: an interior pointer into `self`, valid for this
3806        // borrow and never freed by the `Ref`.
3807        unsafe {
3808            crate::support::Ref::new(AnimationTrackM2CompatQuaternion {
3809                raw: core::ptr::NonNull::new_unchecked(
3810                    ffi::whiteout_m2_M2TextureTransform_get_rotation(self.raw.as_ptr()),
3811                ),
3812            })
3813        }
3814    }
3815
3816    pub fn rotation_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackM2CompatQuaternion> {
3817        // SAFETY: as above; `&mut self` guarantees exclusivity.
3818        unsafe {
3819            crate::support::RefMut::new(AnimationTrackM2CompatQuaternion {
3820                raw: core::ptr::NonNull::new_unchecked(
3821                    ffi::whiteout_m2_M2TextureTransform_get_rotation(self.raw.as_ptr()),
3822                ),
3823            })
3824        }
3825    }
3826
3827    /// Borrows the field in place — no copy, no allocation.
3828    pub fn scaling(&self) -> crate::support::Ref<'_, AnimationTrackVector3f> {
3829        // SAFETY: an interior pointer into `self`, valid for this
3830        // borrow and never freed by the `Ref`.
3831        unsafe {
3832            crate::support::Ref::new(AnimationTrackVector3f {
3833                raw: core::ptr::NonNull::new_unchecked(
3834                    ffi::whiteout_m2_M2TextureTransform_get_scaling(self.raw.as_ptr()),
3835                ),
3836            })
3837        }
3838    }
3839
3840    pub fn scaling_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackVector3f> {
3841        // SAFETY: as above; `&mut self` guarantees exclusivity.
3842        unsafe {
3843            crate::support::RefMut::new(AnimationTrackVector3f {
3844                raw: core::ptr::NonNull::new_unchecked(
3845                    ffi::whiteout_m2_M2TextureTransform_get_scaling(self.raw.as_ptr()),
3846                ),
3847            })
3848        }
3849    }
3850}
3851
3852impl Default for TextureTransform {
3853    fn default() -> Self {
3854        Self::new()
3855    }
3856}
3857
3858pub struct ColorAnimation {
3859    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2ColorAnimation>,
3860}
3861
3862impl Drop for ColorAnimation {
3863    fn drop(&mut self) {
3864        // SAFETY: `raw` came from a native constructor and Drop runs once.
3865        unsafe { ffi::whiteout_m2_M2ColorAnimation_delete(self.raw.as_ptr()) }
3866    }
3867}
3868
3869impl ColorAnimation {
3870    /// # Safety
3871    /// `raw` must be a live handle this value takes ownership of.
3872    #[allow(dead_code)] // used by whichever methods return this type
3873    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2ColorAnimation) -> Option<Self> {
3874        core::ptr::NonNull::new(raw).map(|raw| ColorAnimation { raw })
3875    }
3876}
3877
3878// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
3879// is deliberately NOT implemented — the C++ types make no documented
3880// guarantee about concurrent use, and claiming one we haven't verified
3881// would be unsound. See `@bind thread_safe` in the plan.
3882unsafe impl Send for ColorAnimation {}
3883
3884impl core::fmt::Debug for ColorAnimation {
3885    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3886        f.debug_struct("ColorAnimation").finish_non_exhaustive()
3887    }
3888}
3889
3890impl ColorAnimation {
3891    /// # Panics
3892    /// Panics if the native allocation fails.
3893    pub fn new() -> Self {
3894        // SAFETY: the native constructor returns a live handle; a null here
3895        // means the library is unusable.
3896        unsafe {
3897            let raw = ffi::whiteout_m2_M2ColorAnimation_new();
3898            Self::from_raw(raw).expect("native ColorAnimation allocation failed")
3899        }
3900    }
3901
3902    /// Borrows the field in place — no copy, no allocation.
3903    pub fn color(&self) -> crate::support::Ref<'_, AnimationTrackVector3f> {
3904        // SAFETY: an interior pointer into `self`, valid for this
3905        // borrow and never freed by the `Ref`.
3906        unsafe {
3907            crate::support::Ref::new(AnimationTrackVector3f {
3908                raw: core::ptr::NonNull::new_unchecked(
3909                    ffi::whiteout_m2_M2ColorAnimation_get_color(self.raw.as_ptr()),
3910                ),
3911            })
3912        }
3913    }
3914
3915    pub fn color_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackVector3f> {
3916        // SAFETY: as above; `&mut self` guarantees exclusivity.
3917        unsafe {
3918            crate::support::RefMut::new(AnimationTrackVector3f {
3919                raw: core::ptr::NonNull::new_unchecked(
3920                    ffi::whiteout_m2_M2ColorAnimation_get_color(self.raw.as_ptr()),
3921                ),
3922            })
3923        }
3924    }
3925
3926    /// Borrows the field in place — no copy, no allocation.
3927    pub fn alpha(&self) -> crate::support::Ref<'_, AnimationTrackI16> {
3928        // SAFETY: an interior pointer into `self`, valid for this
3929        // borrow and never freed by the `Ref`.
3930        unsafe {
3931            crate::support::Ref::new(AnimationTrackI16 {
3932                raw: core::ptr::NonNull::new_unchecked(
3933                    ffi::whiteout_m2_M2ColorAnimation_get_alpha(self.raw.as_ptr()),
3934                ),
3935            })
3936        }
3937    }
3938
3939    pub fn alpha_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackI16> {
3940        // SAFETY: as above; `&mut self` guarantees exclusivity.
3941        unsafe {
3942            crate::support::RefMut::new(AnimationTrackI16 {
3943                raw: core::ptr::NonNull::new_unchecked(
3944                    ffi::whiteout_m2_M2ColorAnimation_get_alpha(self.raw.as_ptr()),
3945                ),
3946            })
3947        }
3948    }
3949}
3950
3951impl Default for ColorAnimation {
3952    fn default() -> Self {
3953        Self::new()
3954    }
3955}
3956
3957pub struct Light {
3958    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2Light>,
3959}
3960
3961impl Drop for Light {
3962    fn drop(&mut self) {
3963        // SAFETY: `raw` came from a native constructor and Drop runs once.
3964        unsafe { ffi::whiteout_m2_M2Light_delete(self.raw.as_ptr()) }
3965    }
3966}
3967
3968impl Light {
3969    /// # Safety
3970    /// `raw` must be a live handle this value takes ownership of.
3971    #[allow(dead_code)] // used by whichever methods return this type
3972    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2Light) -> Option<Self> {
3973        core::ptr::NonNull::new(raw).map(|raw| Light { raw })
3974    }
3975}
3976
3977// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
3978// is deliberately NOT implemented — the C++ types make no documented
3979// guarantee about concurrent use, and claiming one we haven't verified
3980// would be unsound. See `@bind thread_safe` in the plan.
3981unsafe impl Send for Light {}
3982
3983impl core::fmt::Debug for Light {
3984    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3985        f.debug_struct("Light").finish_non_exhaustive()
3986    }
3987}
3988
3989impl Light {
3990    /// # Panics
3991    /// Panics if the native allocation fails.
3992    pub fn new() -> Self {
3993        // SAFETY: the native constructor returns a live handle; a null here
3994        // means the library is unusable.
3995        unsafe {
3996            let raw = ffi::whiteout_m2_M2Light_new();
3997            Self::from_raw(raw).expect("native Light allocation failed")
3998        }
3999    }
4000
4001    pub fn type_(&self) -> u16 {
4002        // SAFETY: plain scalar read through a live handle.
4003        unsafe { ffi::whiteout_m2_M2Light_get_type(self.raw.as_ptr()) }
4004    }
4005
4006    pub fn set_type_(&mut self, value: u16) {
4007        // SAFETY: plain scalar write through a live handle.
4008        unsafe { ffi::whiteout_m2_M2Light_set_type(self.raw.as_ptr(), value) }
4009    }
4010
4011    pub fn bone_id(&self) -> i16 {
4012        // SAFETY: plain scalar read through a live handle.
4013        unsafe { ffi::whiteout_m2_M2Light_get_boneId(self.raw.as_ptr()) }
4014    }
4015
4016    pub fn set_bone_id(&mut self, value: i16) {
4017        // SAFETY: plain scalar write through a live handle.
4018        unsafe { ffi::whiteout_m2_M2Light_set_boneId(self.raw.as_ptr(), value) }
4019    }
4020
4021    pub fn position(&self) -> crate::math::Vector3f {
4022        // SAFETY: the getter returns an interior pointer to a
4023        // layout-identical POD; we copy it out immediately.
4024        unsafe {
4025            *(ffi::whiteout_m2_M2Light_get_position(self.raw.as_ptr())
4026                as *const crate::math::Vector3f)
4027        }
4028    }
4029
4030    pub fn set_position(&mut self, value: crate::math::Vector3f) {
4031        // SAFETY: as above, in the other direction.
4032        unsafe {
4033            ffi::whiteout_m2_M2Light_set_position(
4034                self.raw.as_ptr(),
4035                &value as *const crate::math::Vector3f as *const _,
4036            )
4037        }
4038    }
4039
4040    /// Borrows the field in place — no copy, no allocation.
4041    pub fn ambient_color(&self) -> crate::support::Ref<'_, AnimationTrackVector3f> {
4042        // SAFETY: an interior pointer into `self`, valid for this
4043        // borrow and never freed by the `Ref`.
4044        unsafe {
4045            crate::support::Ref::new(AnimationTrackVector3f {
4046                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Light_get_ambientColor(
4047                    self.raw.as_ptr(),
4048                )),
4049            })
4050        }
4051    }
4052
4053    pub fn ambient_color_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackVector3f> {
4054        // SAFETY: as above; `&mut self` guarantees exclusivity.
4055        unsafe {
4056            crate::support::RefMut::new(AnimationTrackVector3f {
4057                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Light_get_ambientColor(
4058                    self.raw.as_ptr(),
4059                )),
4060            })
4061        }
4062    }
4063
4064    /// Borrows the field in place — no copy, no allocation.
4065    pub fn ambient_intensity(&self) -> crate::support::Ref<'_, AnimationTrackF32> {
4066        // SAFETY: an interior pointer into `self`, valid for this
4067        // borrow and never freed by the `Ref`.
4068        unsafe {
4069            crate::support::Ref::new(AnimationTrackF32 {
4070                raw: core::ptr::NonNull::new_unchecked(
4071                    ffi::whiteout_m2_M2Light_get_ambientIntensity(self.raw.as_ptr()),
4072                ),
4073            })
4074        }
4075    }
4076
4077    pub fn ambient_intensity_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackF32> {
4078        // SAFETY: as above; `&mut self` guarantees exclusivity.
4079        unsafe {
4080            crate::support::RefMut::new(AnimationTrackF32 {
4081                raw: core::ptr::NonNull::new_unchecked(
4082                    ffi::whiteout_m2_M2Light_get_ambientIntensity(self.raw.as_ptr()),
4083                ),
4084            })
4085        }
4086    }
4087
4088    /// Borrows the field in place — no copy, no allocation.
4089    pub fn diffuse_color(&self) -> crate::support::Ref<'_, AnimationTrackVector3f> {
4090        // SAFETY: an interior pointer into `self`, valid for this
4091        // borrow and never freed by the `Ref`.
4092        unsafe {
4093            crate::support::Ref::new(AnimationTrackVector3f {
4094                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Light_get_diffuseColor(
4095                    self.raw.as_ptr(),
4096                )),
4097            })
4098        }
4099    }
4100
4101    pub fn diffuse_color_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackVector3f> {
4102        // SAFETY: as above; `&mut self` guarantees exclusivity.
4103        unsafe {
4104            crate::support::RefMut::new(AnimationTrackVector3f {
4105                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Light_get_diffuseColor(
4106                    self.raw.as_ptr(),
4107                )),
4108            })
4109        }
4110    }
4111
4112    /// Borrows the field in place — no copy, no allocation.
4113    pub fn diffuse_intensity(&self) -> crate::support::Ref<'_, AnimationTrackF32> {
4114        // SAFETY: an interior pointer into `self`, valid for this
4115        // borrow and never freed by the `Ref`.
4116        unsafe {
4117            crate::support::Ref::new(AnimationTrackF32 {
4118                raw: core::ptr::NonNull::new_unchecked(
4119                    ffi::whiteout_m2_M2Light_get_diffuseIntensity(self.raw.as_ptr()),
4120                ),
4121            })
4122        }
4123    }
4124
4125    pub fn diffuse_intensity_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackF32> {
4126        // SAFETY: as above; `&mut self` guarantees exclusivity.
4127        unsafe {
4128            crate::support::RefMut::new(AnimationTrackF32 {
4129                raw: core::ptr::NonNull::new_unchecked(
4130                    ffi::whiteout_m2_M2Light_get_diffuseIntensity(self.raw.as_ptr()),
4131                ),
4132            })
4133        }
4134    }
4135
4136    /// Borrows the field in place — no copy, no allocation.
4137    pub fn attenuation_start(&self) -> crate::support::Ref<'_, AnimationTrackF32> {
4138        // SAFETY: an interior pointer into `self`, valid for this
4139        // borrow and never freed by the `Ref`.
4140        unsafe {
4141            crate::support::Ref::new(AnimationTrackF32 {
4142                raw: core::ptr::NonNull::new_unchecked(
4143                    ffi::whiteout_m2_M2Light_get_attenuationStart(self.raw.as_ptr()),
4144                ),
4145            })
4146        }
4147    }
4148
4149    pub fn attenuation_start_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackF32> {
4150        // SAFETY: as above; `&mut self` guarantees exclusivity.
4151        unsafe {
4152            crate::support::RefMut::new(AnimationTrackF32 {
4153                raw: core::ptr::NonNull::new_unchecked(
4154                    ffi::whiteout_m2_M2Light_get_attenuationStart(self.raw.as_ptr()),
4155                ),
4156            })
4157        }
4158    }
4159
4160    /// Borrows the field in place — no copy, no allocation.
4161    pub fn attenuation_end(&self) -> crate::support::Ref<'_, AnimationTrackF32> {
4162        // SAFETY: an interior pointer into `self`, valid for this
4163        // borrow and never freed by the `Ref`.
4164        unsafe {
4165            crate::support::Ref::new(AnimationTrackF32 {
4166                raw: core::ptr::NonNull::new_unchecked(
4167                    ffi::whiteout_m2_M2Light_get_attenuationEnd(self.raw.as_ptr()),
4168                ),
4169            })
4170        }
4171    }
4172
4173    pub fn attenuation_end_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackF32> {
4174        // SAFETY: as above; `&mut self` guarantees exclusivity.
4175        unsafe {
4176            crate::support::RefMut::new(AnimationTrackF32 {
4177                raw: core::ptr::NonNull::new_unchecked(
4178                    ffi::whiteout_m2_M2Light_get_attenuationEnd(self.raw.as_ptr()),
4179                ),
4180            })
4181        }
4182    }
4183
4184    /// Borrows the field in place — no copy, no allocation.
4185    pub fn visibility(&self) -> crate::support::Ref<'_, AnimationTrackU8> {
4186        // SAFETY: an interior pointer into `self`, valid for this
4187        // borrow and never freed by the `Ref`.
4188        unsafe {
4189            crate::support::Ref::new(AnimationTrackU8 {
4190                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Light_get_visibility(
4191                    self.raw.as_ptr(),
4192                )),
4193            })
4194        }
4195    }
4196
4197    pub fn visibility_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackU8> {
4198        // SAFETY: as above; `&mut self` guarantees exclusivity.
4199        unsafe {
4200            crate::support::RefMut::new(AnimationTrackU8 {
4201                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Light_get_visibility(
4202                    self.raw.as_ptr(),
4203                )),
4204            })
4205        }
4206    }
4207}
4208
4209impl Default for Light {
4210    fn default() -> Self {
4211        Self::new()
4212    }
4213}
4214
4215pub struct CameraSpline {
4216    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2CameraSpline>,
4217}
4218
4219impl Drop for CameraSpline {
4220    fn drop(&mut self) {
4221        // SAFETY: `raw` came from a native constructor and Drop runs once.
4222        unsafe { ffi::whiteout_m2_M2CameraSpline_delete(self.raw.as_ptr()) }
4223    }
4224}
4225
4226impl CameraSpline {
4227    /// # Safety
4228    /// `raw` must be a live handle this value takes ownership of.
4229    #[allow(dead_code)] // used by whichever methods return this type
4230    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2CameraSpline) -> Option<Self> {
4231        core::ptr::NonNull::new(raw).map(|raw| CameraSpline { raw })
4232    }
4233}
4234
4235// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
4236// is deliberately NOT implemented — the C++ types make no documented
4237// guarantee about concurrent use, and claiming one we haven't verified
4238// would be unsound. See `@bind thread_safe` in the plan.
4239unsafe impl Send for CameraSpline {}
4240
4241impl core::fmt::Debug for CameraSpline {
4242    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
4243        f.debug_struct("CameraSpline").finish_non_exhaustive()
4244    }
4245}
4246
4247impl CameraSpline {
4248    /// # Panics
4249    /// Panics if the native allocation fails.
4250    pub fn new() -> Self {
4251        // SAFETY: the native constructor returns a live handle; a null here
4252        // means the library is unusable.
4253        unsafe {
4254            let raw = ffi::whiteout_m2_M2CameraSpline_new();
4255            Self::from_raw(raw).expect("native CameraSpline allocation failed")
4256        }
4257    }
4258
4259    pub fn value(&self) -> crate::math::Vector3f {
4260        // SAFETY: the getter returns an interior pointer to a
4261        // layout-identical POD; we copy it out immediately.
4262        unsafe {
4263            *(ffi::whiteout_m2_M2CameraSpline_get_value(self.raw.as_ptr())
4264                as *const crate::math::Vector3f)
4265        }
4266    }
4267
4268    pub fn set_value(&mut self, value: crate::math::Vector3f) {
4269        // SAFETY: as above, in the other direction.
4270        unsafe {
4271            ffi::whiteout_m2_M2CameraSpline_set_value(
4272                self.raw.as_ptr(),
4273                &value as *const crate::math::Vector3f as *const _,
4274            )
4275        }
4276    }
4277
4278    pub fn in_tangent(&self) -> crate::math::Vector3f {
4279        // SAFETY: the getter returns an interior pointer to a
4280        // layout-identical POD; we copy it out immediately.
4281        unsafe {
4282            *(ffi::whiteout_m2_M2CameraSpline_get_inTangent(self.raw.as_ptr())
4283                as *const crate::math::Vector3f)
4284        }
4285    }
4286
4287    pub fn set_in_tangent(&mut self, value: crate::math::Vector3f) {
4288        // SAFETY: as above, in the other direction.
4289        unsafe {
4290            ffi::whiteout_m2_M2CameraSpline_set_inTangent(
4291                self.raw.as_ptr(),
4292                &value as *const crate::math::Vector3f as *const _,
4293            )
4294        }
4295    }
4296
4297    pub fn out_tangent(&self) -> crate::math::Vector3f {
4298        // SAFETY: the getter returns an interior pointer to a
4299        // layout-identical POD; we copy it out immediately.
4300        unsafe {
4301            *(ffi::whiteout_m2_M2CameraSpline_get_outTangent(self.raw.as_ptr())
4302                as *const crate::math::Vector3f)
4303        }
4304    }
4305
4306    pub fn set_out_tangent(&mut self, value: crate::math::Vector3f) {
4307        // SAFETY: as above, in the other direction.
4308        unsafe {
4309            ffi::whiteout_m2_M2CameraSpline_set_outTangent(
4310                self.raw.as_ptr(),
4311                &value as *const crate::math::Vector3f as *const _,
4312            )
4313        }
4314    }
4315}
4316
4317impl Default for CameraSpline {
4318    fn default() -> Self {
4319        Self::new()
4320    }
4321}
4322
4323pub struct Camera {
4324    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2Camera>,
4325}
4326
4327impl Drop for Camera {
4328    fn drop(&mut self) {
4329        // SAFETY: `raw` came from a native constructor and Drop runs once.
4330        unsafe { ffi::whiteout_m2_M2Camera_delete(self.raw.as_ptr()) }
4331    }
4332}
4333
4334impl Camera {
4335    /// # Safety
4336    /// `raw` must be a live handle this value takes ownership of.
4337    #[allow(dead_code)] // used by whichever methods return this type
4338    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2Camera) -> Option<Self> {
4339        core::ptr::NonNull::new(raw).map(|raw| Camera { raw })
4340    }
4341}
4342
4343// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
4344// is deliberately NOT implemented — the C++ types make no documented
4345// guarantee about concurrent use, and claiming one we haven't verified
4346// would be unsound. See `@bind thread_safe` in the plan.
4347unsafe impl Send for Camera {}
4348
4349impl core::fmt::Debug for Camera {
4350    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
4351        f.debug_struct("Camera").finish_non_exhaustive()
4352    }
4353}
4354
4355impl Camera {
4356    /// # Panics
4357    /// Panics if the native allocation fails.
4358    pub fn new() -> Self {
4359        // SAFETY: the native constructor returns a live handle; a null here
4360        // means the library is unusable.
4361        unsafe {
4362            let raw = ffi::whiteout_m2_M2Camera_new();
4363            Self::from_raw(raw).expect("native Camera allocation failed")
4364        }
4365    }
4366
4367    pub fn type_(&self) -> u32 {
4368        // SAFETY: plain scalar read through a live handle.
4369        unsafe { ffi::whiteout_m2_M2Camera_get_type(self.raw.as_ptr()) }
4370    }
4371
4372    pub fn set_type_(&mut self, value: u32) {
4373        // SAFETY: plain scalar write through a live handle.
4374        unsafe { ffi::whiteout_m2_M2Camera_set_type(self.raw.as_ptr(), value) }
4375    }
4376
4377    pub fn field_of_view(&self) -> f32 {
4378        // SAFETY: plain scalar read through a live handle.
4379        unsafe { ffi::whiteout_m2_M2Camera_get_fieldOfView(self.raw.as_ptr()) }
4380    }
4381
4382    pub fn set_field_of_view(&mut self, value: f32) {
4383        // SAFETY: plain scalar write through a live handle.
4384        unsafe { ffi::whiteout_m2_M2Camera_set_fieldOfView(self.raw.as_ptr(), value) }
4385    }
4386
4387    pub fn far_clip(&self) -> f32 {
4388        // SAFETY: plain scalar read through a live handle.
4389        unsafe { ffi::whiteout_m2_M2Camera_get_farClip(self.raw.as_ptr()) }
4390    }
4391
4392    pub fn set_far_clip(&mut self, value: f32) {
4393        // SAFETY: plain scalar write through a live handle.
4394        unsafe { ffi::whiteout_m2_M2Camera_set_farClip(self.raw.as_ptr(), value) }
4395    }
4396
4397    pub fn near_clip(&self) -> f32 {
4398        // SAFETY: plain scalar read through a live handle.
4399        unsafe { ffi::whiteout_m2_M2Camera_get_nearClip(self.raw.as_ptr()) }
4400    }
4401
4402    pub fn set_near_clip(&mut self, value: f32) {
4403        // SAFETY: plain scalar write through a live handle.
4404        unsafe { ffi::whiteout_m2_M2Camera_set_nearClip(self.raw.as_ptr(), value) }
4405    }
4406
4407    /// Borrows the field in place — no copy, no allocation.
4408    pub fn positions(&self) -> crate::support::Ref<'_, AnimationTrackM2CameraSpline> {
4409        // SAFETY: an interior pointer into `self`, valid for this
4410        // borrow and never freed by the `Ref`.
4411        unsafe {
4412            crate::support::Ref::new(AnimationTrackM2CameraSpline {
4413                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Camera_get_positions(
4414                    self.raw.as_ptr(),
4415                )),
4416            })
4417        }
4418    }
4419
4420    pub fn positions_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackM2CameraSpline> {
4421        // SAFETY: as above; `&mut self` guarantees exclusivity.
4422        unsafe {
4423            crate::support::RefMut::new(AnimationTrackM2CameraSpline {
4424                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Camera_get_positions(
4425                    self.raw.as_ptr(),
4426                )),
4427            })
4428        }
4429    }
4430
4431    pub fn position_base(&self) -> crate::math::Vector3f {
4432        // SAFETY: the getter returns an interior pointer to a
4433        // layout-identical POD; we copy it out immediately.
4434        unsafe {
4435            *(ffi::whiteout_m2_M2Camera_get_positionBase(self.raw.as_ptr())
4436                as *const crate::math::Vector3f)
4437        }
4438    }
4439
4440    pub fn set_position_base(&mut self, value: crate::math::Vector3f) {
4441        // SAFETY: as above, in the other direction.
4442        unsafe {
4443            ffi::whiteout_m2_M2Camera_set_positionBase(
4444                self.raw.as_ptr(),
4445                &value as *const crate::math::Vector3f as *const _,
4446            )
4447        }
4448    }
4449
4450    /// Borrows the field in place — no copy, no allocation.
4451    pub fn target_positions(&self) -> crate::support::Ref<'_, AnimationTrackM2CameraSpline> {
4452        // SAFETY: an interior pointer into `self`, valid for this
4453        // borrow and never freed by the `Ref`.
4454        unsafe {
4455            crate::support::Ref::new(AnimationTrackM2CameraSpline {
4456                raw: core::ptr::NonNull::new_unchecked(
4457                    ffi::whiteout_m2_M2Camera_get_targetPositions(self.raw.as_ptr()),
4458                ),
4459            })
4460        }
4461    }
4462
4463    pub fn target_positions_mut(
4464        &mut self,
4465    ) -> crate::support::RefMut<'_, AnimationTrackM2CameraSpline> {
4466        // SAFETY: as above; `&mut self` guarantees exclusivity.
4467        unsafe {
4468            crate::support::RefMut::new(AnimationTrackM2CameraSpline {
4469                raw: core::ptr::NonNull::new_unchecked(
4470                    ffi::whiteout_m2_M2Camera_get_targetPositions(self.raw.as_ptr()),
4471                ),
4472            })
4473        }
4474    }
4475
4476    pub fn target_position_base(&self) -> crate::math::Vector3f {
4477        // SAFETY: the getter returns an interior pointer to a
4478        // layout-identical POD; we copy it out immediately.
4479        unsafe {
4480            *(ffi::whiteout_m2_M2Camera_get_targetPositionBase(self.raw.as_ptr())
4481                as *const crate::math::Vector3f)
4482        }
4483    }
4484
4485    pub fn set_target_position_base(&mut self, value: crate::math::Vector3f) {
4486        // SAFETY: as above, in the other direction.
4487        unsafe {
4488            ffi::whiteout_m2_M2Camera_set_targetPositionBase(
4489                self.raw.as_ptr(),
4490                &value as *const crate::math::Vector3f as *const _,
4491            )
4492        }
4493    }
4494
4495    /// Borrows the field in place — no copy, no allocation.
4496    pub fn roll(&self) -> crate::support::Ref<'_, AnimationTrackF32> {
4497        // SAFETY: an interior pointer into `self`, valid for this
4498        // borrow and never freed by the `Ref`.
4499        unsafe {
4500            crate::support::Ref::new(AnimationTrackF32 {
4501                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Camera_get_roll(
4502                    self.raw.as_ptr(),
4503                )),
4504            })
4505        }
4506    }
4507
4508    pub fn roll_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackF32> {
4509        // SAFETY: as above; `&mut self` guarantees exclusivity.
4510        unsafe {
4511            crate::support::RefMut::new(AnimationTrackF32 {
4512                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Camera_get_roll(
4513                    self.raw.as_ptr(),
4514                )),
4515            })
4516        }
4517    }
4518
4519    /// Borrows the field in place — no copy, no allocation.
4520    pub fn field_of_view_track(&self) -> crate::support::Ref<'_, AnimationTrackF32> {
4521        // SAFETY: an interior pointer into `self`, valid for this
4522        // borrow and never freed by the `Ref`.
4523        unsafe {
4524            crate::support::Ref::new(AnimationTrackF32 {
4525                raw: core::ptr::NonNull::new_unchecked(
4526                    ffi::whiteout_m2_M2Camera_get_fieldOfViewTrack(self.raw.as_ptr()),
4527                ),
4528            })
4529        }
4530    }
4531
4532    pub fn field_of_view_track_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackF32> {
4533        // SAFETY: as above; `&mut self` guarantees exclusivity.
4534        unsafe {
4535            crate::support::RefMut::new(AnimationTrackF32 {
4536                raw: core::ptr::NonNull::new_unchecked(
4537                    ffi::whiteout_m2_M2Camera_get_fieldOfViewTrack(self.raw.as_ptr()),
4538                ),
4539            })
4540        }
4541    }
4542}
4543
4544impl Default for Camera {
4545    fn default() -> Self {
4546        Self::new()
4547    }
4548}
4549
4550pub struct Attachment {
4551    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2Attachment>,
4552}
4553
4554impl Drop for Attachment {
4555    fn drop(&mut self) {
4556        // SAFETY: `raw` came from a native constructor and Drop runs once.
4557        unsafe { ffi::whiteout_m2_M2Attachment_delete(self.raw.as_ptr()) }
4558    }
4559}
4560
4561impl Attachment {
4562    /// # Safety
4563    /// `raw` must be a live handle this value takes ownership of.
4564    #[allow(dead_code)] // used by whichever methods return this type
4565    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2Attachment) -> Option<Self> {
4566        core::ptr::NonNull::new(raw).map(|raw| Attachment { raw })
4567    }
4568}
4569
4570// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
4571// is deliberately NOT implemented — the C++ types make no documented
4572// guarantee about concurrent use, and claiming one we haven't verified
4573// would be unsound. See `@bind thread_safe` in the plan.
4574unsafe impl Send for Attachment {}
4575
4576impl core::fmt::Debug for Attachment {
4577    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
4578        f.debug_struct("Attachment").finish_non_exhaustive()
4579    }
4580}
4581
4582impl Attachment {
4583    /// # Panics
4584    /// Panics if the native allocation fails.
4585    pub fn new() -> Self {
4586        // SAFETY: the native constructor returns a live handle; a null here
4587        // means the library is unusable.
4588        unsafe {
4589            let raw = ffi::whiteout_m2_M2Attachment_new();
4590            Self::from_raw(raw).expect("native Attachment allocation failed")
4591        }
4592    }
4593
4594    pub fn id(&self) -> u32 {
4595        // SAFETY: plain scalar read through a live handle.
4596        unsafe { ffi::whiteout_m2_M2Attachment_get_id(self.raw.as_ptr()) }
4597    }
4598
4599    pub fn set_id(&mut self, value: u32) {
4600        // SAFETY: plain scalar write through a live handle.
4601        unsafe { ffi::whiteout_m2_M2Attachment_set_id(self.raw.as_ptr(), value) }
4602    }
4603
4604    pub fn bone_id(&self) -> u16 {
4605        // SAFETY: plain scalar read through a live handle.
4606        unsafe { ffi::whiteout_m2_M2Attachment_get_boneId(self.raw.as_ptr()) }
4607    }
4608
4609    pub fn set_bone_id(&mut self, value: u16) {
4610        // SAFETY: plain scalar write through a live handle.
4611        unsafe { ffi::whiteout_m2_M2Attachment_set_boneId(self.raw.as_ptr(), value) }
4612    }
4613
4614    pub fn unknown(&self) -> u16 {
4615        // SAFETY: plain scalar read through a live handle.
4616        unsafe { ffi::whiteout_m2_M2Attachment_get_unknown(self.raw.as_ptr()) }
4617    }
4618
4619    pub fn set_unknown(&mut self, value: u16) {
4620        // SAFETY: plain scalar write through a live handle.
4621        unsafe { ffi::whiteout_m2_M2Attachment_set_unknown(self.raw.as_ptr(), value) }
4622    }
4623
4624    pub fn position(&self) -> crate::math::Vector3f {
4625        // SAFETY: the getter returns an interior pointer to a
4626        // layout-identical POD; we copy it out immediately.
4627        unsafe {
4628            *(ffi::whiteout_m2_M2Attachment_get_position(self.raw.as_ptr())
4629                as *const crate::math::Vector3f)
4630        }
4631    }
4632
4633    pub fn set_position(&mut self, value: crate::math::Vector3f) {
4634        // SAFETY: as above, in the other direction.
4635        unsafe {
4636            ffi::whiteout_m2_M2Attachment_set_position(
4637                self.raw.as_ptr(),
4638                &value as *const crate::math::Vector3f as *const _,
4639            )
4640        }
4641    }
4642
4643    /// Borrows the field in place — no copy, no allocation.
4644    pub fn animate(&self) -> crate::support::Ref<'_, AnimationTrackU8> {
4645        // SAFETY: an interior pointer into `self`, valid for this
4646        // borrow and never freed by the `Ref`.
4647        unsafe {
4648            crate::support::Ref::new(AnimationTrackU8 {
4649                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Attachment_get_animate(
4650                    self.raw.as_ptr(),
4651                )),
4652            })
4653        }
4654    }
4655
4656    pub fn animate_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackU8> {
4657        // SAFETY: as above; `&mut self` guarantees exclusivity.
4658        unsafe {
4659            crate::support::RefMut::new(AnimationTrackU8 {
4660                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Attachment_get_animate(
4661                    self.raw.as_ptr(),
4662                )),
4663            })
4664        }
4665    }
4666}
4667
4668impl Default for Attachment {
4669    fn default() -> Self {
4670        Self::new()
4671    }
4672}
4673
4674pub struct RibbonEmitter {
4675    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2RibbonEmitter>,
4676}
4677
4678impl Drop for RibbonEmitter {
4679    fn drop(&mut self) {
4680        // SAFETY: `raw` came from a native constructor and Drop runs once.
4681        unsafe { ffi::whiteout_m2_M2RibbonEmitter_delete(self.raw.as_ptr()) }
4682    }
4683}
4684
4685impl RibbonEmitter {
4686    /// # Safety
4687    /// `raw` must be a live handle this value takes ownership of.
4688    #[allow(dead_code)] // used by whichever methods return this type
4689    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2RibbonEmitter) -> Option<Self> {
4690        core::ptr::NonNull::new(raw).map(|raw| RibbonEmitter { raw })
4691    }
4692}
4693
4694// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
4695// is deliberately NOT implemented — the C++ types make no documented
4696// guarantee about concurrent use, and claiming one we haven't verified
4697// would be unsound. See `@bind thread_safe` in the plan.
4698unsafe impl Send for RibbonEmitter {}
4699
4700impl core::fmt::Debug for RibbonEmitter {
4701    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
4702        f.debug_struct("RibbonEmitter").finish_non_exhaustive()
4703    }
4704}
4705
4706impl RibbonEmitter {
4707    /// # Panics
4708    /// Panics if the native allocation fails.
4709    pub fn new() -> Self {
4710        // SAFETY: the native constructor returns a live handle; a null here
4711        // means the library is unusable.
4712        unsafe {
4713            let raw = ffi::whiteout_m2_M2RibbonEmitter_new();
4714            Self::from_raw(raw).expect("native RibbonEmitter allocation failed")
4715        }
4716    }
4717
4718    pub fn ribbon_id(&self) -> u32 {
4719        // SAFETY: plain scalar read through a live handle.
4720        unsafe { ffi::whiteout_m2_M2RibbonEmitter_get_ribbonId(self.raw.as_ptr()) }
4721    }
4722
4723    pub fn set_ribbon_id(&mut self, value: u32) {
4724        // SAFETY: plain scalar write through a live handle.
4725        unsafe { ffi::whiteout_m2_M2RibbonEmitter_set_ribbonId(self.raw.as_ptr(), value) }
4726    }
4727
4728    pub fn bone_id(&self) -> u32 {
4729        // SAFETY: plain scalar read through a live handle.
4730        unsafe { ffi::whiteout_m2_M2RibbonEmitter_get_boneId(self.raw.as_ptr()) }
4731    }
4732
4733    pub fn set_bone_id(&mut self, value: u32) {
4734        // SAFETY: plain scalar write through a live handle.
4735        unsafe { ffi::whiteout_m2_M2RibbonEmitter_set_boneId(self.raw.as_ptr(), value) }
4736    }
4737
4738    pub fn position(&self) -> crate::math::Vector3f {
4739        // SAFETY: the getter returns an interior pointer to a
4740        // layout-identical POD; we copy it out immediately.
4741        unsafe {
4742            *(ffi::whiteout_m2_M2RibbonEmitter_get_position(self.raw.as_ptr())
4743                as *const crate::math::Vector3f)
4744        }
4745    }
4746
4747    pub fn set_position(&mut self, value: crate::math::Vector3f) {
4748        // SAFETY: as above, in the other direction.
4749        unsafe {
4750            ffi::whiteout_m2_M2RibbonEmitter_set_position(
4751                self.raw.as_ptr(),
4752                &value as *const crate::math::Vector3f as *const _,
4753            )
4754        }
4755    }
4756
4757    /// Zero-copy view of the underlying `std::vector`.
4758    pub fn texture_indices(&self) -> &[u16] {
4759        // SAFETY: `_data`/`_count` describe one contiguous C++
4760        // allocation, borrowed for as long as `self` is.
4761        unsafe {
4762            let n = ffi::whiteout_m2_M2RibbonEmitter_get_textureIndices_count(self.raw.as_ptr());
4763            let p = ffi::whiteout_m2_M2RibbonEmitter_get_textureIndices_data(self.raw.as_ptr());
4764            if p.is_null() || n == 0 {
4765                &[]
4766            } else {
4767                core::slice::from_raw_parts(p, n)
4768            }
4769        }
4770    }
4771
4772    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
4773    pub fn texture_indices_mut(&mut self) -> &mut [u16] {
4774        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
4775        unsafe {
4776            let n = ffi::whiteout_m2_M2RibbonEmitter_get_textureIndices_count(self.raw.as_ptr());
4777            let p = ffi::whiteout_m2_M2RibbonEmitter_get_textureIndices_data(self.raw.as_ptr())
4778                as *mut u16;
4779            if p.is_null() || n == 0 {
4780                &mut []
4781            } else {
4782                core::slice::from_raw_parts_mut(p, n)
4783            }
4784        }
4785    }
4786
4787    pub fn set_texture_indices(&mut self, values: &[u16]) {
4788        // SAFETY: the native side copies `values` before returning.
4789        unsafe {
4790            ffi::whiteout_m2_M2RibbonEmitter_assign_textureIndices(
4791                self.raw.as_ptr(),
4792                values.as_ptr() as *const _,
4793                values.len(),
4794            )
4795        }
4796    }
4797
4798    pub fn resize_texture_indices(&mut self, count: usize) {
4799        // SAFETY: reallocation is safe here precisely because
4800        // `&mut self` means no slice borrow is outstanding.
4801        unsafe { ffi::whiteout_m2_M2RibbonEmitter_resize_textureIndices(self.raw.as_ptr(), count) }
4802    }
4803
4804    /// Zero-copy view of the underlying `std::vector`.
4805    pub fn material_indices(&self) -> &[u16] {
4806        // SAFETY: `_data`/`_count` describe one contiguous C++
4807        // allocation, borrowed for as long as `self` is.
4808        unsafe {
4809            let n = ffi::whiteout_m2_M2RibbonEmitter_get_materialIndices_count(self.raw.as_ptr());
4810            let p = ffi::whiteout_m2_M2RibbonEmitter_get_materialIndices_data(self.raw.as_ptr());
4811            if p.is_null() || n == 0 {
4812                &[]
4813            } else {
4814                core::slice::from_raw_parts(p, n)
4815            }
4816        }
4817    }
4818
4819    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
4820    pub fn material_indices_mut(&mut self) -> &mut [u16] {
4821        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
4822        unsafe {
4823            let n = ffi::whiteout_m2_M2RibbonEmitter_get_materialIndices_count(self.raw.as_ptr());
4824            let p = ffi::whiteout_m2_M2RibbonEmitter_get_materialIndices_data(self.raw.as_ptr())
4825                as *mut u16;
4826            if p.is_null() || n == 0 {
4827                &mut []
4828            } else {
4829                core::slice::from_raw_parts_mut(p, n)
4830            }
4831        }
4832    }
4833
4834    pub fn set_material_indices(&mut self, values: &[u16]) {
4835        // SAFETY: the native side copies `values` before returning.
4836        unsafe {
4837            ffi::whiteout_m2_M2RibbonEmitter_assign_materialIndices(
4838                self.raw.as_ptr(),
4839                values.as_ptr() as *const _,
4840                values.len(),
4841            )
4842        }
4843    }
4844
4845    pub fn resize_material_indices(&mut self, count: usize) {
4846        // SAFETY: reallocation is safe here precisely because
4847        // `&mut self` means no slice borrow is outstanding.
4848        unsafe { ffi::whiteout_m2_M2RibbonEmitter_resize_materialIndices(self.raw.as_ptr(), count) }
4849    }
4850
4851    /// Borrows the field in place — no copy, no allocation.
4852    pub fn color_track(&self) -> crate::support::Ref<'_, AnimationTrackVector3f> {
4853        // SAFETY: an interior pointer into `self`, valid for this
4854        // borrow and never freed by the `Ref`.
4855        unsafe {
4856            crate::support::Ref::new(AnimationTrackVector3f {
4857                raw: core::ptr::NonNull::new_unchecked(
4858                    ffi::whiteout_m2_M2RibbonEmitter_get_colorTrack(self.raw.as_ptr()),
4859                ),
4860            })
4861        }
4862    }
4863
4864    pub fn color_track_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackVector3f> {
4865        // SAFETY: as above; `&mut self` guarantees exclusivity.
4866        unsafe {
4867            crate::support::RefMut::new(AnimationTrackVector3f {
4868                raw: core::ptr::NonNull::new_unchecked(
4869                    ffi::whiteout_m2_M2RibbonEmitter_get_colorTrack(self.raw.as_ptr()),
4870                ),
4871            })
4872        }
4873    }
4874
4875    /// Borrows the field in place — no copy, no allocation.
4876    pub fn alpha_track(&self) -> crate::support::Ref<'_, AnimationTrackI16> {
4877        // SAFETY: an interior pointer into `self`, valid for this
4878        // borrow and never freed by the `Ref`.
4879        unsafe {
4880            crate::support::Ref::new(AnimationTrackI16 {
4881                raw: core::ptr::NonNull::new_unchecked(
4882                    ffi::whiteout_m2_M2RibbonEmitter_get_alphaTrack(self.raw.as_ptr()),
4883                ),
4884            })
4885        }
4886    }
4887
4888    pub fn alpha_track_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackI16> {
4889        // SAFETY: as above; `&mut self` guarantees exclusivity.
4890        unsafe {
4891            crate::support::RefMut::new(AnimationTrackI16 {
4892                raw: core::ptr::NonNull::new_unchecked(
4893                    ffi::whiteout_m2_M2RibbonEmitter_get_alphaTrack(self.raw.as_ptr()),
4894                ),
4895            })
4896        }
4897    }
4898
4899    /// Borrows the field in place — no copy, no allocation.
4900    pub fn height_above(&self) -> crate::support::Ref<'_, AnimationTrackF32> {
4901        // SAFETY: an interior pointer into `self`, valid for this
4902        // borrow and never freed by the `Ref`.
4903        unsafe {
4904            crate::support::Ref::new(AnimationTrackF32 {
4905                raw: core::ptr::NonNull::new_unchecked(
4906                    ffi::whiteout_m2_M2RibbonEmitter_get_heightAbove(self.raw.as_ptr()),
4907                ),
4908            })
4909        }
4910    }
4911
4912    pub fn height_above_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackF32> {
4913        // SAFETY: as above; `&mut self` guarantees exclusivity.
4914        unsafe {
4915            crate::support::RefMut::new(AnimationTrackF32 {
4916                raw: core::ptr::NonNull::new_unchecked(
4917                    ffi::whiteout_m2_M2RibbonEmitter_get_heightAbove(self.raw.as_ptr()),
4918                ),
4919            })
4920        }
4921    }
4922
4923    /// Borrows the field in place — no copy, no allocation.
4924    pub fn height_below(&self) -> crate::support::Ref<'_, AnimationTrackF32> {
4925        // SAFETY: an interior pointer into `self`, valid for this
4926        // borrow and never freed by the `Ref`.
4927        unsafe {
4928            crate::support::Ref::new(AnimationTrackF32 {
4929                raw: core::ptr::NonNull::new_unchecked(
4930                    ffi::whiteout_m2_M2RibbonEmitter_get_heightBelow(self.raw.as_ptr()),
4931                ),
4932            })
4933        }
4934    }
4935
4936    pub fn height_below_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackF32> {
4937        // SAFETY: as above; `&mut self` guarantees exclusivity.
4938        unsafe {
4939            crate::support::RefMut::new(AnimationTrackF32 {
4940                raw: core::ptr::NonNull::new_unchecked(
4941                    ffi::whiteout_m2_M2RibbonEmitter_get_heightBelow(self.raw.as_ptr()),
4942                ),
4943            })
4944        }
4945    }
4946
4947    pub fn edges_per_second(&self) -> f32 {
4948        // SAFETY: plain scalar read through a live handle.
4949        unsafe { ffi::whiteout_m2_M2RibbonEmitter_get_edgesPerSecond(self.raw.as_ptr()) }
4950    }
4951
4952    pub fn set_edges_per_second(&mut self, value: f32) {
4953        // SAFETY: plain scalar write through a live handle.
4954        unsafe { ffi::whiteout_m2_M2RibbonEmitter_set_edgesPerSecond(self.raw.as_ptr(), value) }
4955    }
4956
4957    pub fn edge_lifetime(&self) -> f32 {
4958        // SAFETY: plain scalar read through a live handle.
4959        unsafe { ffi::whiteout_m2_M2RibbonEmitter_get_edgeLifetime(self.raw.as_ptr()) }
4960    }
4961
4962    pub fn set_edge_lifetime(&mut self, value: f32) {
4963        // SAFETY: plain scalar write through a live handle.
4964        unsafe { ffi::whiteout_m2_M2RibbonEmitter_set_edgeLifetime(self.raw.as_ptr(), value) }
4965    }
4966
4967    pub fn gravity(&self) -> f32 {
4968        // SAFETY: plain scalar read through a live handle.
4969        unsafe { ffi::whiteout_m2_M2RibbonEmitter_get_gravity(self.raw.as_ptr()) }
4970    }
4971
4972    pub fn set_gravity(&mut self, value: f32) {
4973        // SAFETY: plain scalar write through a live handle.
4974        unsafe { ffi::whiteout_m2_M2RibbonEmitter_set_gravity(self.raw.as_ptr(), value) }
4975    }
4976
4977    pub fn texture_rows(&self) -> u16 {
4978        // SAFETY: plain scalar read through a live handle.
4979        unsafe { ffi::whiteout_m2_M2RibbonEmitter_get_textureRows(self.raw.as_ptr()) }
4980    }
4981
4982    pub fn set_texture_rows(&mut self, value: u16) {
4983        // SAFETY: plain scalar write through a live handle.
4984        unsafe { ffi::whiteout_m2_M2RibbonEmitter_set_textureRows(self.raw.as_ptr(), value) }
4985    }
4986
4987    pub fn texture_cols(&self) -> u16 {
4988        // SAFETY: plain scalar read through a live handle.
4989        unsafe { ffi::whiteout_m2_M2RibbonEmitter_get_textureCols(self.raw.as_ptr()) }
4990    }
4991
4992    pub fn set_texture_cols(&mut self, value: u16) {
4993        // SAFETY: plain scalar write through a live handle.
4994        unsafe { ffi::whiteout_m2_M2RibbonEmitter_set_textureCols(self.raw.as_ptr(), value) }
4995    }
4996
4997    /// Borrows the field in place — no copy, no allocation.
4998    pub fn tex_slot(&self) -> crate::support::Ref<'_, AnimationTrackU16> {
4999        // SAFETY: an interior pointer into `self`, valid for this
5000        // borrow and never freed by the `Ref`.
5001        unsafe {
5002            crate::support::Ref::new(AnimationTrackU16 {
5003                raw: core::ptr::NonNull::new_unchecked(
5004                    ffi::whiteout_m2_M2RibbonEmitter_get_texSlot(self.raw.as_ptr()),
5005                ),
5006            })
5007        }
5008    }
5009
5010    pub fn tex_slot_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackU16> {
5011        // SAFETY: as above; `&mut self` guarantees exclusivity.
5012        unsafe {
5013            crate::support::RefMut::new(AnimationTrackU16 {
5014                raw: core::ptr::NonNull::new_unchecked(
5015                    ffi::whiteout_m2_M2RibbonEmitter_get_texSlot(self.raw.as_ptr()),
5016                ),
5017            })
5018        }
5019    }
5020
5021    /// Borrows the field in place — no copy, no allocation.
5022    pub fn visibility(&self) -> crate::support::Ref<'_, AnimationTrackU8> {
5023        // SAFETY: an interior pointer into `self`, valid for this
5024        // borrow and never freed by the `Ref`.
5025        unsafe {
5026            crate::support::Ref::new(AnimationTrackU8 {
5027                raw: core::ptr::NonNull::new_unchecked(
5028                    ffi::whiteout_m2_M2RibbonEmitter_get_visibility(self.raw.as_ptr()),
5029                ),
5030            })
5031        }
5032    }
5033
5034    pub fn visibility_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackU8> {
5035        // SAFETY: as above; `&mut self` guarantees exclusivity.
5036        unsafe {
5037            crate::support::RefMut::new(AnimationTrackU8 {
5038                raw: core::ptr::NonNull::new_unchecked(
5039                    ffi::whiteout_m2_M2RibbonEmitter_get_visibility(self.raw.as_ptr()),
5040                ),
5041            })
5042        }
5043    }
5044
5045    pub fn priority_plane(&self) -> i16 {
5046        // SAFETY: plain scalar read through a live handle.
5047        unsafe { ffi::whiteout_m2_M2RibbonEmitter_get_priorityPlane(self.raw.as_ptr()) }
5048    }
5049
5050    pub fn set_priority_plane(&mut self, value: i16) {
5051        // SAFETY: plain scalar write through a live handle.
5052        unsafe { ffi::whiteout_m2_M2RibbonEmitter_set_priorityPlane(self.raw.as_ptr(), value) }
5053    }
5054
5055    pub fn ribbon_color_index(&self) -> i8 {
5056        // SAFETY: plain scalar read through a live handle.
5057        unsafe { ffi::whiteout_m2_M2RibbonEmitter_get_ribbonColorIndex(self.raw.as_ptr()) }
5058    }
5059
5060    pub fn set_ribbon_color_index(&mut self, value: i8) {
5061        // SAFETY: plain scalar write through a live handle.
5062        unsafe { ffi::whiteout_m2_M2RibbonEmitter_set_ribbonColorIndex(self.raw.as_ptr(), value) }
5063    }
5064
5065    pub fn texture_transform_index(&self) -> i8 {
5066        // SAFETY: plain scalar read through a live handle.
5067        unsafe { ffi::whiteout_m2_M2RibbonEmitter_get_textureTransformIndex(self.raw.as_ptr()) }
5068    }
5069
5070    pub fn set_texture_transform_index(&mut self, value: i8) {
5071        // SAFETY: plain scalar write through a live handle.
5072        unsafe {
5073            ffi::whiteout_m2_M2RibbonEmitter_set_textureTransformIndex(self.raw.as_ptr(), value)
5074        }
5075    }
5076}
5077
5078impl Default for RibbonEmitter {
5079    fn default() -> Self {
5080        Self::new()
5081    }
5082}
5083
5084pub struct Box {
5085    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2Box>,
5086}
5087
5088impl Drop for Box {
5089    fn drop(&mut self) {
5090        // SAFETY: `raw` came from a native constructor and Drop runs once.
5091        unsafe { ffi::whiteout_m2_M2Box_delete(self.raw.as_ptr()) }
5092    }
5093}
5094
5095impl Box {
5096    /// # Safety
5097    /// `raw` must be a live handle this value takes ownership of.
5098    #[allow(dead_code)] // used by whichever methods return this type
5099    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2Box) -> Option<Self> {
5100        core::ptr::NonNull::new(raw).map(|raw| Box { raw })
5101    }
5102}
5103
5104// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
5105// is deliberately NOT implemented — the C++ types make no documented
5106// guarantee about concurrent use, and claiming one we haven't verified
5107// would be unsound. See `@bind thread_safe` in the plan.
5108unsafe impl Send for Box {}
5109
5110impl core::fmt::Debug for Box {
5111    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
5112        f.debug_struct("Box").finish_non_exhaustive()
5113    }
5114}
5115
5116impl Box {
5117    /// # Panics
5118    /// Panics if the native allocation fails.
5119    pub fn new() -> Self {
5120        // SAFETY: the native constructor returns a live handle; a null here
5121        // means the library is unusable.
5122        unsafe {
5123            let raw = ffi::whiteout_m2_M2Box_new();
5124            Self::from_raw(raw).expect("native Box allocation failed")
5125        }
5126    }
5127
5128    pub fn minimum(&self) -> crate::math::Vector3f {
5129        // SAFETY: the getter returns an interior pointer to a
5130        // layout-identical POD; we copy it out immediately.
5131        unsafe {
5132            *(ffi::whiteout_m2_M2Box_get_minimum(self.raw.as_ptr()) as *const crate::math::Vector3f)
5133        }
5134    }
5135
5136    pub fn set_minimum(&mut self, value: crate::math::Vector3f) {
5137        // SAFETY: as above, in the other direction.
5138        unsafe {
5139            ffi::whiteout_m2_M2Box_set_minimum(
5140                self.raw.as_ptr(),
5141                &value as *const crate::math::Vector3f as *const _,
5142            )
5143        }
5144    }
5145
5146    pub fn maximum(&self) -> crate::math::Vector3f {
5147        // SAFETY: the getter returns an interior pointer to a
5148        // layout-identical POD; we copy it out immediately.
5149        unsafe {
5150            *(ffi::whiteout_m2_M2Box_get_maximum(self.raw.as_ptr()) as *const crate::math::Vector3f)
5151        }
5152    }
5153
5154    pub fn set_maximum(&mut self, value: crate::math::Vector3f) {
5155        // SAFETY: as above, in the other direction.
5156        unsafe {
5157            ffi::whiteout_m2_M2Box_set_maximum(
5158                self.raw.as_ptr(),
5159                &value as *const crate::math::Vector3f as *const _,
5160            )
5161        }
5162    }
5163}
5164
5165impl Default for Box {
5166    fn default() -> Self {
5167        Self::new()
5168    }
5169}
5170
5171pub struct ParticleEmitter {
5172    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2ParticleEmitter>,
5173}
5174
5175impl Drop for ParticleEmitter {
5176    fn drop(&mut self) {
5177        // SAFETY: `raw` came from a native constructor and Drop runs once.
5178        unsafe { ffi::whiteout_m2_M2ParticleEmitter_delete(self.raw.as_ptr()) }
5179    }
5180}
5181
5182impl ParticleEmitter {
5183    /// # Safety
5184    /// `raw` must be a live handle this value takes ownership of.
5185    #[allow(dead_code)] // used by whichever methods return this type
5186    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2ParticleEmitter) -> Option<Self> {
5187        core::ptr::NonNull::new(raw).map(|raw| ParticleEmitter { raw })
5188    }
5189}
5190
5191// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
5192// is deliberately NOT implemented — the C++ types make no documented
5193// guarantee about concurrent use, and claiming one we haven't verified
5194// would be unsound. See `@bind thread_safe` in the plan.
5195unsafe impl Send for ParticleEmitter {}
5196
5197impl core::fmt::Debug for ParticleEmitter {
5198    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
5199        f.debug_struct("ParticleEmitter").finish_non_exhaustive()
5200    }
5201}
5202
5203impl ParticleEmitter {
5204    /// # Panics
5205    /// Panics if the native allocation fails.
5206    pub fn new() -> Self {
5207        // SAFETY: the native constructor returns a live handle; a null here
5208        // means the library is unusable.
5209        unsafe {
5210            let raw = ffi::whiteout_m2_M2ParticleEmitter_new();
5211            Self::from_raw(raw).expect("native ParticleEmitter allocation failed")
5212        }
5213    }
5214
5215    pub fn particle_id(&self) -> u32 {
5216        // SAFETY: plain scalar read through a live handle.
5217        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_particleId(self.raw.as_ptr()) }
5218    }
5219
5220    pub fn set_particle_id(&mut self, value: u32) {
5221        // SAFETY: plain scalar write through a live handle.
5222        unsafe { ffi::whiteout_m2_M2ParticleEmitter_set_particleId(self.raw.as_ptr(), value) }
5223    }
5224
5225    pub fn flags(&self) -> ParticleFlag {
5226        // SAFETY: scalar read; a flag set accepts any bits.
5227        ParticleFlag(unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_flags(self.raw.as_ptr()) })
5228    }
5229
5230    pub fn set_flags(&mut self, value: ParticleFlag) {
5231        // SAFETY: scalar write through a live handle.
5232        unsafe { ffi::whiteout_m2_M2ParticleEmitter_set_flags(self.raw.as_ptr(), value.0) }
5233    }
5234
5235    pub fn position(&self) -> crate::math::Vector3f {
5236        // SAFETY: the getter returns an interior pointer to a
5237        // layout-identical POD; we copy it out immediately.
5238        unsafe {
5239            *(ffi::whiteout_m2_M2ParticleEmitter_get_position(self.raw.as_ptr())
5240                as *const crate::math::Vector3f)
5241        }
5242    }
5243
5244    pub fn set_position(&mut self, value: crate::math::Vector3f) {
5245        // SAFETY: as above, in the other direction.
5246        unsafe {
5247            ffi::whiteout_m2_M2ParticleEmitter_set_position(
5248                self.raw.as_ptr(),
5249                &value as *const crate::math::Vector3f as *const _,
5250            )
5251        }
5252    }
5253
5254    pub fn bone_id(&self) -> u16 {
5255        // SAFETY: plain scalar read through a live handle.
5256        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_boneId(self.raw.as_ptr()) }
5257    }
5258
5259    pub fn set_bone_id(&mut self, value: u16) {
5260        // SAFETY: plain scalar write through a live handle.
5261        unsafe { ffi::whiteout_m2_M2ParticleEmitter_set_boneId(self.raw.as_ptr(), value) }
5262    }
5263
5264    pub fn particle_model_filename(&self) -> String {
5265        // SAFETY: the native side hands over an owned CString.
5266        unsafe {
5267            crate::support::take_string(
5268                ffi::whiteout_m2_M2ParticleEmitter_get_particleModelFilename(self.raw.as_ptr()),
5269            )
5270        }
5271    }
5272
5273    pub fn set_particle_model_filename(&mut self, value: &str) {
5274        let value = std::ffi::CString::new(value).unwrap_or_default();
5275        // SAFETY: the pointer outlives the call.
5276        unsafe {
5277            ffi::whiteout_m2_M2ParticleEmitter_set_particleModelFilename(
5278                self.raw.as_ptr(),
5279                value.as_ptr(),
5280            )
5281        }
5282    }
5283
5284    pub fn child_emitters_model_filename(&self) -> String {
5285        // SAFETY: the native side hands over an owned CString.
5286        unsafe {
5287            crate::support::take_string(
5288                ffi::whiteout_m2_M2ParticleEmitter_get_childEmittersModelFilename(
5289                    self.raw.as_ptr(),
5290                ),
5291            )
5292        }
5293    }
5294
5295    pub fn set_child_emitters_model_filename(&mut self, value: &str) {
5296        let value = std::ffi::CString::new(value).unwrap_or_default();
5297        // SAFETY: the pointer outlives the call.
5298        unsafe {
5299            ffi::whiteout_m2_M2ParticleEmitter_set_childEmittersModelFilename(
5300                self.raw.as_ptr(),
5301                value.as_ptr(),
5302            )
5303        }
5304    }
5305
5306    pub fn blending_type(&self) -> ParticleBlending {
5307        // SAFETY: scalar read; the discriminant is validated below.
5308        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_blendingType(self.raw.as_ptr()) }
5309            .try_into()
5310            .expect("unknown enum discriminant from the native library")
5311    }
5312
5313    pub fn set_blending_type(&mut self, value: ParticleBlending) {
5314        // SAFETY: scalar write through a live handle.
5315        unsafe {
5316            ffi::whiteout_m2_M2ParticleEmitter_set_blendingType(self.raw.as_ptr(), value as i32)
5317        }
5318    }
5319
5320    pub fn emitter_type(&self) -> ParticleEmitterType {
5321        // SAFETY: scalar read; the discriminant is validated below.
5322        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_emitterType(self.raw.as_ptr()) }
5323            .try_into()
5324            .expect("unknown enum discriminant from the native library")
5325    }
5326
5327    pub fn set_emitter_type(&mut self, value: ParticleEmitterType) {
5328        // SAFETY: scalar write through a live handle.
5329        unsafe {
5330            ffi::whiteout_m2_M2ParticleEmitter_set_emitterType(self.raw.as_ptr(), value as i32)
5331        }
5332    }
5333
5334    pub fn particle_color_index(&self) -> u16 {
5335        // SAFETY: plain scalar read through a live handle.
5336        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_particleColorIndex(self.raw.as_ptr()) }
5337    }
5338
5339    pub fn set_particle_color_index(&mut self, value: u16) {
5340        // SAFETY: plain scalar write through a live handle.
5341        unsafe {
5342            ffi::whiteout_m2_M2ParticleEmitter_set_particleColorIndex(self.raw.as_ptr(), value)
5343        }
5344    }
5345
5346    pub fn texture_tilerotation(&self) -> i16 {
5347        // SAFETY: plain scalar read through a live handle.
5348        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_textureTilerotation(self.raw.as_ptr()) }
5349    }
5350
5351    pub fn set_texture_tilerotation(&mut self, value: i16) {
5352        // SAFETY: plain scalar write through a live handle.
5353        unsafe {
5354            ffi::whiteout_m2_M2ParticleEmitter_set_textureTilerotation(self.raw.as_ptr(), value)
5355        }
5356    }
5357
5358    pub fn rows(&self) -> u16 {
5359        // SAFETY: plain scalar read through a live handle.
5360        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_rows(self.raw.as_ptr()) }
5361    }
5362
5363    pub fn set_rows(&mut self, value: u16) {
5364        // SAFETY: plain scalar write through a live handle.
5365        unsafe { ffi::whiteout_m2_M2ParticleEmitter_set_rows(self.raw.as_ptr(), value) }
5366    }
5367
5368    pub fn columns(&self) -> u16 {
5369        // SAFETY: plain scalar read through a live handle.
5370        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_columns(self.raw.as_ptr()) }
5371    }
5372
5373    pub fn set_columns(&mut self, value: u16) {
5374        // SAFETY: plain scalar write through a live handle.
5375        unsafe { ffi::whiteout_m2_M2ParticleEmitter_set_columns(self.raw.as_ptr(), value) }
5376    }
5377
5378    /// Borrows the field in place — no copy, no allocation.
5379    pub fn emission_speed(&self) -> crate::support::Ref<'_, AnimationTrackF32> {
5380        // SAFETY: an interior pointer into `self`, valid for this
5381        // borrow and never freed by the `Ref`.
5382        unsafe {
5383            crate::support::Ref::new(AnimationTrackF32 {
5384                raw: core::ptr::NonNull::new_unchecked(
5385                    ffi::whiteout_m2_M2ParticleEmitter_get_emissionSpeed(self.raw.as_ptr()),
5386                ),
5387            })
5388        }
5389    }
5390
5391    pub fn emission_speed_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackF32> {
5392        // SAFETY: as above; `&mut self` guarantees exclusivity.
5393        unsafe {
5394            crate::support::RefMut::new(AnimationTrackF32 {
5395                raw: core::ptr::NonNull::new_unchecked(
5396                    ffi::whiteout_m2_M2ParticleEmitter_get_emissionSpeed(self.raw.as_ptr()),
5397                ),
5398            })
5399        }
5400    }
5401
5402    /// Borrows the field in place — no copy, no allocation.
5403    pub fn speed_variation(&self) -> crate::support::Ref<'_, AnimationTrackF32> {
5404        // SAFETY: an interior pointer into `self`, valid for this
5405        // borrow and never freed by the `Ref`.
5406        unsafe {
5407            crate::support::Ref::new(AnimationTrackF32 {
5408                raw: core::ptr::NonNull::new_unchecked(
5409                    ffi::whiteout_m2_M2ParticleEmitter_get_speedVariation(self.raw.as_ptr()),
5410                ),
5411            })
5412        }
5413    }
5414
5415    pub fn speed_variation_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackF32> {
5416        // SAFETY: as above; `&mut self` guarantees exclusivity.
5417        unsafe {
5418            crate::support::RefMut::new(AnimationTrackF32 {
5419                raw: core::ptr::NonNull::new_unchecked(
5420                    ffi::whiteout_m2_M2ParticleEmitter_get_speedVariation(self.raw.as_ptr()),
5421                ),
5422            })
5423        }
5424    }
5425
5426    /// Borrows the field in place — no copy, no allocation.
5427    pub fn vertical_range(&self) -> crate::support::Ref<'_, AnimationTrackF32> {
5428        // SAFETY: an interior pointer into `self`, valid for this
5429        // borrow and never freed by the `Ref`.
5430        unsafe {
5431            crate::support::Ref::new(AnimationTrackF32 {
5432                raw: core::ptr::NonNull::new_unchecked(
5433                    ffi::whiteout_m2_M2ParticleEmitter_get_verticalRange(self.raw.as_ptr()),
5434                ),
5435            })
5436        }
5437    }
5438
5439    pub fn vertical_range_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackF32> {
5440        // SAFETY: as above; `&mut self` guarantees exclusivity.
5441        unsafe {
5442            crate::support::RefMut::new(AnimationTrackF32 {
5443                raw: core::ptr::NonNull::new_unchecked(
5444                    ffi::whiteout_m2_M2ParticleEmitter_get_verticalRange(self.raw.as_ptr()),
5445                ),
5446            })
5447        }
5448    }
5449
5450    /// Borrows the field in place — no copy, no allocation.
5451    pub fn horizontal_range(&self) -> crate::support::Ref<'_, AnimationTrackF32> {
5452        // SAFETY: an interior pointer into `self`, valid for this
5453        // borrow and never freed by the `Ref`.
5454        unsafe {
5455            crate::support::Ref::new(AnimationTrackF32 {
5456                raw: core::ptr::NonNull::new_unchecked(
5457                    ffi::whiteout_m2_M2ParticleEmitter_get_horizontalRange(self.raw.as_ptr()),
5458                ),
5459            })
5460        }
5461    }
5462
5463    pub fn horizontal_range_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackF32> {
5464        // SAFETY: as above; `&mut self` guarantees exclusivity.
5465        unsafe {
5466            crate::support::RefMut::new(AnimationTrackF32 {
5467                raw: core::ptr::NonNull::new_unchecked(
5468                    ffi::whiteout_m2_M2ParticleEmitter_get_horizontalRange(self.raw.as_ptr()),
5469                ),
5470            })
5471        }
5472    }
5473
5474    /// Borrows the field in place — no copy, no allocation.
5475    pub fn gravity(&self) -> crate::support::Ref<'_, AnimationTrackF32> {
5476        // SAFETY: an interior pointer into `self`, valid for this
5477        // borrow and never freed by the `Ref`.
5478        unsafe {
5479            crate::support::Ref::new(AnimationTrackF32 {
5480                raw: core::ptr::NonNull::new_unchecked(
5481                    ffi::whiteout_m2_M2ParticleEmitter_get_gravity(self.raw.as_ptr()),
5482                ),
5483            })
5484        }
5485    }
5486
5487    pub fn gravity_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackF32> {
5488        // SAFETY: as above; `&mut self` guarantees exclusivity.
5489        unsafe {
5490            crate::support::RefMut::new(AnimationTrackF32 {
5491                raw: core::ptr::NonNull::new_unchecked(
5492                    ffi::whiteout_m2_M2ParticleEmitter_get_gravity(self.raw.as_ptr()),
5493                ),
5494            })
5495        }
5496    }
5497
5498    /// Borrows the field in place — no copy, no allocation.
5499    pub fn lifespan(&self) -> crate::support::Ref<'_, AnimationTrackF32> {
5500        // SAFETY: an interior pointer into `self`, valid for this
5501        // borrow and never freed by the `Ref`.
5502        unsafe {
5503            crate::support::Ref::new(AnimationTrackF32 {
5504                raw: core::ptr::NonNull::new_unchecked(
5505                    ffi::whiteout_m2_M2ParticleEmitter_get_lifespan(self.raw.as_ptr()),
5506                ),
5507            })
5508        }
5509    }
5510
5511    pub fn lifespan_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackF32> {
5512        // SAFETY: as above; `&mut self` guarantees exclusivity.
5513        unsafe {
5514            crate::support::RefMut::new(AnimationTrackF32 {
5515                raw: core::ptr::NonNull::new_unchecked(
5516                    ffi::whiteout_m2_M2ParticleEmitter_get_lifespan(self.raw.as_ptr()),
5517                ),
5518            })
5519        }
5520    }
5521
5522    pub fn lifespan_variation(&self) -> f32 {
5523        // SAFETY: plain scalar read through a live handle.
5524        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_lifespanVariation(self.raw.as_ptr()) }
5525    }
5526
5527    pub fn set_lifespan_variation(&mut self, value: f32) {
5528        // SAFETY: plain scalar write through a live handle.
5529        unsafe {
5530            ffi::whiteout_m2_M2ParticleEmitter_set_lifespanVariation(self.raw.as_ptr(), value)
5531        }
5532    }
5533
5534    /// Borrows the field in place — no copy, no allocation.
5535    pub fn emission_rate(&self) -> crate::support::Ref<'_, AnimationTrackF32> {
5536        // SAFETY: an interior pointer into `self`, valid for this
5537        // borrow and never freed by the `Ref`.
5538        unsafe {
5539            crate::support::Ref::new(AnimationTrackF32 {
5540                raw: core::ptr::NonNull::new_unchecked(
5541                    ffi::whiteout_m2_M2ParticleEmitter_get_emissionRate(self.raw.as_ptr()),
5542                ),
5543            })
5544        }
5545    }
5546
5547    pub fn emission_rate_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackF32> {
5548        // SAFETY: as above; `&mut self` guarantees exclusivity.
5549        unsafe {
5550            crate::support::RefMut::new(AnimationTrackF32 {
5551                raw: core::ptr::NonNull::new_unchecked(
5552                    ffi::whiteout_m2_M2ParticleEmitter_get_emissionRate(self.raw.as_ptr()),
5553                ),
5554            })
5555        }
5556    }
5557
5558    pub fn emission_rate_variation(&self) -> f32 {
5559        // SAFETY: plain scalar read through a live handle.
5560        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_emissionRateVariation(self.raw.as_ptr()) }
5561    }
5562
5563    pub fn set_emission_rate_variation(&mut self, value: f32) {
5564        // SAFETY: plain scalar write through a live handle.
5565        unsafe {
5566            ffi::whiteout_m2_M2ParticleEmitter_set_emissionRateVariation(self.raw.as_ptr(), value)
5567        }
5568    }
5569
5570    /// Borrows the field in place — no copy, no allocation.
5571    pub fn emission_area_width(&self) -> crate::support::Ref<'_, AnimationTrackF32> {
5572        // SAFETY: an interior pointer into `self`, valid for this
5573        // borrow and never freed by the `Ref`.
5574        unsafe {
5575            crate::support::Ref::new(AnimationTrackF32 {
5576                raw: core::ptr::NonNull::new_unchecked(
5577                    ffi::whiteout_m2_M2ParticleEmitter_get_emissionAreaWidth(self.raw.as_ptr()),
5578                ),
5579            })
5580        }
5581    }
5582
5583    pub fn emission_area_width_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackF32> {
5584        // SAFETY: as above; `&mut self` guarantees exclusivity.
5585        unsafe {
5586            crate::support::RefMut::new(AnimationTrackF32 {
5587                raw: core::ptr::NonNull::new_unchecked(
5588                    ffi::whiteout_m2_M2ParticleEmitter_get_emissionAreaWidth(self.raw.as_ptr()),
5589                ),
5590            })
5591        }
5592    }
5593
5594    /// Borrows the field in place — no copy, no allocation.
5595    pub fn emission_area_length(&self) -> crate::support::Ref<'_, AnimationTrackF32> {
5596        // SAFETY: an interior pointer into `self`, valid for this
5597        // borrow and never freed by the `Ref`.
5598        unsafe {
5599            crate::support::Ref::new(AnimationTrackF32 {
5600                raw: core::ptr::NonNull::new_unchecked(
5601                    ffi::whiteout_m2_M2ParticleEmitter_get_emissionAreaLength(self.raw.as_ptr()),
5602                ),
5603            })
5604        }
5605    }
5606
5607    pub fn emission_area_length_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackF32> {
5608        // SAFETY: as above; `&mut self` guarantees exclusivity.
5609        unsafe {
5610            crate::support::RefMut::new(AnimationTrackF32 {
5611                raw: core::ptr::NonNull::new_unchecked(
5612                    ffi::whiteout_m2_M2ParticleEmitter_get_emissionAreaLength(self.raw.as_ptr()),
5613                ),
5614            })
5615        }
5616    }
5617
5618    /// Borrows the field in place — no copy, no allocation.
5619    pub fn z_source(&self) -> crate::support::Ref<'_, AnimationTrackF32> {
5620        // SAFETY: an interior pointer into `self`, valid for this
5621        // borrow and never freed by the `Ref`.
5622        unsafe {
5623            crate::support::Ref::new(AnimationTrackF32 {
5624                raw: core::ptr::NonNull::new_unchecked(
5625                    ffi::whiteout_m2_M2ParticleEmitter_get_zSource(self.raw.as_ptr()),
5626                ),
5627            })
5628        }
5629    }
5630
5631    pub fn z_source_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackF32> {
5632        // SAFETY: as above; `&mut self` guarantees exclusivity.
5633        unsafe {
5634            crate::support::RefMut::new(AnimationTrackF32 {
5635                raw: core::ptr::NonNull::new_unchecked(
5636                    ffi::whiteout_m2_M2ParticleEmitter_get_zSource(self.raw.as_ptr()),
5637                ),
5638            })
5639        }
5640    }
5641
5642    /// Borrows the field in place — no copy, no allocation.
5643    pub fn color_track(&self) -> crate::support::Ref<'_, ParticleAnimationTrackVector3f> {
5644        // SAFETY: an interior pointer into `self`, valid for this
5645        // borrow and never freed by the `Ref`.
5646        unsafe {
5647            crate::support::Ref::new(ParticleAnimationTrackVector3f {
5648                raw: core::ptr::NonNull::new_unchecked(
5649                    ffi::whiteout_m2_M2ParticleEmitter_get_colorTrack(self.raw.as_ptr()),
5650                ),
5651            })
5652        }
5653    }
5654
5655    pub fn color_track_mut(
5656        &mut self,
5657    ) -> crate::support::RefMut<'_, ParticleAnimationTrackVector3f> {
5658        // SAFETY: as above; `&mut self` guarantees exclusivity.
5659        unsafe {
5660            crate::support::RefMut::new(ParticleAnimationTrackVector3f {
5661                raw: core::ptr::NonNull::new_unchecked(
5662                    ffi::whiteout_m2_M2ParticleEmitter_get_colorTrack(self.raw.as_ptr()),
5663                ),
5664            })
5665        }
5666    }
5667
5668    /// Borrows the field in place — no copy, no allocation.
5669    pub fn scale_track(&self) -> crate::support::Ref<'_, ParticleAnimationTrackVector2f> {
5670        // SAFETY: an interior pointer into `self`, valid for this
5671        // borrow and never freed by the `Ref`.
5672        unsafe {
5673            crate::support::Ref::new(ParticleAnimationTrackVector2f {
5674                raw: core::ptr::NonNull::new_unchecked(
5675                    ffi::whiteout_m2_M2ParticleEmitter_get_scaleTrack(self.raw.as_ptr()),
5676                ),
5677            })
5678        }
5679    }
5680
5681    pub fn scale_track_mut(
5682        &mut self,
5683    ) -> crate::support::RefMut<'_, ParticleAnimationTrackVector2f> {
5684        // SAFETY: as above; `&mut self` guarantees exclusivity.
5685        unsafe {
5686            crate::support::RefMut::new(ParticleAnimationTrackVector2f {
5687                raw: core::ptr::NonNull::new_unchecked(
5688                    ffi::whiteout_m2_M2ParticleEmitter_get_scaleTrack(self.raw.as_ptr()),
5689                ),
5690            })
5691        }
5692    }
5693
5694    pub fn scale_vary(&self) -> crate::math::Vector2f {
5695        // SAFETY: the getter returns an interior pointer to a
5696        // layout-identical POD; we copy it out immediately.
5697        unsafe {
5698            *(ffi::whiteout_m2_M2ParticleEmitter_get_scaleVary(self.raw.as_ptr())
5699                as *const crate::math::Vector2f)
5700        }
5701    }
5702
5703    pub fn set_scale_vary(&mut self, value: crate::math::Vector2f) {
5704        // SAFETY: as above, in the other direction.
5705        unsafe {
5706            ffi::whiteout_m2_M2ParticleEmitter_set_scaleVary(
5707                self.raw.as_ptr(),
5708                &value as *const crate::math::Vector2f as *const _,
5709            )
5710        }
5711    }
5712
5713    pub fn tail_length(&self) -> f32 {
5714        // SAFETY: plain scalar read through a live handle.
5715        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_tailLength(self.raw.as_ptr()) }
5716    }
5717
5718    pub fn set_tail_length(&mut self, value: f32) {
5719        // SAFETY: plain scalar write through a live handle.
5720        unsafe { ffi::whiteout_m2_M2ParticleEmitter_set_tailLength(self.raw.as_ptr(), value) }
5721    }
5722
5723    pub fn twinkle_speed(&self) -> f32 {
5724        // SAFETY: plain scalar read through a live handle.
5725        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_twinkleSpeed(self.raw.as_ptr()) }
5726    }
5727
5728    pub fn set_twinkle_speed(&mut self, value: f32) {
5729        // SAFETY: plain scalar write through a live handle.
5730        unsafe { ffi::whiteout_m2_M2ParticleEmitter_set_twinkleSpeed(self.raw.as_ptr(), value) }
5731    }
5732
5733    pub fn twinkle_percent(&self) -> f32 {
5734        // SAFETY: plain scalar read through a live handle.
5735        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_twinklePercent(self.raw.as_ptr()) }
5736    }
5737
5738    pub fn set_twinkle_percent(&mut self, value: f32) {
5739        // SAFETY: plain scalar write through a live handle.
5740        unsafe { ffi::whiteout_m2_M2ParticleEmitter_set_twinklePercent(self.raw.as_ptr(), value) }
5741    }
5742
5743    pub fn twinkle_scale(&self) -> crate::math::Vector2f {
5744        // SAFETY: the getter returns an interior pointer to a
5745        // layout-identical POD; we copy it out immediately.
5746        unsafe {
5747            *(ffi::whiteout_m2_M2ParticleEmitter_get_twinkleScale(self.raw.as_ptr())
5748                as *const crate::math::Vector2f)
5749        }
5750    }
5751
5752    pub fn set_twinkle_scale(&mut self, value: crate::math::Vector2f) {
5753        // SAFETY: as above, in the other direction.
5754        unsafe {
5755            ffi::whiteout_m2_M2ParticleEmitter_set_twinkleScale(
5756                self.raw.as_ptr(),
5757                &value as *const crate::math::Vector2f as *const _,
5758            )
5759        }
5760    }
5761
5762    pub fn inherit_velocity_scale(&self) -> f32 {
5763        // SAFETY: plain scalar read through a live handle.
5764        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_inheritVelocityScale(self.raw.as_ptr()) }
5765    }
5766
5767    pub fn set_inherit_velocity_scale(&mut self, value: f32) {
5768        // SAFETY: plain scalar write through a live handle.
5769        unsafe {
5770            ffi::whiteout_m2_M2ParticleEmitter_set_inheritVelocityScale(self.raw.as_ptr(), value)
5771        }
5772    }
5773
5774    pub fn drag(&self) -> f32 {
5775        // SAFETY: plain scalar read through a live handle.
5776        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_drag(self.raw.as_ptr()) }
5777    }
5778
5779    pub fn set_drag(&mut self, value: f32) {
5780        // SAFETY: plain scalar write through a live handle.
5781        unsafe { ffi::whiteout_m2_M2ParticleEmitter_set_drag(self.raw.as_ptr(), value) }
5782    }
5783
5784    pub fn base_spin(&self) -> f32 {
5785        // SAFETY: plain scalar read through a live handle.
5786        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_baseSpin(self.raw.as_ptr()) }
5787    }
5788
5789    pub fn set_base_spin(&mut self, value: f32) {
5790        // SAFETY: plain scalar write through a live handle.
5791        unsafe { ffi::whiteout_m2_M2ParticleEmitter_set_baseSpin(self.raw.as_ptr(), value) }
5792    }
5793
5794    pub fn base_spin_variation(&self) -> f32 {
5795        // SAFETY: plain scalar read through a live handle.
5796        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_baseSpinVariation(self.raw.as_ptr()) }
5797    }
5798
5799    pub fn set_base_spin_variation(&mut self, value: f32) {
5800        // SAFETY: plain scalar write through a live handle.
5801        unsafe {
5802            ffi::whiteout_m2_M2ParticleEmitter_set_baseSpinVariation(self.raw.as_ptr(), value)
5803        }
5804    }
5805
5806    pub fn spin_speed(&self) -> f32 {
5807        // SAFETY: plain scalar read through a live handle.
5808        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_spinSpeed(self.raw.as_ptr()) }
5809    }
5810
5811    pub fn set_spin_speed(&mut self, value: f32) {
5812        // SAFETY: plain scalar write through a live handle.
5813        unsafe { ffi::whiteout_m2_M2ParticleEmitter_set_spinSpeed(self.raw.as_ptr(), value) }
5814    }
5815
5816    pub fn spin_speed_variation(&self) -> f32 {
5817        // SAFETY: plain scalar read through a live handle.
5818        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_spinSpeedVariation(self.raw.as_ptr()) }
5819    }
5820
5821    pub fn set_spin_speed_variation(&mut self, value: f32) {
5822        // SAFETY: plain scalar write through a live handle.
5823        unsafe {
5824            ffi::whiteout_m2_M2ParticleEmitter_set_spinSpeedVariation(self.raw.as_ptr(), value)
5825        }
5826    }
5827
5828    /// Borrows the field in place — no copy, no allocation.
5829    pub fn tumble(&self) -> crate::support::Ref<'_, Box> {
5830        // SAFETY: an interior pointer into `self`, valid for this
5831        // borrow and never freed by the `Ref`.
5832        unsafe {
5833            crate::support::Ref::new(Box {
5834                raw: core::ptr::NonNull::new_unchecked(
5835                    ffi::whiteout_m2_M2ParticleEmitter_get_tumble(self.raw.as_ptr()),
5836                ),
5837            })
5838        }
5839    }
5840
5841    pub fn tumble_mut(&mut self) -> crate::support::RefMut<'_, Box> {
5842        // SAFETY: as above; `&mut self` guarantees exclusivity.
5843        unsafe {
5844            crate::support::RefMut::new(Box {
5845                raw: core::ptr::NonNull::new_unchecked(
5846                    ffi::whiteout_m2_M2ParticleEmitter_get_tumble(self.raw.as_ptr()),
5847                ),
5848            })
5849        }
5850    }
5851
5852    pub fn wind_vector(&self) -> crate::math::Vector3f {
5853        // SAFETY: the getter returns an interior pointer to a
5854        // layout-identical POD; we copy it out immediately.
5855        unsafe {
5856            *(ffi::whiteout_m2_M2ParticleEmitter_get_windVector(self.raw.as_ptr())
5857                as *const crate::math::Vector3f)
5858        }
5859    }
5860
5861    pub fn set_wind_vector(&mut self, value: crate::math::Vector3f) {
5862        // SAFETY: as above, in the other direction.
5863        unsafe {
5864            ffi::whiteout_m2_M2ParticleEmitter_set_windVector(
5865                self.raw.as_ptr(),
5866                &value as *const crate::math::Vector3f as *const _,
5867            )
5868        }
5869    }
5870
5871    pub fn wind_time(&self) -> f32 {
5872        // SAFETY: plain scalar read through a live handle.
5873        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_windTime(self.raw.as_ptr()) }
5874    }
5875
5876    pub fn set_wind_time(&mut self, value: f32) {
5877        // SAFETY: plain scalar write through a live handle.
5878        unsafe { ffi::whiteout_m2_M2ParticleEmitter_set_windTime(self.raw.as_ptr(), value) }
5879    }
5880
5881    pub fn follow_speed_1(&self) -> f32 {
5882        // SAFETY: plain scalar read through a live handle.
5883        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_followSpeed1(self.raw.as_ptr()) }
5884    }
5885
5886    pub fn set_follow_speed_1(&mut self, value: f32) {
5887        // SAFETY: plain scalar write through a live handle.
5888        unsafe { ffi::whiteout_m2_M2ParticleEmitter_set_followSpeed1(self.raw.as_ptr(), value) }
5889    }
5890
5891    pub fn follow_scale_1(&self) -> f32 {
5892        // SAFETY: plain scalar read through a live handle.
5893        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_followScale1(self.raw.as_ptr()) }
5894    }
5895
5896    pub fn set_follow_scale_1(&mut self, value: f32) {
5897        // SAFETY: plain scalar write through a live handle.
5898        unsafe { ffi::whiteout_m2_M2ParticleEmitter_set_followScale1(self.raw.as_ptr(), value) }
5899    }
5900
5901    pub fn follow_speed_2(&self) -> f32 {
5902        // SAFETY: plain scalar read through a live handle.
5903        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_followSpeed2(self.raw.as_ptr()) }
5904    }
5905
5906    pub fn set_follow_speed_2(&mut self, value: f32) {
5907        // SAFETY: plain scalar write through a live handle.
5908        unsafe { ffi::whiteout_m2_M2ParticleEmitter_set_followSpeed2(self.raw.as_ptr(), value) }
5909    }
5910
5911    pub fn follow_scale_2(&self) -> f32 {
5912        // SAFETY: plain scalar read through a live handle.
5913        unsafe { ffi::whiteout_m2_M2ParticleEmitter_get_followScale2(self.raw.as_ptr()) }
5914    }
5915
5916    pub fn set_follow_scale_2(&mut self, value: f32) {
5917        // SAFETY: plain scalar write through a live handle.
5918        unsafe { ffi::whiteout_m2_M2ParticleEmitter_set_followScale2(self.raw.as_ptr(), value) }
5919    }
5920
5921    /// Zero-copy view of the underlying `std::vector`.
5922    pub fn spline_points(&self) -> &[crate::math::Vector3f] {
5923        // SAFETY: `_data`/`_count` describe one contiguous C++
5924        // allocation, borrowed for as long as `self` is.
5925        unsafe {
5926            let n = ffi::whiteout_m2_M2ParticleEmitter_get_splinePoints_count(self.raw.as_ptr());
5927            let p = ffi::whiteout_m2_M2ParticleEmitter_get_splinePoints_data(self.raw.as_ptr())
5928                as *const crate::math::Vector3f;
5929            if p.is_null() || n == 0 {
5930                &[]
5931            } else {
5932                core::slice::from_raw_parts(p, n)
5933            }
5934        }
5935    }
5936
5937    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
5938    pub fn spline_points_mut(&mut self) -> &mut [crate::math::Vector3f] {
5939        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
5940        unsafe {
5941            let n = ffi::whiteout_m2_M2ParticleEmitter_get_splinePoints_count(self.raw.as_ptr());
5942            let p = ffi::whiteout_m2_M2ParticleEmitter_get_splinePoints_data(self.raw.as_ptr())
5943                as *const crate::math::Vector3f as *mut crate::math::Vector3f;
5944            if p.is_null() || n == 0 {
5945                &mut []
5946            } else {
5947                core::slice::from_raw_parts_mut(p, n)
5948            }
5949        }
5950    }
5951
5952    pub fn set_spline_points(&mut self, values: &[crate::math::Vector3f]) {
5953        // SAFETY: the native side copies `values` before returning.
5954        unsafe {
5955            ffi::whiteout_m2_M2ParticleEmitter_assign_splinePoints(
5956                self.raw.as_ptr(),
5957                values.as_ptr() as *const _,
5958                values.len(),
5959            )
5960        }
5961    }
5962
5963    pub fn resize_spline_points(&mut self, count: usize) {
5964        // SAFETY: reallocation is safe here precisely because
5965        // `&mut self` means no slice borrow is outstanding.
5966        unsafe { ffi::whiteout_m2_M2ParticleEmitter_resize_splinePoints(self.raw.as_ptr(), count) }
5967    }
5968
5969    /// Borrows the field in place — no copy, no allocation.
5970    pub fn enabled_in(&self) -> crate::support::Ref<'_, AnimationTrackU8> {
5971        // SAFETY: an interior pointer into `self`, valid for this
5972        // borrow and never freed by the `Ref`.
5973        unsafe {
5974            crate::support::Ref::new(AnimationTrackU8 {
5975                raw: core::ptr::NonNull::new_unchecked(
5976                    ffi::whiteout_m2_M2ParticleEmitter_get_enabledIn(self.raw.as_ptr()),
5977                ),
5978            })
5979        }
5980    }
5981
5982    pub fn enabled_in_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackU8> {
5983        // SAFETY: as above; `&mut self` guarantees exclusivity.
5984        unsafe {
5985            crate::support::RefMut::new(AnimationTrackU8 {
5986                raw: core::ptr::NonNull::new_unchecked(
5987                    ffi::whiteout_m2_M2ParticleEmitter_get_enabledIn(self.raw.as_ptr()),
5988                ),
5989            })
5990        }
5991    }
5992}
5993
5994impl Default for ParticleEmitter {
5995    fn default() -> Self {
5996        Self::new()
5997    }
5998}
5999
6000pub struct Event {
6001    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2Event>,
6002}
6003
6004impl Drop for Event {
6005    fn drop(&mut self) {
6006        // SAFETY: `raw` came from a native constructor and Drop runs once.
6007        unsafe { ffi::whiteout_m2_M2Event_delete(self.raw.as_ptr()) }
6008    }
6009}
6010
6011impl Event {
6012    /// # Safety
6013    /// `raw` must be a live handle this value takes ownership of.
6014    #[allow(dead_code)] // used by whichever methods return this type
6015    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2Event) -> Option<Self> {
6016        core::ptr::NonNull::new(raw).map(|raw| Event { raw })
6017    }
6018}
6019
6020// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
6021// is deliberately NOT implemented — the C++ types make no documented
6022// guarantee about concurrent use, and claiming one we haven't verified
6023// would be unsound. See `@bind thread_safe` in the plan.
6024unsafe impl Send for Event {}
6025
6026impl core::fmt::Debug for Event {
6027    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
6028        f.debug_struct("Event").finish_non_exhaustive()
6029    }
6030}
6031
6032impl Event {
6033    /// # Panics
6034    /// Panics if the native allocation fails.
6035    pub fn new() -> Self {
6036        // SAFETY: the native constructor returns a live handle; a null here
6037        // means the library is unusable.
6038        unsafe {
6039            let raw = ffi::whiteout_m2_M2Event_new();
6040            Self::from_raw(raw).expect("native Event allocation failed")
6041        }
6042    }
6043
6044    pub fn identifier(&self) -> u32 {
6045        // SAFETY: plain scalar read through a live handle.
6046        unsafe { ffi::whiteout_m2_M2Event_get_identifier(self.raw.as_ptr()) }
6047    }
6048
6049    pub fn set_identifier(&mut self, value: u32) {
6050        // SAFETY: plain scalar write through a live handle.
6051        unsafe { ffi::whiteout_m2_M2Event_set_identifier(self.raw.as_ptr(), value) }
6052    }
6053
6054    pub fn data(&self) -> u32 {
6055        // SAFETY: plain scalar read through a live handle.
6056        unsafe { ffi::whiteout_m2_M2Event_get_data(self.raw.as_ptr()) }
6057    }
6058
6059    pub fn set_data(&mut self, value: u32) {
6060        // SAFETY: plain scalar write through a live handle.
6061        unsafe { ffi::whiteout_m2_M2Event_set_data(self.raw.as_ptr(), value) }
6062    }
6063
6064    pub fn bone_id(&self) -> u32 {
6065        // SAFETY: plain scalar read through a live handle.
6066        unsafe { ffi::whiteout_m2_M2Event_get_boneId(self.raw.as_ptr()) }
6067    }
6068
6069    pub fn set_bone_id(&mut self, value: u32) {
6070        // SAFETY: plain scalar write through a live handle.
6071        unsafe { ffi::whiteout_m2_M2Event_set_boneId(self.raw.as_ptr(), value) }
6072    }
6073
6074    pub fn position(&self) -> crate::math::Vector3f {
6075        // SAFETY: the getter returns an interior pointer to a
6076        // layout-identical POD; we copy it out immediately.
6077        unsafe {
6078            *(ffi::whiteout_m2_M2Event_get_position(self.raw.as_ptr())
6079                as *const crate::math::Vector3f)
6080        }
6081    }
6082
6083    pub fn set_position(&mut self, value: crate::math::Vector3f) {
6084        // SAFETY: as above, in the other direction.
6085        unsafe {
6086            ffi::whiteout_m2_M2Event_set_position(
6087                self.raw.as_ptr(),
6088                &value as *const crate::math::Vector3f as *const _,
6089            )
6090        }
6091    }
6092
6093    /// Borrows the field in place — no copy, no allocation.
6094    pub fn enabled(&self) -> crate::support::Ref<'_, AnimationTrackBase> {
6095        // SAFETY: an interior pointer into `self`, valid for this
6096        // borrow and never freed by the `Ref`.
6097        unsafe {
6098            crate::support::Ref::new(AnimationTrackBase {
6099                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Event_get_enabled(
6100                    self.raw.as_ptr(),
6101                )),
6102            })
6103        }
6104    }
6105
6106    pub fn enabled_mut(&mut self) -> crate::support::RefMut<'_, AnimationTrackBase> {
6107        // SAFETY: as above; `&mut self` guarantees exclusivity.
6108        unsafe {
6109            crate::support::RefMut::new(AnimationTrackBase {
6110                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Event_get_enabled(
6111                    self.raw.as_ptr(),
6112                )),
6113            })
6114        }
6115    }
6116}
6117
6118impl Default for Event {
6119    fn default() -> Self {
6120        Self::new()
6121    }
6122}
6123
6124pub struct Model {
6125    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2Model>,
6126}
6127
6128impl Drop for Model {
6129    fn drop(&mut self) {
6130        // SAFETY: `raw` came from a native constructor and Drop runs once.
6131        unsafe { ffi::whiteout_m2_M2Model_delete(self.raw.as_ptr()) }
6132    }
6133}
6134
6135impl Model {
6136    /// # Safety
6137    /// `raw` must be a live handle this value takes ownership of.
6138    #[allow(dead_code)] // used by whichever methods return this type
6139    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2Model) -> Option<Self> {
6140        core::ptr::NonNull::new(raw).map(|raw| Model { raw })
6141    }
6142}
6143
6144// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
6145// is deliberately NOT implemented — the C++ types make no documented
6146// guarantee about concurrent use, and claiming one we haven't verified
6147// would be unsound. See `@bind thread_safe` in the plan.
6148unsafe impl Send for Model {}
6149
6150impl core::fmt::Debug for Model {
6151    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
6152        f.debug_struct("Model").finish_non_exhaustive()
6153    }
6154}
6155
6156impl Model {
6157    /// # Panics
6158    /// Panics if the native allocation fails.
6159    pub fn new() -> Self {
6160        // SAFETY: the native constructor returns a live handle; a null here
6161        // means the library is unusable.
6162        unsafe {
6163            let raw = ffi::whiteout_m2_M2Model_new();
6164            Self::from_raw(raw).expect("native Model allocation failed")
6165        }
6166    }
6167
6168    pub fn model_name(&self) -> String {
6169        // SAFETY: the native side hands over an owned CString.
6170        unsafe {
6171            crate::support::take_string(ffi::whiteout_m2_M2Model_get_modelName(self.raw.as_ptr()))
6172        }
6173    }
6174
6175    pub fn set_model_name(&mut self, value: &str) {
6176        let value = std::ffi::CString::new(value).unwrap_or_default();
6177        // SAFETY: the pointer outlives the call.
6178        unsafe { ffi::whiteout_m2_M2Model_set_modelName(self.raw.as_ptr(), value.as_ptr()) }
6179    }
6180
6181    /// Borrows the field in place — no copy, no allocation.
6182    pub fn global_flags(&self) -> crate::support::Ref<'_, GlobalFlags> {
6183        // SAFETY: an interior pointer into `self`, valid for this
6184        // borrow and never freed by the `Ref`.
6185        unsafe {
6186            crate::support::Ref::new(GlobalFlags {
6187                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_globalFlags(
6188                    self.raw.as_ptr(),
6189                )),
6190            })
6191        }
6192    }
6193
6194    pub fn global_flags_mut(&mut self) -> crate::support::RefMut<'_, GlobalFlags> {
6195        // SAFETY: as above; `&mut self` guarantees exclusivity.
6196        unsafe {
6197            crate::support::RefMut::new(GlobalFlags {
6198                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_globalFlags(
6199                    self.raw.as_ptr(),
6200                )),
6201            })
6202        }
6203    }
6204
6205    pub fn global_loops_len(&self) -> usize {
6206        // SAFETY: scalar read through a live handle.
6207        unsafe { ffi::whiteout_m2_M2Model_get_globalLoops_count(self.raw.as_ptr()) }
6208    }
6209
6210    /// Borrows element `index` in place. `None` when out of range.
6211    pub fn global_loops(&self, index: usize) -> Option<crate::support::Ref<'_, GlobalSequence>> {
6212        if index >= self.global_loops_len() {
6213            return None;
6214        }
6215        // SAFETY: index checked above; the pointer is interior to `self`.
6216        unsafe {
6217            Some(crate::support::Ref::new(GlobalSequence {
6218                raw: core::ptr::NonNull::new_unchecked(
6219                    ffi::whiteout_m2_M2Model_get_globalLoops_at(self.raw.as_ptr(), index),
6220                ),
6221            }))
6222        }
6223    }
6224
6225    pub fn global_loops_mut(
6226        &mut self,
6227        index: usize,
6228    ) -> Option<crate::support::RefMut<'_, GlobalSequence>> {
6229        if index >= self.global_loops_len() {
6230            return None;
6231        }
6232        // SAFETY: as above; `&mut self` guarantees exclusivity.
6233        unsafe {
6234            Some(crate::support::RefMut::new(GlobalSequence {
6235                raw: core::ptr::NonNull::new_unchecked(
6236                    ffi::whiteout_m2_M2Model_get_globalLoops_at(self.raw.as_ptr(), index),
6237                ),
6238            }))
6239        }
6240    }
6241
6242    /// Iterate the elements, borrowing each in turn.
6243    pub fn global_loops_iter(
6244        &self,
6245    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, GlobalSequence>> {
6246        (0..self.global_loops_len()).map(move |i| self.global_loops(i).expect("index below len"))
6247    }
6248
6249    pub fn resize_global_loops(&mut self, count: usize) {
6250        // SAFETY: exclusive access, so no borrow is outstanding.
6251        unsafe { ffi::whiteout_m2_M2Model_resize_globalLoops(self.raw.as_ptr(), count) }
6252    }
6253
6254    pub fn sequences_len(&self) -> usize {
6255        // SAFETY: scalar read through a live handle.
6256        unsafe { ffi::whiteout_m2_M2Model_get_sequences_count(self.raw.as_ptr()) }
6257    }
6258
6259    /// Borrows element `index` in place. `None` when out of range.
6260    pub fn sequences(&self, index: usize) -> Option<crate::support::Ref<'_, Sequence>> {
6261        if index >= self.sequences_len() {
6262            return None;
6263        }
6264        // SAFETY: index checked above; the pointer is interior to `self`.
6265        unsafe {
6266            Some(crate::support::Ref::new(Sequence {
6267                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_sequences_at(
6268                    self.raw.as_ptr(),
6269                    index,
6270                )),
6271            }))
6272        }
6273    }
6274
6275    pub fn sequences_mut(&mut self, index: usize) -> Option<crate::support::RefMut<'_, Sequence>> {
6276        if index >= self.sequences_len() {
6277            return None;
6278        }
6279        // SAFETY: as above; `&mut self` guarantees exclusivity.
6280        unsafe {
6281            Some(crate::support::RefMut::new(Sequence {
6282                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_sequences_at(
6283                    self.raw.as_ptr(),
6284                    index,
6285                )),
6286            }))
6287        }
6288    }
6289
6290    /// Iterate the elements, borrowing each in turn.
6291    pub fn sequences_iter(
6292        &self,
6293    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, Sequence>> {
6294        (0..self.sequences_len()).map(move |i| self.sequences(i).expect("index below len"))
6295    }
6296
6297    pub fn resize_sequences(&mut self, count: usize) {
6298        // SAFETY: exclusive access, so no borrow is outstanding.
6299        unsafe { ffi::whiteout_m2_M2Model_resize_sequences(self.raw.as_ptr(), count) }
6300    }
6301
6302    /// Zero-copy view of the underlying `std::vector`.
6303    pub fn sequence_idx_hash_by_id(&self) -> &[u16] {
6304        // SAFETY: `_data`/`_count` describe one contiguous C++
6305        // allocation, borrowed for as long as `self` is.
6306        unsafe {
6307            let n = ffi::whiteout_m2_M2Model_get_sequenceIdxHashById_count(self.raw.as_ptr());
6308            let p = ffi::whiteout_m2_M2Model_get_sequenceIdxHashById_data(self.raw.as_ptr());
6309            if p.is_null() || n == 0 {
6310                &[]
6311            } else {
6312                core::slice::from_raw_parts(p, n)
6313            }
6314        }
6315    }
6316
6317    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
6318    pub fn sequence_idx_hash_by_id_mut(&mut self) -> &mut [u16] {
6319        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
6320        unsafe {
6321            let n = ffi::whiteout_m2_M2Model_get_sequenceIdxHashById_count(self.raw.as_ptr());
6322            let p = ffi::whiteout_m2_M2Model_get_sequenceIdxHashById_data(self.raw.as_ptr())
6323                as *mut u16;
6324            if p.is_null() || n == 0 {
6325                &mut []
6326            } else {
6327                core::slice::from_raw_parts_mut(p, n)
6328            }
6329        }
6330    }
6331
6332    pub fn set_sequence_idx_hash_by_id(&mut self, values: &[u16]) {
6333        // SAFETY: the native side copies `values` before returning.
6334        unsafe {
6335            ffi::whiteout_m2_M2Model_assign_sequenceIdxHashById(
6336                self.raw.as_ptr(),
6337                values.as_ptr() as *const _,
6338                values.len(),
6339            )
6340        }
6341    }
6342
6343    pub fn resize_sequence_idx_hash_by_id(&mut self, count: usize) {
6344        // SAFETY: reallocation is safe here precisely because
6345        // `&mut self` means no slice borrow is outstanding.
6346        unsafe { ffi::whiteout_m2_M2Model_resize_sequenceIdxHashById(self.raw.as_ptr(), count) }
6347    }
6348
6349    pub fn bones_len(&self) -> usize {
6350        // SAFETY: scalar read through a live handle.
6351        unsafe { ffi::whiteout_m2_M2Model_get_bones_count(self.raw.as_ptr()) }
6352    }
6353
6354    /// Borrows element `index` in place. `None` when out of range.
6355    pub fn bones(&self, index: usize) -> Option<crate::support::Ref<'_, Bone>> {
6356        if index >= self.bones_len() {
6357            return None;
6358        }
6359        // SAFETY: index checked above; the pointer is interior to `self`.
6360        unsafe {
6361            Some(crate::support::Ref::new(Bone {
6362                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_bones_at(
6363                    self.raw.as_ptr(),
6364                    index,
6365                )),
6366            }))
6367        }
6368    }
6369
6370    pub fn bones_mut(&mut self, index: usize) -> Option<crate::support::RefMut<'_, Bone>> {
6371        if index >= self.bones_len() {
6372            return None;
6373        }
6374        // SAFETY: as above; `&mut self` guarantees exclusivity.
6375        unsafe {
6376            Some(crate::support::RefMut::new(Bone {
6377                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_bones_at(
6378                    self.raw.as_ptr(),
6379                    index,
6380                )),
6381            }))
6382        }
6383    }
6384
6385    /// Iterate the elements, borrowing each in turn.
6386    pub fn bones_iter(&self) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, Bone>> {
6387        (0..self.bones_len()).map(move |i| self.bones(i).expect("index below len"))
6388    }
6389
6390    pub fn resize_bones(&mut self, count: usize) {
6391        // SAFETY: exclusive access, so no borrow is outstanding.
6392        unsafe { ffi::whiteout_m2_M2Model_resize_bones(self.raw.as_ptr(), count) }
6393    }
6394
6395    /// Zero-copy view of the underlying `std::vector`.
6396    pub fn key_bone_ids(&self) -> &[u16] {
6397        // SAFETY: `_data`/`_count` describe one contiguous C++
6398        // allocation, borrowed for as long as `self` is.
6399        unsafe {
6400            let n = ffi::whiteout_m2_M2Model_get_keyBoneIds_count(self.raw.as_ptr());
6401            let p = ffi::whiteout_m2_M2Model_get_keyBoneIds_data(self.raw.as_ptr());
6402            if p.is_null() || n == 0 {
6403                &[]
6404            } else {
6405                core::slice::from_raw_parts(p, n)
6406            }
6407        }
6408    }
6409
6410    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
6411    pub fn key_bone_ids_mut(&mut self) -> &mut [u16] {
6412        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
6413        unsafe {
6414            let n = ffi::whiteout_m2_M2Model_get_keyBoneIds_count(self.raw.as_ptr());
6415            let p = ffi::whiteout_m2_M2Model_get_keyBoneIds_data(self.raw.as_ptr()) as *mut u16;
6416            if p.is_null() || n == 0 {
6417                &mut []
6418            } else {
6419                core::slice::from_raw_parts_mut(p, n)
6420            }
6421        }
6422    }
6423
6424    pub fn set_key_bone_ids(&mut self, values: &[u16]) {
6425        // SAFETY: the native side copies `values` before returning.
6426        unsafe {
6427            ffi::whiteout_m2_M2Model_assign_keyBoneIds(
6428                self.raw.as_ptr(),
6429                values.as_ptr() as *const _,
6430                values.len(),
6431            )
6432        }
6433    }
6434
6435    pub fn resize_key_bone_ids(&mut self, count: usize) {
6436        // SAFETY: reallocation is safe here precisely because
6437        // `&mut self` means no slice borrow is outstanding.
6438        unsafe { ffi::whiteout_m2_M2Model_resize_keyBoneIds(self.raw.as_ptr(), count) }
6439    }
6440
6441    pub fn vertices_len(&self) -> usize {
6442        // SAFETY: scalar read through a live handle.
6443        unsafe { ffi::whiteout_m2_M2Model_get_vertices_count(self.raw.as_ptr()) }
6444    }
6445
6446    /// Borrows element `index` in place. `None` when out of range.
6447    pub fn vertices(&self, index: usize) -> Option<crate::support::Ref<'_, Vertex>> {
6448        if index >= self.vertices_len() {
6449            return None;
6450        }
6451        // SAFETY: index checked above; the pointer is interior to `self`.
6452        unsafe {
6453            Some(crate::support::Ref::new(Vertex {
6454                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_vertices_at(
6455                    self.raw.as_ptr(),
6456                    index,
6457                )),
6458            }))
6459        }
6460    }
6461
6462    pub fn vertices_mut(&mut self, index: usize) -> Option<crate::support::RefMut<'_, Vertex>> {
6463        if index >= self.vertices_len() {
6464            return None;
6465        }
6466        // SAFETY: as above; `&mut self` guarantees exclusivity.
6467        unsafe {
6468            Some(crate::support::RefMut::new(Vertex {
6469                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_vertices_at(
6470                    self.raw.as_ptr(),
6471                    index,
6472                )),
6473            }))
6474        }
6475    }
6476
6477    /// Iterate the elements, borrowing each in turn.
6478    pub fn vertices_iter(&self) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, Vertex>> {
6479        (0..self.vertices_len()).map(move |i| self.vertices(i).expect("index below len"))
6480    }
6481
6482    pub fn resize_vertices(&mut self, count: usize) {
6483        // SAFETY: exclusive access, so no borrow is outstanding.
6484        unsafe { ffi::whiteout_m2_M2Model_resize_vertices(self.raw.as_ptr(), count) }
6485    }
6486
6487    pub fn skin_profiles_len(&self) -> usize {
6488        // SAFETY: scalar read through a live handle.
6489        unsafe { ffi::whiteout_m2_M2Model_get_skinProfiles_count(self.raw.as_ptr()) }
6490    }
6491
6492    /// Borrows element `index` in place. `None` when out of range.
6493    pub fn skin_profiles(&self, index: usize) -> Option<crate::support::Ref<'_, SkinProfile>> {
6494        if index >= self.skin_profiles_len() {
6495            return None;
6496        }
6497        // SAFETY: index checked above; the pointer is interior to `self`.
6498        unsafe {
6499            Some(crate::support::Ref::new(SkinProfile {
6500                raw: core::ptr::NonNull::new_unchecked(
6501                    ffi::whiteout_m2_M2Model_get_skinProfiles_at(self.raw.as_ptr(), index),
6502                ),
6503            }))
6504        }
6505    }
6506
6507    pub fn skin_profiles_mut(
6508        &mut self,
6509        index: usize,
6510    ) -> Option<crate::support::RefMut<'_, SkinProfile>> {
6511        if index >= self.skin_profiles_len() {
6512            return None;
6513        }
6514        // SAFETY: as above; `&mut self` guarantees exclusivity.
6515        unsafe {
6516            Some(crate::support::RefMut::new(SkinProfile {
6517                raw: core::ptr::NonNull::new_unchecked(
6518                    ffi::whiteout_m2_M2Model_get_skinProfiles_at(self.raw.as_ptr(), index),
6519                ),
6520            }))
6521        }
6522    }
6523
6524    /// Iterate the elements, borrowing each in turn.
6525    pub fn skin_profiles_iter(
6526        &self,
6527    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, SkinProfile>> {
6528        (0..self.skin_profiles_len()).map(move |i| self.skin_profiles(i).expect("index below len"))
6529    }
6530
6531    pub fn resize_skin_profiles(&mut self, count: usize) {
6532        // SAFETY: exclusive access, so no borrow is outstanding.
6533        unsafe { ffi::whiteout_m2_M2Model_resize_skinProfiles(self.raw.as_ptr(), count) }
6534    }
6535
6536    pub fn lod_profiles_len(&self) -> usize {
6537        // SAFETY: scalar read through a live handle.
6538        unsafe { ffi::whiteout_m2_M2Model_get_lodProfiles_count(self.raw.as_ptr()) }
6539    }
6540
6541    /// Borrows element `index` in place. `None` when out of range.
6542    pub fn lod_profiles(&self, index: usize) -> Option<crate::support::Ref<'_, SkinProfile>> {
6543        if index >= self.lod_profiles_len() {
6544            return None;
6545        }
6546        // SAFETY: index checked above; the pointer is interior to `self`.
6547        unsafe {
6548            Some(crate::support::Ref::new(SkinProfile {
6549                raw: core::ptr::NonNull::new_unchecked(
6550                    ffi::whiteout_m2_M2Model_get_lodProfiles_at(self.raw.as_ptr(), index),
6551                ),
6552            }))
6553        }
6554    }
6555
6556    pub fn lod_profiles_mut(
6557        &mut self,
6558        index: usize,
6559    ) -> Option<crate::support::RefMut<'_, SkinProfile>> {
6560        if index >= self.lod_profiles_len() {
6561            return None;
6562        }
6563        // SAFETY: as above; `&mut self` guarantees exclusivity.
6564        unsafe {
6565            Some(crate::support::RefMut::new(SkinProfile {
6566                raw: core::ptr::NonNull::new_unchecked(
6567                    ffi::whiteout_m2_M2Model_get_lodProfiles_at(self.raw.as_ptr(), index),
6568                ),
6569            }))
6570        }
6571    }
6572
6573    /// Iterate the elements, borrowing each in turn.
6574    pub fn lod_profiles_iter(
6575        &self,
6576    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, SkinProfile>> {
6577        (0..self.lod_profiles_len()).map(move |i| self.lod_profiles(i).expect("index below len"))
6578    }
6579
6580    pub fn resize_lod_profiles(&mut self, count: usize) {
6581        // SAFETY: exclusive access, so no borrow is outstanding.
6582        unsafe { ffi::whiteout_m2_M2Model_resize_lodProfiles(self.raw.as_ptr(), count) }
6583    }
6584
6585    pub fn num_skin_profiles(&self) -> u32 {
6586        // SAFETY: plain scalar read through a live handle.
6587        unsafe { ffi::whiteout_m2_M2Model_get_numSkinProfiles(self.raw.as_ptr()) }
6588    }
6589
6590    pub fn set_num_skin_profiles(&mut self, value: u32) {
6591        // SAFETY: plain scalar write through a live handle.
6592        unsafe { ffi::whiteout_m2_M2Model_set_numSkinProfiles(self.raw.as_ptr(), value) }
6593    }
6594
6595    pub fn colors_len(&self) -> usize {
6596        // SAFETY: scalar read through a live handle.
6597        unsafe { ffi::whiteout_m2_M2Model_get_colors_count(self.raw.as_ptr()) }
6598    }
6599
6600    /// Borrows element `index` in place. `None` when out of range.
6601    pub fn colors(&self, index: usize) -> Option<crate::support::Ref<'_, ColorAnimation>> {
6602        if index >= self.colors_len() {
6603            return None;
6604        }
6605        // SAFETY: index checked above; the pointer is interior to `self`.
6606        unsafe {
6607            Some(crate::support::Ref::new(ColorAnimation {
6608                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_colors_at(
6609                    self.raw.as_ptr(),
6610                    index,
6611                )),
6612            }))
6613        }
6614    }
6615
6616    pub fn colors_mut(
6617        &mut self,
6618        index: usize,
6619    ) -> Option<crate::support::RefMut<'_, ColorAnimation>> {
6620        if index >= self.colors_len() {
6621            return None;
6622        }
6623        // SAFETY: as above; `&mut self` guarantees exclusivity.
6624        unsafe {
6625            Some(crate::support::RefMut::new(ColorAnimation {
6626                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_colors_at(
6627                    self.raw.as_ptr(),
6628                    index,
6629                )),
6630            }))
6631        }
6632    }
6633
6634    /// Iterate the elements, borrowing each in turn.
6635    pub fn colors_iter(
6636        &self,
6637    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, ColorAnimation>> {
6638        (0..self.colors_len()).map(move |i| self.colors(i).expect("index below len"))
6639    }
6640
6641    pub fn resize_colors(&mut self, count: usize) {
6642        // SAFETY: exclusive access, so no borrow is outstanding.
6643        unsafe { ffi::whiteout_m2_M2Model_resize_colors(self.raw.as_ptr(), count) }
6644    }
6645
6646    pub fn textures_len(&self) -> usize {
6647        // SAFETY: scalar read through a live handle.
6648        unsafe { ffi::whiteout_m2_M2Model_get_textures_count(self.raw.as_ptr()) }
6649    }
6650
6651    /// Borrows element `index` in place. `None` when out of range.
6652    pub fn textures(&self, index: usize) -> Option<crate::support::Ref<'_, Texture>> {
6653        if index >= self.textures_len() {
6654            return None;
6655        }
6656        // SAFETY: index checked above; the pointer is interior to `self`.
6657        unsafe {
6658            Some(crate::support::Ref::new(Texture {
6659                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_textures_at(
6660                    self.raw.as_ptr(),
6661                    index,
6662                )),
6663            }))
6664        }
6665    }
6666
6667    pub fn textures_mut(&mut self, index: usize) -> Option<crate::support::RefMut<'_, Texture>> {
6668        if index >= self.textures_len() {
6669            return None;
6670        }
6671        // SAFETY: as above; `&mut self` guarantees exclusivity.
6672        unsafe {
6673            Some(crate::support::RefMut::new(Texture {
6674                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_textures_at(
6675                    self.raw.as_ptr(),
6676                    index,
6677                )),
6678            }))
6679        }
6680    }
6681
6682    /// Iterate the elements, borrowing each in turn.
6683    pub fn textures_iter(&self) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, Texture>> {
6684        (0..self.textures_len()).map(move |i| self.textures(i).expect("index below len"))
6685    }
6686
6687    pub fn resize_textures(&mut self, count: usize) {
6688        // SAFETY: exclusive access, so no borrow is outstanding.
6689        unsafe { ffi::whiteout_m2_M2Model_resize_textures(self.raw.as_ptr(), count) }
6690    }
6691
6692    pub fn texture_weights_len(&self) -> usize {
6693        // SAFETY: scalar read through a live handle.
6694        unsafe { ffi::whiteout_m2_M2Model_get_textureWeights_count(self.raw.as_ptr()) }
6695    }
6696
6697    /// Borrows element `index` in place. `None` when out of range.
6698    pub fn texture_weights(&self, index: usize) -> Option<crate::support::Ref<'_, TextureWeight>> {
6699        if index >= self.texture_weights_len() {
6700            return None;
6701        }
6702        // SAFETY: index checked above; the pointer is interior to `self`.
6703        unsafe {
6704            Some(crate::support::Ref::new(TextureWeight {
6705                raw: core::ptr::NonNull::new_unchecked(
6706                    ffi::whiteout_m2_M2Model_get_textureWeights_at(self.raw.as_ptr(), index),
6707                ),
6708            }))
6709        }
6710    }
6711
6712    pub fn texture_weights_mut(
6713        &mut self,
6714        index: usize,
6715    ) -> Option<crate::support::RefMut<'_, TextureWeight>> {
6716        if index >= self.texture_weights_len() {
6717            return None;
6718        }
6719        // SAFETY: as above; `&mut self` guarantees exclusivity.
6720        unsafe {
6721            Some(crate::support::RefMut::new(TextureWeight {
6722                raw: core::ptr::NonNull::new_unchecked(
6723                    ffi::whiteout_m2_M2Model_get_textureWeights_at(self.raw.as_ptr(), index),
6724                ),
6725            }))
6726        }
6727    }
6728
6729    /// Iterate the elements, borrowing each in turn.
6730    pub fn texture_weights_iter(
6731        &self,
6732    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, TextureWeight>> {
6733        (0..self.texture_weights_len())
6734            .map(move |i| self.texture_weights(i).expect("index below len"))
6735    }
6736
6737    pub fn resize_texture_weights(&mut self, count: usize) {
6738        // SAFETY: exclusive access, so no borrow is outstanding.
6739        unsafe { ffi::whiteout_m2_M2Model_resize_textureWeights(self.raw.as_ptr(), count) }
6740    }
6741
6742    pub fn texture_transforms_len(&self) -> usize {
6743        // SAFETY: scalar read through a live handle.
6744        unsafe { ffi::whiteout_m2_M2Model_get_textureTransforms_count(self.raw.as_ptr()) }
6745    }
6746
6747    /// Borrows element `index` in place. `None` when out of range.
6748    pub fn texture_transforms(
6749        &self,
6750        index: usize,
6751    ) -> Option<crate::support::Ref<'_, TextureTransform>> {
6752        if index >= self.texture_transforms_len() {
6753            return None;
6754        }
6755        // SAFETY: index checked above; the pointer is interior to `self`.
6756        unsafe {
6757            Some(crate::support::Ref::new(TextureTransform {
6758                raw: core::ptr::NonNull::new_unchecked(
6759                    ffi::whiteout_m2_M2Model_get_textureTransforms_at(self.raw.as_ptr(), index),
6760                ),
6761            }))
6762        }
6763    }
6764
6765    pub fn texture_transforms_mut(
6766        &mut self,
6767        index: usize,
6768    ) -> Option<crate::support::RefMut<'_, TextureTransform>> {
6769        if index >= self.texture_transforms_len() {
6770            return None;
6771        }
6772        // SAFETY: as above; `&mut self` guarantees exclusivity.
6773        unsafe {
6774            Some(crate::support::RefMut::new(TextureTransform {
6775                raw: core::ptr::NonNull::new_unchecked(
6776                    ffi::whiteout_m2_M2Model_get_textureTransforms_at(self.raw.as_ptr(), index),
6777                ),
6778            }))
6779        }
6780    }
6781
6782    /// Iterate the elements, borrowing each in turn.
6783    pub fn texture_transforms_iter(
6784        &self,
6785    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, TextureTransform>> {
6786        (0..self.texture_transforms_len())
6787            .map(move |i| self.texture_transforms(i).expect("index below len"))
6788    }
6789
6790    pub fn resize_texture_transforms(&mut self, count: usize) {
6791        // SAFETY: exclusive access, so no borrow is outstanding.
6792        unsafe { ffi::whiteout_m2_M2Model_resize_textureTransforms(self.raw.as_ptr(), count) }
6793    }
6794
6795    /// Zero-copy view of the underlying `std::vector`.
6796    pub fn texture_indices_by_id(&self) -> &[u16] {
6797        // SAFETY: `_data`/`_count` describe one contiguous C++
6798        // allocation, borrowed for as long as `self` is.
6799        unsafe {
6800            let n = ffi::whiteout_m2_M2Model_get_textureIndicesById_count(self.raw.as_ptr());
6801            let p = ffi::whiteout_m2_M2Model_get_textureIndicesById_data(self.raw.as_ptr());
6802            if p.is_null() || n == 0 {
6803                &[]
6804            } else {
6805                core::slice::from_raw_parts(p, n)
6806            }
6807        }
6808    }
6809
6810    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
6811    pub fn texture_indices_by_id_mut(&mut self) -> &mut [u16] {
6812        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
6813        unsafe {
6814            let n = ffi::whiteout_m2_M2Model_get_textureIndicesById_count(self.raw.as_ptr());
6815            let p =
6816                ffi::whiteout_m2_M2Model_get_textureIndicesById_data(self.raw.as_ptr()) as *mut u16;
6817            if p.is_null() || n == 0 {
6818                &mut []
6819            } else {
6820                core::slice::from_raw_parts_mut(p, n)
6821            }
6822        }
6823    }
6824
6825    pub fn set_texture_indices_by_id(&mut self, values: &[u16]) {
6826        // SAFETY: the native side copies `values` before returning.
6827        unsafe {
6828            ffi::whiteout_m2_M2Model_assign_textureIndicesById(
6829                self.raw.as_ptr(),
6830                values.as_ptr() as *const _,
6831                values.len(),
6832            )
6833        }
6834    }
6835
6836    pub fn resize_texture_indices_by_id(&mut self, count: usize) {
6837        // SAFETY: reallocation is safe here precisely because
6838        // `&mut self` means no slice borrow is outstanding.
6839        unsafe { ffi::whiteout_m2_M2Model_resize_textureIndicesById(self.raw.as_ptr(), count) }
6840    }
6841
6842    pub fn materials_len(&self) -> usize {
6843        // SAFETY: scalar read through a live handle.
6844        unsafe { ffi::whiteout_m2_M2Model_get_materials_count(self.raw.as_ptr()) }
6845    }
6846
6847    /// Borrows element `index` in place. `None` when out of range.
6848    pub fn materials(&self, index: usize) -> Option<crate::support::Ref<'_, Material>> {
6849        if index >= self.materials_len() {
6850            return None;
6851        }
6852        // SAFETY: index checked above; the pointer is interior to `self`.
6853        unsafe {
6854            Some(crate::support::Ref::new(Material {
6855                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_materials_at(
6856                    self.raw.as_ptr(),
6857                    index,
6858                )),
6859            }))
6860        }
6861    }
6862
6863    pub fn materials_mut(&mut self, index: usize) -> Option<crate::support::RefMut<'_, Material>> {
6864        if index >= self.materials_len() {
6865            return None;
6866        }
6867        // SAFETY: as above; `&mut self` guarantees exclusivity.
6868        unsafe {
6869            Some(crate::support::RefMut::new(Material {
6870                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_materials_at(
6871                    self.raw.as_ptr(),
6872                    index,
6873                )),
6874            }))
6875        }
6876    }
6877
6878    /// Iterate the elements, borrowing each in turn.
6879    pub fn materials_iter(
6880        &self,
6881    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, Material>> {
6882        (0..self.materials_len()).map(move |i| self.materials(i).expect("index below len"))
6883    }
6884
6885    pub fn resize_materials(&mut self, count: usize) {
6886        // SAFETY: exclusive access, so no borrow is outstanding.
6887        unsafe { ffi::whiteout_m2_M2Model_resize_materials(self.raw.as_ptr(), count) }
6888    }
6889
6890    /// Zero-copy view of the underlying `std::vector`.
6891    pub fn bone_combos(&self) -> &[u16] {
6892        // SAFETY: `_data`/`_count` describe one contiguous C++
6893        // allocation, borrowed for as long as `self` is.
6894        unsafe {
6895            let n = ffi::whiteout_m2_M2Model_get_boneCombos_count(self.raw.as_ptr());
6896            let p = ffi::whiteout_m2_M2Model_get_boneCombos_data(self.raw.as_ptr());
6897            if p.is_null() || n == 0 {
6898                &[]
6899            } else {
6900                core::slice::from_raw_parts(p, n)
6901            }
6902        }
6903    }
6904
6905    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
6906    pub fn bone_combos_mut(&mut self) -> &mut [u16] {
6907        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
6908        unsafe {
6909            let n = ffi::whiteout_m2_M2Model_get_boneCombos_count(self.raw.as_ptr());
6910            let p = ffi::whiteout_m2_M2Model_get_boneCombos_data(self.raw.as_ptr()) as *mut u16;
6911            if p.is_null() || n == 0 {
6912                &mut []
6913            } else {
6914                core::slice::from_raw_parts_mut(p, n)
6915            }
6916        }
6917    }
6918
6919    pub fn set_bone_combos(&mut self, values: &[u16]) {
6920        // SAFETY: the native side copies `values` before returning.
6921        unsafe {
6922            ffi::whiteout_m2_M2Model_assign_boneCombos(
6923                self.raw.as_ptr(),
6924                values.as_ptr() as *const _,
6925                values.len(),
6926            )
6927        }
6928    }
6929
6930    pub fn resize_bone_combos(&mut self, count: usize) {
6931        // SAFETY: reallocation is safe here precisely because
6932        // `&mut self` means no slice borrow is outstanding.
6933        unsafe { ffi::whiteout_m2_M2Model_resize_boneCombos(self.raw.as_ptr(), count) }
6934    }
6935
6936    /// Zero-copy view of the underlying `std::vector`.
6937    pub fn texture_combos(&self) -> &[u16] {
6938        // SAFETY: `_data`/`_count` describe one contiguous C++
6939        // allocation, borrowed for as long as `self` is.
6940        unsafe {
6941            let n = ffi::whiteout_m2_M2Model_get_textureCombos_count(self.raw.as_ptr());
6942            let p = ffi::whiteout_m2_M2Model_get_textureCombos_data(self.raw.as_ptr());
6943            if p.is_null() || n == 0 {
6944                &[]
6945            } else {
6946                core::slice::from_raw_parts(p, n)
6947            }
6948        }
6949    }
6950
6951    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
6952    pub fn texture_combos_mut(&mut self) -> &mut [u16] {
6953        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
6954        unsafe {
6955            let n = ffi::whiteout_m2_M2Model_get_textureCombos_count(self.raw.as_ptr());
6956            let p = ffi::whiteout_m2_M2Model_get_textureCombos_data(self.raw.as_ptr()) as *mut u16;
6957            if p.is_null() || n == 0 {
6958                &mut []
6959            } else {
6960                core::slice::from_raw_parts_mut(p, n)
6961            }
6962        }
6963    }
6964
6965    pub fn set_texture_combos(&mut self, values: &[u16]) {
6966        // SAFETY: the native side copies `values` before returning.
6967        unsafe {
6968            ffi::whiteout_m2_M2Model_assign_textureCombos(
6969                self.raw.as_ptr(),
6970                values.as_ptr() as *const _,
6971                values.len(),
6972            )
6973        }
6974    }
6975
6976    pub fn resize_texture_combos(&mut self, count: usize) {
6977        // SAFETY: reallocation is safe here precisely because
6978        // `&mut self` means no slice borrow is outstanding.
6979        unsafe { ffi::whiteout_m2_M2Model_resize_textureCombos(self.raw.as_ptr(), count) }
6980    }
6981
6982    /// Zero-copy view of the underlying `std::vector`.
6983    pub fn texture_coord_combos(&self) -> &[u16] {
6984        // SAFETY: `_data`/`_count` describe one contiguous C++
6985        // allocation, borrowed for as long as `self` is.
6986        unsafe {
6987            let n = ffi::whiteout_m2_M2Model_get_textureCoordCombos_count(self.raw.as_ptr());
6988            let p = ffi::whiteout_m2_M2Model_get_textureCoordCombos_data(self.raw.as_ptr());
6989            if p.is_null() || n == 0 {
6990                &[]
6991            } else {
6992                core::slice::from_raw_parts(p, n)
6993            }
6994        }
6995    }
6996
6997    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
6998    pub fn texture_coord_combos_mut(&mut self) -> &mut [u16] {
6999        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
7000        unsafe {
7001            let n = ffi::whiteout_m2_M2Model_get_textureCoordCombos_count(self.raw.as_ptr());
7002            let p =
7003                ffi::whiteout_m2_M2Model_get_textureCoordCombos_data(self.raw.as_ptr()) as *mut u16;
7004            if p.is_null() || n == 0 {
7005                &mut []
7006            } else {
7007                core::slice::from_raw_parts_mut(p, n)
7008            }
7009        }
7010    }
7011
7012    pub fn set_texture_coord_combos(&mut self, values: &[u16]) {
7013        // SAFETY: the native side copies `values` before returning.
7014        unsafe {
7015            ffi::whiteout_m2_M2Model_assign_textureCoordCombos(
7016                self.raw.as_ptr(),
7017                values.as_ptr() as *const _,
7018                values.len(),
7019            )
7020        }
7021    }
7022
7023    pub fn resize_texture_coord_combos(&mut self, count: usize) {
7024        // SAFETY: reallocation is safe here precisely because
7025        // `&mut self` means no slice borrow is outstanding.
7026        unsafe { ffi::whiteout_m2_M2Model_resize_textureCoordCombos(self.raw.as_ptr(), count) }
7027    }
7028
7029    /// Zero-copy view of the underlying `std::vector`.
7030    pub fn texture_weight_combos(&self) -> &[u16] {
7031        // SAFETY: `_data`/`_count` describe one contiguous C++
7032        // allocation, borrowed for as long as `self` is.
7033        unsafe {
7034            let n = ffi::whiteout_m2_M2Model_get_textureWeightCombos_count(self.raw.as_ptr());
7035            let p = ffi::whiteout_m2_M2Model_get_textureWeightCombos_data(self.raw.as_ptr());
7036            if p.is_null() || n == 0 {
7037                &[]
7038            } else {
7039                core::slice::from_raw_parts(p, n)
7040            }
7041        }
7042    }
7043
7044    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
7045    pub fn texture_weight_combos_mut(&mut self) -> &mut [u16] {
7046        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
7047        unsafe {
7048            let n = ffi::whiteout_m2_M2Model_get_textureWeightCombos_count(self.raw.as_ptr());
7049            let p = ffi::whiteout_m2_M2Model_get_textureWeightCombos_data(self.raw.as_ptr())
7050                as *mut u16;
7051            if p.is_null() || n == 0 {
7052                &mut []
7053            } else {
7054                core::slice::from_raw_parts_mut(p, n)
7055            }
7056        }
7057    }
7058
7059    pub fn set_texture_weight_combos(&mut self, values: &[u16]) {
7060        // SAFETY: the native side copies `values` before returning.
7061        unsafe {
7062            ffi::whiteout_m2_M2Model_assign_textureWeightCombos(
7063                self.raw.as_ptr(),
7064                values.as_ptr() as *const _,
7065                values.len(),
7066            )
7067        }
7068    }
7069
7070    pub fn resize_texture_weight_combos(&mut self, count: usize) {
7071        // SAFETY: reallocation is safe here precisely because
7072        // `&mut self` means no slice borrow is outstanding.
7073        unsafe { ffi::whiteout_m2_M2Model_resize_textureWeightCombos(self.raw.as_ptr(), count) }
7074    }
7075
7076    /// Zero-copy view of the underlying `std::vector`.
7077    pub fn texture_transform_combos(&self) -> &[u16] {
7078        // SAFETY: `_data`/`_count` describe one contiguous C++
7079        // allocation, borrowed for as long as `self` is.
7080        unsafe {
7081            let n = ffi::whiteout_m2_M2Model_get_textureTransformCombos_count(self.raw.as_ptr());
7082            let p = ffi::whiteout_m2_M2Model_get_textureTransformCombos_data(self.raw.as_ptr());
7083            if p.is_null() || n == 0 {
7084                &[]
7085            } else {
7086                core::slice::from_raw_parts(p, n)
7087            }
7088        }
7089    }
7090
7091    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
7092    pub fn texture_transform_combos_mut(&mut self) -> &mut [u16] {
7093        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
7094        unsafe {
7095            let n = ffi::whiteout_m2_M2Model_get_textureTransformCombos_count(self.raw.as_ptr());
7096            let p = ffi::whiteout_m2_M2Model_get_textureTransformCombos_data(self.raw.as_ptr())
7097                as *mut u16;
7098            if p.is_null() || n == 0 {
7099                &mut []
7100            } else {
7101                core::slice::from_raw_parts_mut(p, n)
7102            }
7103        }
7104    }
7105
7106    pub fn set_texture_transform_combos(&mut self, values: &[u16]) {
7107        // SAFETY: the native side copies `values` before returning.
7108        unsafe {
7109            ffi::whiteout_m2_M2Model_assign_textureTransformCombos(
7110                self.raw.as_ptr(),
7111                values.as_ptr() as *const _,
7112                values.len(),
7113            )
7114        }
7115    }
7116
7117    pub fn resize_texture_transform_combos(&mut self, count: usize) {
7118        // SAFETY: reallocation is safe here precisely because
7119        // `&mut self` means no slice borrow is outstanding.
7120        unsafe { ffi::whiteout_m2_M2Model_resize_textureTransformCombos(self.raw.as_ptr(), count) }
7121    }
7122
7123    /// Borrows the field in place — no copy, no allocation.
7124    pub fn bounding(&self) -> crate::support::Ref<'_, Extent> {
7125        // SAFETY: an interior pointer into `self`, valid for this
7126        // borrow and never freed by the `Ref`.
7127        unsafe {
7128            crate::support::Ref::new(Extent {
7129                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_bounding(
7130                    self.raw.as_ptr(),
7131                )),
7132            })
7133        }
7134    }
7135
7136    pub fn bounding_mut(&mut self) -> crate::support::RefMut<'_, Extent> {
7137        // SAFETY: as above; `&mut self` guarantees exclusivity.
7138        unsafe {
7139            crate::support::RefMut::new(Extent {
7140                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_bounding(
7141                    self.raw.as_ptr(),
7142                )),
7143            })
7144        }
7145    }
7146
7147    /// Borrows the field in place — no copy, no allocation.
7148    pub fn collision(&self) -> crate::support::Ref<'_, Extent> {
7149        // SAFETY: an interior pointer into `self`, valid for this
7150        // borrow and never freed by the `Ref`.
7151        unsafe {
7152            crate::support::Ref::new(Extent {
7153                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_collision(
7154                    self.raw.as_ptr(),
7155                )),
7156            })
7157        }
7158    }
7159
7160    pub fn collision_mut(&mut self) -> crate::support::RefMut<'_, Extent> {
7161        // SAFETY: as above; `&mut self` guarantees exclusivity.
7162        unsafe {
7163            crate::support::RefMut::new(Extent {
7164                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_collision(
7165                    self.raw.as_ptr(),
7166                )),
7167            })
7168        }
7169    }
7170
7171    /// Zero-copy view of the underlying `std::vector`.
7172    pub fn collision_triangle_indices(&self) -> &[u16] {
7173        // SAFETY: `_data`/`_count` describe one contiguous C++
7174        // allocation, borrowed for as long as `self` is.
7175        unsafe {
7176            let n = ffi::whiteout_m2_M2Model_get_collisionTriangleIndices_count(self.raw.as_ptr());
7177            let p = ffi::whiteout_m2_M2Model_get_collisionTriangleIndices_data(self.raw.as_ptr());
7178            if p.is_null() || n == 0 {
7179                &[]
7180            } else {
7181                core::slice::from_raw_parts(p, n)
7182            }
7183        }
7184    }
7185
7186    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
7187    pub fn collision_triangle_indices_mut(&mut self) -> &mut [u16] {
7188        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
7189        unsafe {
7190            let n = ffi::whiteout_m2_M2Model_get_collisionTriangleIndices_count(self.raw.as_ptr());
7191            let p = ffi::whiteout_m2_M2Model_get_collisionTriangleIndices_data(self.raw.as_ptr())
7192                as *mut u16;
7193            if p.is_null() || n == 0 {
7194                &mut []
7195            } else {
7196                core::slice::from_raw_parts_mut(p, n)
7197            }
7198        }
7199    }
7200
7201    pub fn set_collision_triangle_indices(&mut self, values: &[u16]) {
7202        // SAFETY: the native side copies `values` before returning.
7203        unsafe {
7204            ffi::whiteout_m2_M2Model_assign_collisionTriangleIndices(
7205                self.raw.as_ptr(),
7206                values.as_ptr() as *const _,
7207                values.len(),
7208            )
7209        }
7210    }
7211
7212    pub fn resize_collision_triangle_indices(&mut self, count: usize) {
7213        // SAFETY: reallocation is safe here precisely because
7214        // `&mut self` means no slice borrow is outstanding.
7215        unsafe {
7216            ffi::whiteout_m2_M2Model_resize_collisionTriangleIndices(self.raw.as_ptr(), count)
7217        }
7218    }
7219
7220    /// Zero-copy view of the underlying `std::vector`.
7221    pub fn collision_vertices(&self) -> &[crate::math::Vector3f] {
7222        // SAFETY: `_data`/`_count` describe one contiguous C++
7223        // allocation, borrowed for as long as `self` is.
7224        unsafe {
7225            let n = ffi::whiteout_m2_M2Model_get_collisionVertices_count(self.raw.as_ptr());
7226            let p = ffi::whiteout_m2_M2Model_get_collisionVertices_data(self.raw.as_ptr())
7227                as *const crate::math::Vector3f;
7228            if p.is_null() || n == 0 {
7229                &[]
7230            } else {
7231                core::slice::from_raw_parts(p, n)
7232            }
7233        }
7234    }
7235
7236    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
7237    pub fn collision_vertices_mut(&mut self) -> &mut [crate::math::Vector3f] {
7238        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
7239        unsafe {
7240            let n = ffi::whiteout_m2_M2Model_get_collisionVertices_count(self.raw.as_ptr());
7241            let p = ffi::whiteout_m2_M2Model_get_collisionVertices_data(self.raw.as_ptr())
7242                as *const crate::math::Vector3f as *mut crate::math::Vector3f;
7243            if p.is_null() || n == 0 {
7244                &mut []
7245            } else {
7246                core::slice::from_raw_parts_mut(p, n)
7247            }
7248        }
7249    }
7250
7251    pub fn set_collision_vertices(&mut self, values: &[crate::math::Vector3f]) {
7252        // SAFETY: the native side copies `values` before returning.
7253        unsafe {
7254            ffi::whiteout_m2_M2Model_assign_collisionVertices(
7255                self.raw.as_ptr(),
7256                values.as_ptr() as *const _,
7257                values.len(),
7258            )
7259        }
7260    }
7261
7262    pub fn resize_collision_vertices(&mut self, count: usize) {
7263        // SAFETY: reallocation is safe here precisely because
7264        // `&mut self` means no slice borrow is outstanding.
7265        unsafe { ffi::whiteout_m2_M2Model_resize_collisionVertices(self.raw.as_ptr(), count) }
7266    }
7267
7268    /// Zero-copy view of the underlying `std::vector`.
7269    pub fn collision_face_normals(&self) -> &[crate::math::Vector3f] {
7270        // SAFETY: `_data`/`_count` describe one contiguous C++
7271        // allocation, borrowed for as long as `self` is.
7272        unsafe {
7273            let n = ffi::whiteout_m2_M2Model_get_collisionFaceNormals_count(self.raw.as_ptr());
7274            let p = ffi::whiteout_m2_M2Model_get_collisionFaceNormals_data(self.raw.as_ptr())
7275                as *const crate::math::Vector3f;
7276            if p.is_null() || n == 0 {
7277                &[]
7278            } else {
7279                core::slice::from_raw_parts(p, n)
7280            }
7281        }
7282    }
7283
7284    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
7285    pub fn collision_face_normals_mut(&mut self) -> &mut [crate::math::Vector3f] {
7286        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
7287        unsafe {
7288            let n = ffi::whiteout_m2_M2Model_get_collisionFaceNormals_count(self.raw.as_ptr());
7289            let p = ffi::whiteout_m2_M2Model_get_collisionFaceNormals_data(self.raw.as_ptr())
7290                as *const crate::math::Vector3f as *mut crate::math::Vector3f;
7291            if p.is_null() || n == 0 {
7292                &mut []
7293            } else {
7294                core::slice::from_raw_parts_mut(p, n)
7295            }
7296        }
7297    }
7298
7299    pub fn set_collision_face_normals(&mut self, values: &[crate::math::Vector3f]) {
7300        // SAFETY: the native side copies `values` before returning.
7301        unsafe {
7302            ffi::whiteout_m2_M2Model_assign_collisionFaceNormals(
7303                self.raw.as_ptr(),
7304                values.as_ptr() as *const _,
7305                values.len(),
7306            )
7307        }
7308    }
7309
7310    pub fn resize_collision_face_normals(&mut self, count: usize) {
7311        // SAFETY: reallocation is safe here precisely because
7312        // `&mut self` means no slice borrow is outstanding.
7313        unsafe { ffi::whiteout_m2_M2Model_resize_collisionFaceNormals(self.raw.as_ptr(), count) }
7314    }
7315
7316    pub fn attachments_len(&self) -> usize {
7317        // SAFETY: scalar read through a live handle.
7318        unsafe { ffi::whiteout_m2_M2Model_get_attachments_count(self.raw.as_ptr()) }
7319    }
7320
7321    /// Borrows element `index` in place. `None` when out of range.
7322    pub fn attachments(&self, index: usize) -> Option<crate::support::Ref<'_, Attachment>> {
7323        if index >= self.attachments_len() {
7324            return None;
7325        }
7326        // SAFETY: index checked above; the pointer is interior to `self`.
7327        unsafe {
7328            Some(crate::support::Ref::new(Attachment {
7329                raw: core::ptr::NonNull::new_unchecked(
7330                    ffi::whiteout_m2_M2Model_get_attachments_at(self.raw.as_ptr(), index),
7331                ),
7332            }))
7333        }
7334    }
7335
7336    pub fn attachments_mut(
7337        &mut self,
7338        index: usize,
7339    ) -> Option<crate::support::RefMut<'_, Attachment>> {
7340        if index >= self.attachments_len() {
7341            return None;
7342        }
7343        // SAFETY: as above; `&mut self` guarantees exclusivity.
7344        unsafe {
7345            Some(crate::support::RefMut::new(Attachment {
7346                raw: core::ptr::NonNull::new_unchecked(
7347                    ffi::whiteout_m2_M2Model_get_attachments_at(self.raw.as_ptr(), index),
7348                ),
7349            }))
7350        }
7351    }
7352
7353    /// Iterate the elements, borrowing each in turn.
7354    pub fn attachments_iter(
7355        &self,
7356    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, Attachment>> {
7357        (0..self.attachments_len()).map(move |i| self.attachments(i).expect("index below len"))
7358    }
7359
7360    pub fn resize_attachments(&mut self, count: usize) {
7361        // SAFETY: exclusive access, so no borrow is outstanding.
7362        unsafe { ffi::whiteout_m2_M2Model_resize_attachments(self.raw.as_ptr(), count) }
7363    }
7364
7365    /// Zero-copy view of the underlying `std::vector`.
7366    pub fn attachment_indices_by_id(&self) -> &[u16] {
7367        // SAFETY: `_data`/`_count` describe one contiguous C++
7368        // allocation, borrowed for as long as `self` is.
7369        unsafe {
7370            let n = ffi::whiteout_m2_M2Model_get_attachmentIndicesById_count(self.raw.as_ptr());
7371            let p = ffi::whiteout_m2_M2Model_get_attachmentIndicesById_data(self.raw.as_ptr());
7372            if p.is_null() || n == 0 {
7373                &[]
7374            } else {
7375                core::slice::from_raw_parts(p, n)
7376            }
7377        }
7378    }
7379
7380    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
7381    pub fn attachment_indices_by_id_mut(&mut self) -> &mut [u16] {
7382        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
7383        unsafe {
7384            let n = ffi::whiteout_m2_M2Model_get_attachmentIndicesById_count(self.raw.as_ptr());
7385            let p = ffi::whiteout_m2_M2Model_get_attachmentIndicesById_data(self.raw.as_ptr())
7386                as *mut u16;
7387            if p.is_null() || n == 0 {
7388                &mut []
7389            } else {
7390                core::slice::from_raw_parts_mut(p, n)
7391            }
7392        }
7393    }
7394
7395    pub fn set_attachment_indices_by_id(&mut self, values: &[u16]) {
7396        // SAFETY: the native side copies `values` before returning.
7397        unsafe {
7398            ffi::whiteout_m2_M2Model_assign_attachmentIndicesById(
7399                self.raw.as_ptr(),
7400                values.as_ptr() as *const _,
7401                values.len(),
7402            )
7403        }
7404    }
7405
7406    pub fn resize_attachment_indices_by_id(&mut self, count: usize) {
7407        // SAFETY: reallocation is safe here precisely because
7408        // `&mut self` means no slice borrow is outstanding.
7409        unsafe { ffi::whiteout_m2_M2Model_resize_attachmentIndicesById(self.raw.as_ptr(), count) }
7410    }
7411
7412    pub fn events_len(&self) -> usize {
7413        // SAFETY: scalar read through a live handle.
7414        unsafe { ffi::whiteout_m2_M2Model_get_events_count(self.raw.as_ptr()) }
7415    }
7416
7417    /// Borrows element `index` in place. `None` when out of range.
7418    pub fn events(&self, index: usize) -> Option<crate::support::Ref<'_, Event>> {
7419        if index >= self.events_len() {
7420            return None;
7421        }
7422        // SAFETY: index checked above; the pointer is interior to `self`.
7423        unsafe {
7424            Some(crate::support::Ref::new(Event {
7425                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_events_at(
7426                    self.raw.as_ptr(),
7427                    index,
7428                )),
7429            }))
7430        }
7431    }
7432
7433    pub fn events_mut(&mut self, index: usize) -> Option<crate::support::RefMut<'_, Event>> {
7434        if index >= self.events_len() {
7435            return None;
7436        }
7437        // SAFETY: as above; `&mut self` guarantees exclusivity.
7438        unsafe {
7439            Some(crate::support::RefMut::new(Event {
7440                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_events_at(
7441                    self.raw.as_ptr(),
7442                    index,
7443                )),
7444            }))
7445        }
7446    }
7447
7448    /// Iterate the elements, borrowing each in turn.
7449    pub fn events_iter(&self) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, Event>> {
7450        (0..self.events_len()).map(move |i| self.events(i).expect("index below len"))
7451    }
7452
7453    pub fn resize_events(&mut self, count: usize) {
7454        // SAFETY: exclusive access, so no borrow is outstanding.
7455        unsafe { ffi::whiteout_m2_M2Model_resize_events(self.raw.as_ptr(), count) }
7456    }
7457
7458    pub fn lights_len(&self) -> usize {
7459        // SAFETY: scalar read through a live handle.
7460        unsafe { ffi::whiteout_m2_M2Model_get_lights_count(self.raw.as_ptr()) }
7461    }
7462
7463    /// Borrows element `index` in place. `None` when out of range.
7464    pub fn lights(&self, index: usize) -> Option<crate::support::Ref<'_, Light>> {
7465        if index >= self.lights_len() {
7466            return None;
7467        }
7468        // SAFETY: index checked above; the pointer is interior to `self`.
7469        unsafe {
7470            Some(crate::support::Ref::new(Light {
7471                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_lights_at(
7472                    self.raw.as_ptr(),
7473                    index,
7474                )),
7475            }))
7476        }
7477    }
7478
7479    pub fn lights_mut(&mut self, index: usize) -> Option<crate::support::RefMut<'_, Light>> {
7480        if index >= self.lights_len() {
7481            return None;
7482        }
7483        // SAFETY: as above; `&mut self` guarantees exclusivity.
7484        unsafe {
7485            Some(crate::support::RefMut::new(Light {
7486                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_lights_at(
7487                    self.raw.as_ptr(),
7488                    index,
7489                )),
7490            }))
7491        }
7492    }
7493
7494    /// Iterate the elements, borrowing each in turn.
7495    pub fn lights_iter(&self) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, Light>> {
7496        (0..self.lights_len()).map(move |i| self.lights(i).expect("index below len"))
7497    }
7498
7499    pub fn resize_lights(&mut self, count: usize) {
7500        // SAFETY: exclusive access, so no borrow is outstanding.
7501        unsafe { ffi::whiteout_m2_M2Model_resize_lights(self.raw.as_ptr(), count) }
7502    }
7503
7504    pub fn cameras_len(&self) -> usize {
7505        // SAFETY: scalar read through a live handle.
7506        unsafe { ffi::whiteout_m2_M2Model_get_cameras_count(self.raw.as_ptr()) }
7507    }
7508
7509    /// Borrows element `index` in place. `None` when out of range.
7510    pub fn cameras(&self, index: usize) -> Option<crate::support::Ref<'_, Camera>> {
7511        if index >= self.cameras_len() {
7512            return None;
7513        }
7514        // SAFETY: index checked above; the pointer is interior to `self`.
7515        unsafe {
7516            Some(crate::support::Ref::new(Camera {
7517                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_cameras_at(
7518                    self.raw.as_ptr(),
7519                    index,
7520                )),
7521            }))
7522        }
7523    }
7524
7525    pub fn cameras_mut(&mut self, index: usize) -> Option<crate::support::RefMut<'_, Camera>> {
7526        if index >= self.cameras_len() {
7527            return None;
7528        }
7529        // SAFETY: as above; `&mut self` guarantees exclusivity.
7530        unsafe {
7531            Some(crate::support::RefMut::new(Camera {
7532                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m2_M2Model_get_cameras_at(
7533                    self.raw.as_ptr(),
7534                    index,
7535                )),
7536            }))
7537        }
7538    }
7539
7540    /// Iterate the elements, borrowing each in turn.
7541    pub fn cameras_iter(&self) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, Camera>> {
7542        (0..self.cameras_len()).map(move |i| self.cameras(i).expect("index below len"))
7543    }
7544
7545    pub fn resize_cameras(&mut self, count: usize) {
7546        // SAFETY: exclusive access, so no borrow is outstanding.
7547        unsafe { ffi::whiteout_m2_M2Model_resize_cameras(self.raw.as_ptr(), count) }
7548    }
7549
7550    /// Zero-copy view of the underlying `std::vector`.
7551    pub fn camera_indices_by_id(&self) -> &[u16] {
7552        // SAFETY: `_data`/`_count` describe one contiguous C++
7553        // allocation, borrowed for as long as `self` is.
7554        unsafe {
7555            let n = ffi::whiteout_m2_M2Model_get_cameraIndicesById_count(self.raw.as_ptr());
7556            let p = ffi::whiteout_m2_M2Model_get_cameraIndicesById_data(self.raw.as_ptr());
7557            if p.is_null() || n == 0 {
7558                &[]
7559            } else {
7560                core::slice::from_raw_parts(p, n)
7561            }
7562        }
7563    }
7564
7565    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
7566    pub fn camera_indices_by_id_mut(&mut self) -> &mut [u16] {
7567        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
7568        unsafe {
7569            let n = ffi::whiteout_m2_M2Model_get_cameraIndicesById_count(self.raw.as_ptr());
7570            let p =
7571                ffi::whiteout_m2_M2Model_get_cameraIndicesById_data(self.raw.as_ptr()) as *mut u16;
7572            if p.is_null() || n == 0 {
7573                &mut []
7574            } else {
7575                core::slice::from_raw_parts_mut(p, n)
7576            }
7577        }
7578    }
7579
7580    pub fn set_camera_indices_by_id(&mut self, values: &[u16]) {
7581        // SAFETY: the native side copies `values` before returning.
7582        unsafe {
7583            ffi::whiteout_m2_M2Model_assign_cameraIndicesById(
7584                self.raw.as_ptr(),
7585                values.as_ptr() as *const _,
7586                values.len(),
7587            )
7588        }
7589    }
7590
7591    pub fn resize_camera_indices_by_id(&mut self, count: usize) {
7592        // SAFETY: reallocation is safe here precisely because
7593        // `&mut self` means no slice borrow is outstanding.
7594        unsafe { ffi::whiteout_m2_M2Model_resize_cameraIndicesById(self.raw.as_ptr(), count) }
7595    }
7596
7597    pub fn ribbon_emitters_len(&self) -> usize {
7598        // SAFETY: scalar read through a live handle.
7599        unsafe { ffi::whiteout_m2_M2Model_get_ribbonEmitters_count(self.raw.as_ptr()) }
7600    }
7601
7602    /// Borrows element `index` in place. `None` when out of range.
7603    pub fn ribbon_emitters(&self, index: usize) -> Option<crate::support::Ref<'_, RibbonEmitter>> {
7604        if index >= self.ribbon_emitters_len() {
7605            return None;
7606        }
7607        // SAFETY: index checked above; the pointer is interior to `self`.
7608        unsafe {
7609            Some(crate::support::Ref::new(RibbonEmitter {
7610                raw: core::ptr::NonNull::new_unchecked(
7611                    ffi::whiteout_m2_M2Model_get_ribbonEmitters_at(self.raw.as_ptr(), index),
7612                ),
7613            }))
7614        }
7615    }
7616
7617    pub fn ribbon_emitters_mut(
7618        &mut self,
7619        index: usize,
7620    ) -> Option<crate::support::RefMut<'_, RibbonEmitter>> {
7621        if index >= self.ribbon_emitters_len() {
7622            return None;
7623        }
7624        // SAFETY: as above; `&mut self` guarantees exclusivity.
7625        unsafe {
7626            Some(crate::support::RefMut::new(RibbonEmitter {
7627                raw: core::ptr::NonNull::new_unchecked(
7628                    ffi::whiteout_m2_M2Model_get_ribbonEmitters_at(self.raw.as_ptr(), index),
7629                ),
7630            }))
7631        }
7632    }
7633
7634    /// Iterate the elements, borrowing each in turn.
7635    pub fn ribbon_emitters_iter(
7636        &self,
7637    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, RibbonEmitter>> {
7638        (0..self.ribbon_emitters_len())
7639            .map(move |i| self.ribbon_emitters(i).expect("index below len"))
7640    }
7641
7642    pub fn resize_ribbon_emitters(&mut self, count: usize) {
7643        // SAFETY: exclusive access, so no borrow is outstanding.
7644        unsafe { ffi::whiteout_m2_M2Model_resize_ribbonEmitters(self.raw.as_ptr(), count) }
7645    }
7646
7647    pub fn particle_emitters_len(&self) -> usize {
7648        // SAFETY: scalar read through a live handle.
7649        unsafe { ffi::whiteout_m2_M2Model_get_particleEmitters_count(self.raw.as_ptr()) }
7650    }
7651
7652    /// Borrows element `index` in place. `None` when out of range.
7653    pub fn particle_emitters(
7654        &self,
7655        index: usize,
7656    ) -> Option<crate::support::Ref<'_, ParticleEmitter>> {
7657        if index >= self.particle_emitters_len() {
7658            return None;
7659        }
7660        // SAFETY: index checked above; the pointer is interior to `self`.
7661        unsafe {
7662            Some(crate::support::Ref::new(ParticleEmitter {
7663                raw: core::ptr::NonNull::new_unchecked(
7664                    ffi::whiteout_m2_M2Model_get_particleEmitters_at(self.raw.as_ptr(), index),
7665                ),
7666            }))
7667        }
7668    }
7669
7670    pub fn particle_emitters_mut(
7671        &mut self,
7672        index: usize,
7673    ) -> Option<crate::support::RefMut<'_, ParticleEmitter>> {
7674        if index >= self.particle_emitters_len() {
7675            return None;
7676        }
7677        // SAFETY: as above; `&mut self` guarantees exclusivity.
7678        unsafe {
7679            Some(crate::support::RefMut::new(ParticleEmitter {
7680                raw: core::ptr::NonNull::new_unchecked(
7681                    ffi::whiteout_m2_M2Model_get_particleEmitters_at(self.raw.as_ptr(), index),
7682                ),
7683            }))
7684        }
7685    }
7686
7687    /// Iterate the elements, borrowing each in turn.
7688    pub fn particle_emitters_iter(
7689        &self,
7690    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, ParticleEmitter>> {
7691        (0..self.particle_emitters_len())
7692            .map(move |i| self.particle_emitters(i).expect("index below len"))
7693    }
7694
7695    pub fn resize_particle_emitters(&mut self, count: usize) {
7696        // SAFETY: exclusive access, so no borrow is outstanding.
7697        unsafe { ffi::whiteout_m2_M2Model_resize_particleEmitters(self.raw.as_ptr(), count) }
7698    }
7699
7700    /// Zero-copy view of the underlying `std::vector`.
7701    pub fn texture_combiner_combos(&self) -> &[u16] {
7702        // SAFETY: `_data`/`_count` describe one contiguous C++
7703        // allocation, borrowed for as long as `self` is.
7704        unsafe {
7705            let n = ffi::whiteout_m2_M2Model_get_textureCombinerCombos_count(self.raw.as_ptr());
7706            let p = ffi::whiteout_m2_M2Model_get_textureCombinerCombos_data(self.raw.as_ptr());
7707            if p.is_null() || n == 0 {
7708                &[]
7709            } else {
7710                core::slice::from_raw_parts(p, n)
7711            }
7712        }
7713    }
7714
7715    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
7716    pub fn texture_combiner_combos_mut(&mut self) -> &mut [u16] {
7717        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
7718        unsafe {
7719            let n = ffi::whiteout_m2_M2Model_get_textureCombinerCombos_count(self.raw.as_ptr());
7720            let p = ffi::whiteout_m2_M2Model_get_textureCombinerCombos_data(self.raw.as_ptr())
7721                as *mut u16;
7722            if p.is_null() || n == 0 {
7723                &mut []
7724            } else {
7725                core::slice::from_raw_parts_mut(p, n)
7726            }
7727        }
7728    }
7729
7730    pub fn set_texture_combiner_combos(&mut self, values: &[u16]) {
7731        // SAFETY: the native side copies `values` before returning.
7732        unsafe {
7733            ffi::whiteout_m2_M2Model_assign_textureCombinerCombos(
7734                self.raw.as_ptr(),
7735                values.as_ptr() as *const _,
7736                values.len(),
7737            )
7738        }
7739    }
7740
7741    pub fn resize_texture_combiner_combos(&mut self, count: usize) {
7742        // SAFETY: reallocation is safe here precisely because
7743        // `&mut self` means no slice borrow is outstanding.
7744        unsafe { ffi::whiteout_m2_M2Model_resize_textureCombinerCombos(self.raw.as_ptr(), count) }
7745    }
7746
7747    /// TXID
7748    /// Zero-copy view of the underlying `std::vector`.
7749    pub fn texture_ids(&self) -> &[u32] {
7750        // SAFETY: `_data`/`_count` describe one contiguous C++
7751        // allocation, borrowed for as long as `self` is.
7752        unsafe {
7753            let n = ffi::whiteout_m2_M2Model_get_texture_ids_count(self.raw.as_ptr());
7754            let p = ffi::whiteout_m2_M2Model_get_texture_ids_data(self.raw.as_ptr());
7755            if p.is_null() || n == 0 {
7756                &[]
7757            } else {
7758                core::slice::from_raw_parts(p, n)
7759            }
7760        }
7761    }
7762
7763    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
7764    pub fn texture_ids_mut(&mut self) -> &mut [u32] {
7765        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
7766        unsafe {
7767            let n = ffi::whiteout_m2_M2Model_get_texture_ids_count(self.raw.as_ptr());
7768            let p = ffi::whiteout_m2_M2Model_get_texture_ids_data(self.raw.as_ptr()) as *mut u32;
7769            if p.is_null() || n == 0 {
7770                &mut []
7771            } else {
7772                core::slice::from_raw_parts_mut(p, n)
7773            }
7774        }
7775    }
7776
7777    pub fn set_texture_ids(&mut self, values: &[u32]) {
7778        // SAFETY: the native side copies `values` before returning.
7779        unsafe {
7780            ffi::whiteout_m2_M2Model_assign_texture_ids(
7781                self.raw.as_ptr(),
7782                values.as_ptr() as *const _,
7783                values.len(),
7784            )
7785        }
7786    }
7787
7788    pub fn resize_texture_ids(&mut self, count: usize) {
7789        // SAFETY: reallocation is safe here precisely because
7790        // `&mut self` means no slice borrow is outstanding.
7791        unsafe { ffi::whiteout_m2_M2Model_resize_texture_ids(self.raw.as_ptr(), count) }
7792    }
7793
7794    /// PABC
7795    /// Zero-copy view of the underlying `std::vector`.
7796    pub fn parent_sequence_replacements(&self) -> &[u16] {
7797        // SAFETY: `_data`/`_count` describe one contiguous C++
7798        // allocation, borrowed for as long as `self` is.
7799        unsafe {
7800            let n =
7801                ffi::whiteout_m2_M2Model_get_parentSequenceReplacements_count(self.raw.as_ptr());
7802            let p = ffi::whiteout_m2_M2Model_get_parentSequenceReplacements_data(self.raw.as_ptr());
7803            if p.is_null() || n == 0 {
7804                &[]
7805            } else {
7806                core::slice::from_raw_parts(p, n)
7807            }
7808        }
7809    }
7810
7811    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
7812    pub fn parent_sequence_replacements_mut(&mut self) -> &mut [u16] {
7813        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
7814        unsafe {
7815            let n =
7816                ffi::whiteout_m2_M2Model_get_parentSequenceReplacements_count(self.raw.as_ptr());
7817            let p = ffi::whiteout_m2_M2Model_get_parentSequenceReplacements_data(self.raw.as_ptr())
7818                as *mut u16;
7819            if p.is_null() || n == 0 {
7820                &mut []
7821            } else {
7822                core::slice::from_raw_parts_mut(p, n)
7823            }
7824        }
7825    }
7826
7827    pub fn set_parent_sequence_replacements(&mut self, values: &[u16]) {
7828        // SAFETY: the native side copies `values` before returning.
7829        unsafe {
7830            ffi::whiteout_m2_M2Model_assign_parentSequenceReplacements(
7831                self.raw.as_ptr(),
7832                values.as_ptr() as *const _,
7833                values.len(),
7834            )
7835        }
7836    }
7837
7838    pub fn resize_parent_sequence_replacements(&mut self, count: usize) {
7839        // SAFETY: reallocation is safe here precisely because
7840        // `&mut self` means no slice borrow is outstanding.
7841        unsafe {
7842            ffi::whiteout_m2_M2Model_resize_parentSequenceReplacements(self.raw.as_ptr(), count)
7843        }
7844    }
7845
7846    /// PADC
7847    pub fn parent_texture_weights_len(&self) -> usize {
7848        // SAFETY: scalar read through a live handle.
7849        unsafe { ffi::whiteout_m2_M2Model_get_parentTextureWeights_count(self.raw.as_ptr()) }
7850    }
7851
7852    /// Borrows element `index` in place. `None` when out of range.
7853    pub fn parent_texture_weights(
7854        &self,
7855        index: usize,
7856    ) -> Option<crate::support::Ref<'_, TextureWeight>> {
7857        if index >= self.parent_texture_weights_len() {
7858            return None;
7859        }
7860        // SAFETY: index checked above; the pointer is interior to `self`.
7861        unsafe {
7862            Some(crate::support::Ref::new(TextureWeight {
7863                raw: core::ptr::NonNull::new_unchecked(
7864                    ffi::whiteout_m2_M2Model_get_parentTextureWeights_at(self.raw.as_ptr(), index),
7865                ),
7866            }))
7867        }
7868    }
7869
7870    pub fn parent_texture_weights_mut(
7871        &mut self,
7872        index: usize,
7873    ) -> Option<crate::support::RefMut<'_, TextureWeight>> {
7874        if index >= self.parent_texture_weights_len() {
7875            return None;
7876        }
7877        // SAFETY: as above; `&mut self` guarantees exclusivity.
7878        unsafe {
7879            Some(crate::support::RefMut::new(TextureWeight {
7880                raw: core::ptr::NonNull::new_unchecked(
7881                    ffi::whiteout_m2_M2Model_get_parentTextureWeights_at(self.raw.as_ptr(), index),
7882                ),
7883            }))
7884        }
7885    }
7886
7887    /// Iterate the elements, borrowing each in turn.
7888    pub fn parent_texture_weights_iter(
7889        &self,
7890    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, TextureWeight>> {
7891        (0..self.parent_texture_weights_len())
7892            .map(move |i| self.parent_texture_weights(i).expect("index below len"))
7893    }
7894
7895    pub fn resize_parent_texture_weights(&mut self, count: usize) {
7896        // SAFETY: exclusive access, so no borrow is outstanding.
7897        unsafe { ffi::whiteout_m2_M2Model_resize_parentTextureWeights(self.raw.as_ptr(), count) }
7898    }
7899
7900    /// PSBC
7901    pub fn parent_sequence_bounds_len(&self) -> usize {
7902        // SAFETY: scalar read through a live handle.
7903        unsafe { ffi::whiteout_m2_M2Model_get_parentSequenceBounds_count(self.raw.as_ptr()) }
7904    }
7905
7906    /// Borrows element `index` in place. `None` when out of range.
7907    pub fn parent_sequence_bounds(&self, index: usize) -> Option<crate::support::Ref<'_, Extent>> {
7908        if index >= self.parent_sequence_bounds_len() {
7909            return None;
7910        }
7911        // SAFETY: index checked above; the pointer is interior to `self`.
7912        unsafe {
7913            Some(crate::support::Ref::new(Extent {
7914                raw: core::ptr::NonNull::new_unchecked(
7915                    ffi::whiteout_m2_M2Model_get_parentSequenceBounds_at(self.raw.as_ptr(), index),
7916                ),
7917            }))
7918        }
7919    }
7920
7921    pub fn parent_sequence_bounds_mut(
7922        &mut self,
7923        index: usize,
7924    ) -> Option<crate::support::RefMut<'_, Extent>> {
7925        if index >= self.parent_sequence_bounds_len() {
7926            return None;
7927        }
7928        // SAFETY: as above; `&mut self` guarantees exclusivity.
7929        unsafe {
7930            Some(crate::support::RefMut::new(Extent {
7931                raw: core::ptr::NonNull::new_unchecked(
7932                    ffi::whiteout_m2_M2Model_get_parentSequenceBounds_at(self.raw.as_ptr(), index),
7933                ),
7934            }))
7935        }
7936    }
7937
7938    /// Iterate the elements, borrowing each in turn.
7939    pub fn parent_sequence_bounds_iter(
7940        &self,
7941    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, Extent>> {
7942        (0..self.parent_sequence_bounds_len())
7943            .map(move |i| self.parent_sequence_bounds(i).expect("index below len"))
7944    }
7945
7946    pub fn resize_parent_sequence_bounds(&mut self, count: usize) {
7947        // SAFETY: exclusive access, so no borrow is outstanding.
7948        unsafe { ffi::whiteout_m2_M2Model_resize_parentSequenceBounds(self.raw.as_ptr(), count) }
7949    }
7950
7951    /// PEDC
7952    pub fn parent_event_data_len(&self) -> usize {
7953        // SAFETY: scalar read through a live handle.
7954        unsafe { ffi::whiteout_m2_M2Model_get_parentEventData_count(self.raw.as_ptr()) }
7955    }
7956
7957    /// Borrows element `index` in place. `None` when out of range.
7958    pub fn parent_event_data(
7959        &self,
7960        index: usize,
7961    ) -> Option<crate::support::Ref<'_, AnimationTrackBase>> {
7962        if index >= self.parent_event_data_len() {
7963            return None;
7964        }
7965        // SAFETY: index checked above; the pointer is interior to `self`.
7966        unsafe {
7967            Some(crate::support::Ref::new(AnimationTrackBase {
7968                raw: core::ptr::NonNull::new_unchecked(
7969                    ffi::whiteout_m2_M2Model_get_parentEventData_at(self.raw.as_ptr(), index),
7970                ),
7971            }))
7972        }
7973    }
7974
7975    pub fn parent_event_data_mut(
7976        &mut self,
7977        index: usize,
7978    ) -> Option<crate::support::RefMut<'_, AnimationTrackBase>> {
7979        if index >= self.parent_event_data_len() {
7980            return None;
7981        }
7982        // SAFETY: as above; `&mut self` guarantees exclusivity.
7983        unsafe {
7984            Some(crate::support::RefMut::new(AnimationTrackBase {
7985                raw: core::ptr::NonNull::new_unchecked(
7986                    ffi::whiteout_m2_M2Model_get_parentEventData_at(self.raw.as_ptr(), index),
7987                ),
7988            }))
7989        }
7990    }
7991
7992    /// Iterate the elements, borrowing each in turn.
7993    pub fn parent_event_data_iter(
7994        &self,
7995    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, AnimationTrackBase>> {
7996        (0..self.parent_event_data_len())
7997            .map(move |i| self.parent_event_data(i).expect("index below len"))
7998    }
7999
8000    pub fn resize_parent_event_data(&mut self, count: usize) {
8001        // SAFETY: exclusive access, so no borrow is outstanding.
8002        unsafe { ffi::whiteout_m2_M2Model_resize_parentEventData(self.raw.as_ptr(), count) }
8003    }
8004
8005    /// RPID
8006    /// Zero-copy view of the underlying `std::vector`.
8007    pub fn recursive_particle_model_ids(&self) -> &[u32] {
8008        // SAFETY: `_data`/`_count` describe one contiguous C++
8009        // allocation, borrowed for as long as `self` is.
8010        unsafe {
8011            let n = ffi::whiteout_m2_M2Model_get_recursiveParticleModelIds_count(self.raw.as_ptr());
8012            let p = ffi::whiteout_m2_M2Model_get_recursiveParticleModelIds_data(self.raw.as_ptr());
8013            if p.is_null() || n == 0 {
8014                &[]
8015            } else {
8016                core::slice::from_raw_parts(p, n)
8017            }
8018        }
8019    }
8020
8021    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
8022    pub fn recursive_particle_model_ids_mut(&mut self) -> &mut [u32] {
8023        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
8024        unsafe {
8025            let n = ffi::whiteout_m2_M2Model_get_recursiveParticleModelIds_count(self.raw.as_ptr());
8026            let p = ffi::whiteout_m2_M2Model_get_recursiveParticleModelIds_data(self.raw.as_ptr())
8027                as *mut u32;
8028            if p.is_null() || n == 0 {
8029                &mut []
8030            } else {
8031                core::slice::from_raw_parts_mut(p, n)
8032            }
8033        }
8034    }
8035
8036    pub fn set_recursive_particle_model_ids(&mut self, values: &[u32]) {
8037        // SAFETY: the native side copies `values` before returning.
8038        unsafe {
8039            ffi::whiteout_m2_M2Model_assign_recursiveParticleModelIds(
8040                self.raw.as_ptr(),
8041                values.as_ptr() as *const _,
8042                values.len(),
8043            )
8044        }
8045    }
8046
8047    pub fn resize_recursive_particle_model_ids(&mut self, count: usize) {
8048        // SAFETY: reallocation is safe here precisely because
8049        // `&mut self` means no slice borrow is outstanding.
8050        unsafe {
8051            ffi::whiteout_m2_M2Model_resize_recursiveParticleModelIds(self.raw.as_ptr(), count)
8052        }
8053    }
8054
8055    /// GPID
8056    /// Zero-copy view of the underlying `std::vector`.
8057    pub fn geometry_particle_model_ids(&self) -> &[u32] {
8058        // SAFETY: `_data`/`_count` describe one contiguous C++
8059        // allocation, borrowed for as long as `self` is.
8060        unsafe {
8061            let n = ffi::whiteout_m2_M2Model_get_geometryParticleModelIds_count(self.raw.as_ptr());
8062            let p = ffi::whiteout_m2_M2Model_get_geometryParticleModelIds_data(self.raw.as_ptr());
8063            if p.is_null() || n == 0 {
8064                &[]
8065            } else {
8066                core::slice::from_raw_parts(p, n)
8067            }
8068        }
8069    }
8070
8071    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
8072    pub fn geometry_particle_model_ids_mut(&mut self) -> &mut [u32] {
8073        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
8074        unsafe {
8075            let n = ffi::whiteout_m2_M2Model_get_geometryParticleModelIds_count(self.raw.as_ptr());
8076            let p = ffi::whiteout_m2_M2Model_get_geometryParticleModelIds_data(self.raw.as_ptr())
8077                as *mut u32;
8078            if p.is_null() || n == 0 {
8079                &mut []
8080            } else {
8081                core::slice::from_raw_parts_mut(p, n)
8082            }
8083        }
8084    }
8085
8086    pub fn set_geometry_particle_model_ids(&mut self, values: &[u32]) {
8087        // SAFETY: the native side copies `values` before returning.
8088        unsafe {
8089            ffi::whiteout_m2_M2Model_assign_geometryParticleModelIds(
8090                self.raw.as_ptr(),
8091                values.as_ptr() as *const _,
8092                values.len(),
8093            )
8094        }
8095    }
8096
8097    pub fn resize_geometry_particle_model_ids(&mut self, count: usize) {
8098        // SAFETY: reallocation is safe here precisely because
8099        // `&mut self` means no slice borrow is outstanding.
8100        unsafe {
8101            ffi::whiteout_m2_M2Model_resize_geometryParticleModelIds(self.raw.as_ptr(), count)
8102        }
8103    }
8104
8105    /// PGD1
8106    pub fn particle_geosets_len(&self) -> usize {
8107        // SAFETY: scalar read through a live handle.
8108        unsafe { ffi::whiteout_m2_M2Model_get_particleGeosets_count(self.raw.as_ptr()) }
8109    }
8110
8111    /// Borrows element `index` in place. `None` when out of range.
8112    pub fn particle_geosets(
8113        &self,
8114        index: usize,
8115    ) -> Option<crate::support::Ref<'_, ParticleGeosetData>> {
8116        if index >= self.particle_geosets_len() {
8117            return None;
8118        }
8119        // SAFETY: index checked above; the pointer is interior to `self`.
8120        unsafe {
8121            Some(crate::support::Ref::new(ParticleGeosetData {
8122                raw: core::ptr::NonNull::new_unchecked(
8123                    ffi::whiteout_m2_M2Model_get_particleGeosets_at(self.raw.as_ptr(), index),
8124                ),
8125            }))
8126        }
8127    }
8128
8129    pub fn particle_geosets_mut(
8130        &mut self,
8131        index: usize,
8132    ) -> Option<crate::support::RefMut<'_, ParticleGeosetData>> {
8133        if index >= self.particle_geosets_len() {
8134            return None;
8135        }
8136        // SAFETY: as above; `&mut self` guarantees exclusivity.
8137        unsafe {
8138            Some(crate::support::RefMut::new(ParticleGeosetData {
8139                raw: core::ptr::NonNull::new_unchecked(
8140                    ffi::whiteout_m2_M2Model_get_particleGeosets_at(self.raw.as_ptr(), index),
8141                ),
8142            }))
8143        }
8144    }
8145
8146    /// Iterate the elements, borrowing each in turn.
8147    pub fn particle_geosets_iter(
8148        &self,
8149    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, ParticleGeosetData>> {
8150        (0..self.particle_geosets_len())
8151            .map(move |i| self.particle_geosets(i).expect("index below len"))
8152    }
8153
8154    pub fn resize_particle_geosets(&mut self, count: usize) {
8155        // SAFETY: exclusive access, so no borrow is outstanding.
8156        unsafe { ffi::whiteout_m2_M2Model_resize_particleGeosets(self.raw.as_ptr(), count) }
8157    }
8158
8159    /// PFDC
8160    /// Zero-copy view of the underlying `std::vector`.
8161    pub fn physics_file_data(&self) -> &[u8] {
8162        // SAFETY: `_data`/`_count` describe one contiguous C++
8163        // allocation, borrowed for as long as `self` is.
8164        unsafe {
8165            let n = ffi::whiteout_m2_M2Model_get_physicsFileData_count(self.raw.as_ptr());
8166            let p = ffi::whiteout_m2_M2Model_get_physicsFileData_data(self.raw.as_ptr());
8167            if p.is_null() || n == 0 {
8168                &[]
8169            } else {
8170                core::slice::from_raw_parts(p, n)
8171            }
8172        }
8173    }
8174
8175    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
8176    pub fn physics_file_data_mut(&mut self) -> &mut [u8] {
8177        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
8178        unsafe {
8179            let n = ffi::whiteout_m2_M2Model_get_physicsFileData_count(self.raw.as_ptr());
8180            let p = ffi::whiteout_m2_M2Model_get_physicsFileData_data(self.raw.as_ptr()) as *mut u8;
8181            if p.is_null() || n == 0 {
8182                &mut []
8183            } else {
8184                core::slice::from_raw_parts_mut(p, n)
8185            }
8186        }
8187    }
8188
8189    pub fn set_physics_file_data(&mut self, values: &[u8]) {
8190        // SAFETY: the native side copies `values` before returning.
8191        unsafe {
8192            ffi::whiteout_m2_M2Model_assign_physicsFileData(
8193                self.raw.as_ptr(),
8194                values.as_ptr() as *const _,
8195                values.len(),
8196            )
8197        }
8198    }
8199
8200    pub fn resize_physics_file_data(&mut self, count: usize) {
8201        // SAFETY: reallocation is safe here precisely because
8202        // `&mut self` means no slice borrow is outstanding.
8203        unsafe { ffi::whiteout_m2_M2Model_resize_physicsFileData(self.raw.as_ptr(), count) }
8204    }
8205
8206    /// EDGF
8207    pub fn edge_fade_entries_len(&self) -> usize {
8208        // SAFETY: scalar read through a live handle.
8209        unsafe { ffi::whiteout_m2_M2Model_get_edgeFadeEntries_count(self.raw.as_ptr()) }
8210    }
8211
8212    /// Borrows element `index` in place. `None` when out of range.
8213    pub fn edge_fade_entries(&self, index: usize) -> Option<crate::support::Ref<'_, EdgeFadeData>> {
8214        if index >= self.edge_fade_entries_len() {
8215            return None;
8216        }
8217        // SAFETY: index checked above; the pointer is interior to `self`.
8218        unsafe {
8219            Some(crate::support::Ref::new(EdgeFadeData {
8220                raw: core::ptr::NonNull::new_unchecked(
8221                    ffi::whiteout_m2_M2Model_get_edgeFadeEntries_at(self.raw.as_ptr(), index),
8222                ),
8223            }))
8224        }
8225    }
8226
8227    pub fn edge_fade_entries_mut(
8228        &mut self,
8229        index: usize,
8230    ) -> Option<crate::support::RefMut<'_, EdgeFadeData>> {
8231        if index >= self.edge_fade_entries_len() {
8232            return None;
8233        }
8234        // SAFETY: as above; `&mut self` guarantees exclusivity.
8235        unsafe {
8236            Some(crate::support::RefMut::new(EdgeFadeData {
8237                raw: core::ptr::NonNull::new_unchecked(
8238                    ffi::whiteout_m2_M2Model_get_edgeFadeEntries_at(self.raw.as_ptr(), index),
8239                ),
8240            }))
8241        }
8242    }
8243
8244    /// Iterate the elements, borrowing each in turn.
8245    pub fn edge_fade_entries_iter(
8246        &self,
8247    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, EdgeFadeData>> {
8248        (0..self.edge_fade_entries_len())
8249            .map(move |i| self.edge_fade_entries(i).expect("index below len"))
8250    }
8251
8252    pub fn resize_edge_fade_entries(&mut self, count: usize) {
8253        // SAFETY: exclusive access, so no borrow is outstanding.
8254        unsafe { ffi::whiteout_m2_M2Model_resize_edgeFadeEntries(self.raw.as_ptr(), count) }
8255    }
8256
8257    /// NERF
8258    pub fn nerf_entries_len(&self) -> usize {
8259        // SAFETY: scalar read through a live handle.
8260        unsafe { ffi::whiteout_m2_M2Model_get_nerfEntries_count(self.raw.as_ptr()) }
8261    }
8262
8263    /// Borrows element `index` in place. `None` when out of range.
8264    pub fn nerf_entries(&self, index: usize) -> Option<crate::support::Ref<'_, DistanceFadeData>> {
8265        if index >= self.nerf_entries_len() {
8266            return None;
8267        }
8268        // SAFETY: index checked above; the pointer is interior to `self`.
8269        unsafe {
8270            Some(crate::support::Ref::new(DistanceFadeData {
8271                raw: core::ptr::NonNull::new_unchecked(
8272                    ffi::whiteout_m2_M2Model_get_nerfEntries_at(self.raw.as_ptr(), index),
8273                ),
8274            }))
8275        }
8276    }
8277
8278    pub fn nerf_entries_mut(
8279        &mut self,
8280        index: usize,
8281    ) -> Option<crate::support::RefMut<'_, DistanceFadeData>> {
8282        if index >= self.nerf_entries_len() {
8283            return None;
8284        }
8285        // SAFETY: as above; `&mut self` guarantees exclusivity.
8286        unsafe {
8287            Some(crate::support::RefMut::new(DistanceFadeData {
8288                raw: core::ptr::NonNull::new_unchecked(
8289                    ffi::whiteout_m2_M2Model_get_nerfEntries_at(self.raw.as_ptr(), index),
8290                ),
8291            }))
8292        }
8293    }
8294
8295    /// Iterate the elements, borrowing each in turn.
8296    pub fn nerf_entries_iter(
8297        &self,
8298    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, DistanceFadeData>> {
8299        (0..self.nerf_entries_len()).map(move |i| self.nerf_entries(i).expect("index below len"))
8300    }
8301
8302    pub fn resize_nerf_entries(&mut self, count: usize) {
8303        // SAFETY: exclusive access, so no borrow is outstanding.
8304        unsafe { ffi::whiteout_m2_M2Model_resize_nerfEntries(self.raw.as_ptr(), count) }
8305    }
8306
8307    /// DETL
8308    pub fn detailed_light_entries_len(&self) -> usize {
8309        // SAFETY: scalar read through a live handle.
8310        unsafe { ffi::whiteout_m2_M2Model_get_detailedLightEntries_count(self.raw.as_ptr()) }
8311    }
8312
8313    /// Borrows element `index` in place. `None` when out of range.
8314    pub fn detailed_light_entries(
8315        &self,
8316        index: usize,
8317    ) -> Option<crate::support::Ref<'_, DetailedLightData>> {
8318        if index >= self.detailed_light_entries_len() {
8319            return None;
8320        }
8321        // SAFETY: index checked above; the pointer is interior to `self`.
8322        unsafe {
8323            Some(crate::support::Ref::new(DetailedLightData {
8324                raw: core::ptr::NonNull::new_unchecked(
8325                    ffi::whiteout_m2_M2Model_get_detailedLightEntries_at(self.raw.as_ptr(), index),
8326                ),
8327            }))
8328        }
8329    }
8330
8331    pub fn detailed_light_entries_mut(
8332        &mut self,
8333        index: usize,
8334    ) -> Option<crate::support::RefMut<'_, DetailedLightData>> {
8335        if index >= self.detailed_light_entries_len() {
8336            return None;
8337        }
8338        // SAFETY: as above; `&mut self` guarantees exclusivity.
8339        unsafe {
8340            Some(crate::support::RefMut::new(DetailedLightData {
8341                raw: core::ptr::NonNull::new_unchecked(
8342                    ffi::whiteout_m2_M2Model_get_detailedLightEntries_at(self.raw.as_ptr(), index),
8343                ),
8344            }))
8345        }
8346    }
8347
8348    /// Iterate the elements, borrowing each in turn.
8349    pub fn detailed_light_entries_iter(
8350        &self,
8351    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, DetailedLightData>> {
8352        (0..self.detailed_light_entries_len())
8353            .map(move |i| self.detailed_light_entries(i).expect("index below len"))
8354    }
8355
8356    pub fn resize_detailed_light_entries(&mut self, count: usize) {
8357        // SAFETY: exclusive access, so no borrow is outstanding.
8358        unsafe { ffi::whiteout_m2_M2Model_resize_detailedLightEntries(self.raw.as_ptr(), count) }
8359    }
8360
8361    /// DBOC
8362    pub fn debug_occlusion_entries_len(&self) -> usize {
8363        // SAFETY: scalar read through a live handle.
8364        unsafe { ffi::whiteout_m2_M2Model_get_debugOcclusionEntries_count(self.raw.as_ptr()) }
8365    }
8366
8367    /// Borrows element `index` in place. `None` when out of range.
8368    pub fn debug_occlusion_entries(
8369        &self,
8370        index: usize,
8371    ) -> Option<crate::support::Ref<'_, DebugOcclusionData>> {
8372        if index >= self.debug_occlusion_entries_len() {
8373            return None;
8374        }
8375        // SAFETY: index checked above; the pointer is interior to `self`.
8376        unsafe {
8377            Some(crate::support::Ref::new(DebugOcclusionData {
8378                raw: core::ptr::NonNull::new_unchecked(
8379                    ffi::whiteout_m2_M2Model_get_debugOcclusionEntries_at(self.raw.as_ptr(), index),
8380                ),
8381            }))
8382        }
8383    }
8384
8385    pub fn debug_occlusion_entries_mut(
8386        &mut self,
8387        index: usize,
8388    ) -> Option<crate::support::RefMut<'_, DebugOcclusionData>> {
8389        if index >= self.debug_occlusion_entries_len() {
8390            return None;
8391        }
8392        // SAFETY: as above; `&mut self` guarantees exclusivity.
8393        unsafe {
8394            Some(crate::support::RefMut::new(DebugOcclusionData {
8395                raw: core::ptr::NonNull::new_unchecked(
8396                    ffi::whiteout_m2_M2Model_get_debugOcclusionEntries_at(self.raw.as_ptr(), index),
8397                ),
8398            }))
8399        }
8400    }
8401
8402    /// Iterate the elements, borrowing each in turn.
8403    pub fn debug_occlusion_entries_iter(
8404        &self,
8405    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, DebugOcclusionData>> {
8406        (0..self.debug_occlusion_entries_len())
8407            .map(move |i| self.debug_occlusion_entries(i).expect("index below len"))
8408    }
8409
8410    pub fn resize_debug_occlusion_entries(&mut self, count: usize) {
8411        // SAFETY: exclusive access, so no borrow is outstanding.
8412        unsafe { ffi::whiteout_m2_M2Model_resize_debugOcclusionEntries(self.raw.as_ptr(), count) }
8413    }
8414
8415    /// AFRA
8416    /// Zero-copy view of the underlying `std::vector`.
8417    pub fn anim_frame_data(&self) -> &[u8] {
8418        // SAFETY: `_data`/`_count` describe one contiguous C++
8419        // allocation, borrowed for as long as `self` is.
8420        unsafe {
8421            let n = ffi::whiteout_m2_M2Model_get_animFrameData_count(self.raw.as_ptr());
8422            let p = ffi::whiteout_m2_M2Model_get_animFrameData_data(self.raw.as_ptr());
8423            if p.is_null() || n == 0 {
8424                &[]
8425            } else {
8426                core::slice::from_raw_parts(p, n)
8427            }
8428        }
8429    }
8430
8431    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
8432    pub fn anim_frame_data_mut(&mut self) -> &mut [u8] {
8433        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
8434        unsafe {
8435            let n = ffi::whiteout_m2_M2Model_get_animFrameData_count(self.raw.as_ptr());
8436            let p = ffi::whiteout_m2_M2Model_get_animFrameData_data(self.raw.as_ptr()) as *mut u8;
8437            if p.is_null() || n == 0 {
8438                &mut []
8439            } else {
8440                core::slice::from_raw_parts_mut(p, n)
8441            }
8442        }
8443    }
8444
8445    pub fn set_anim_frame_data(&mut self, values: &[u8]) {
8446        // SAFETY: the native side copies `values` before returning.
8447        unsafe {
8448            ffi::whiteout_m2_M2Model_assign_animFrameData(
8449                self.raw.as_ptr(),
8450                values.as_ptr() as *const _,
8451                values.len(),
8452            )
8453        }
8454    }
8455
8456    pub fn resize_anim_frame_data(&mut self, count: usize) {
8457        // SAFETY: reallocation is safe here precisely because
8458        // `&mut self` means no slice borrow is outstanding.
8459        unsafe { ffi::whiteout_m2_M2Model_resize_animFrameData(self.raw.as_ptr(), count) }
8460    }
8461
8462    /// TEXL
8463    pub fn textured_light_entries_len(&self) -> usize {
8464        // SAFETY: scalar read through a live handle.
8465        unsafe { ffi::whiteout_m2_M2Model_get_texturedLightEntries_count(self.raw.as_ptr()) }
8466    }
8467
8468    /// Borrows element `index` in place. `None` when out of range.
8469    pub fn textured_light_entries(
8470        &self,
8471        index: usize,
8472    ) -> Option<crate::support::Ref<'_, TexturedLightData>> {
8473        if index >= self.textured_light_entries_len() {
8474            return None;
8475        }
8476        // SAFETY: index checked above; the pointer is interior to `self`.
8477        unsafe {
8478            Some(crate::support::Ref::new(TexturedLightData {
8479                raw: core::ptr::NonNull::new_unchecked(
8480                    ffi::whiteout_m2_M2Model_get_texturedLightEntries_at(self.raw.as_ptr(), index),
8481                ),
8482            }))
8483        }
8484    }
8485
8486    pub fn textured_light_entries_mut(
8487        &mut self,
8488        index: usize,
8489    ) -> Option<crate::support::RefMut<'_, TexturedLightData>> {
8490        if index >= self.textured_light_entries_len() {
8491            return None;
8492        }
8493        // SAFETY: as above; `&mut self` guarantees exclusivity.
8494        unsafe {
8495            Some(crate::support::RefMut::new(TexturedLightData {
8496                raw: core::ptr::NonNull::new_unchecked(
8497                    ffi::whiteout_m2_M2Model_get_texturedLightEntries_at(self.raw.as_ptr(), index),
8498                ),
8499            }))
8500        }
8501    }
8502
8503    /// Iterate the elements, borrowing each in turn.
8504    pub fn textured_light_entries_iter(
8505        &self,
8506    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, TexturedLightData>> {
8507        (0..self.textured_light_entries_len())
8508            .map(move |i| self.textured_light_entries(i).expect("index below len"))
8509    }
8510
8511    pub fn resize_textured_light_entries(&mut self, count: usize) {
8512        // SAFETY: exclusive access, so no borrow is outstanding.
8513        unsafe { ffi::whiteout_m2_M2Model_resize_texturedLightEntries(self.raw.as_ptr(), count) }
8514    }
8515}
8516
8517impl Default for Model {
8518    fn default() -> Self {
8519        Self::new()
8520    }
8521}
8522
8523pub struct Parser {
8524    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2Parser>,
8525}
8526
8527impl Drop for Parser {
8528    fn drop(&mut self) {
8529        // SAFETY: `raw` came from a native constructor and Drop runs once.
8530        unsafe { ffi::whiteout_m2_M2Parser_delete(self.raw.as_ptr()) }
8531    }
8532}
8533
8534impl Parser {
8535    /// # Safety
8536    /// `raw` must be a live handle this value takes ownership of.
8537    #[allow(dead_code)] // used by whichever methods return this type
8538    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2Parser) -> Option<Self> {
8539        core::ptr::NonNull::new(raw).map(|raw| Parser { raw })
8540    }
8541}
8542
8543// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
8544// is deliberately NOT implemented — the C++ types make no documented
8545// guarantee about concurrent use, and claiming one we haven't verified
8546// would be unsound. See `@bind thread_safe` in the plan.
8547unsafe impl Send for Parser {}
8548
8549impl core::fmt::Debug for Parser {
8550    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
8551        f.debug_struct("Parser").finish_non_exhaustive()
8552    }
8553}
8554
8555impl Parser {
8556    /// # Panics
8557    /// Panics if the native allocation fails.
8558    pub fn new() -> Self {
8559        // SAFETY: the native constructor returns a live handle; a null here
8560        // means the library is unusable.
8561        unsafe {
8562            let raw = ffi::whiteout_m2_M2Parser_new();
8563            Self::from_raw(raw).expect("native Parser allocation failed")
8564        }
8565    }
8566
8567    pub fn parse_file(
8568        &mut self,
8569        fs: Option<&crate::interfaces::HostFileSystem>,
8570        file_path: &str,
8571    ) -> Option<Model> {
8572        let file_path_cstr = std::ffi::CString::new(file_path).unwrap_or_default();
8573        // SAFETY: handle is live for the duration of the call.
8574        unsafe {
8575            Model::from_raw(ffi::whiteout_m2_M2Parser_parse(
8576                self.raw.as_ptr(),
8577                fs.map_or(core::ptr::null_mut(), |v| v.as_ptr()),
8578                file_path_cstr.as_ptr(),
8579            ))
8580        }
8581    }
8582
8583    pub fn parse_casc_fs_buffer(&mut self, casc_fs: &[u8], buffer: &[u8]) -> Option<Model> {
8584        // SAFETY: handle is live for the duration of the call.
8585        unsafe {
8586            Model::from_raw(ffi::whiteout_m2_M2Parser_parse_cascFs_buffer(
8587                self.raw.as_ptr(),
8588                casc_fs.as_ptr(),
8589                casc_fs.len(),
8590                buffer.as_ptr(),
8591                buffer.len(),
8592            ))
8593        }
8594    }
8595
8596    pub fn has_issues(&self) -> bool {
8597        // SAFETY: handle is live for the duration of the call.
8598        unsafe { ffi::whiteout_m2_M2Parser_hasIssues(self.raw.as_ptr()) != 0 }
8599    }
8600
8601    pub fn issues(&self) -> Vec<String> {
8602        // SAFETY: index stays below the reported count.
8603        unsafe {
8604            let n = ffi::whiteout_m2_M2Parser_getIssues_count(self.raw.as_ptr());
8605            (0..n)
8606                .map(|i| {
8607                    crate::support::take_string(ffi::whiteout_m2_M2Parser_getIssues_at(
8608                        self.raw.as_ptr(),
8609                        i,
8610                    ))
8611                })
8612                .collect()
8613        }
8614    }
8615}
8616
8617impl Default for Parser {
8618    fn default() -> Self {
8619        Self::new()
8620    }
8621}
8622
8623pub struct WriteOptions {
8624    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2WriteOptions>,
8625}
8626
8627impl Drop for WriteOptions {
8628    fn drop(&mut self) {
8629        // SAFETY: `raw` came from a native constructor and Drop runs once.
8630        unsafe { ffi::whiteout_m2_M2WriteOptions_delete(self.raw.as_ptr()) }
8631    }
8632}
8633
8634impl WriteOptions {
8635    /// # Safety
8636    /// `raw` must be a live handle this value takes ownership of.
8637    #[allow(dead_code)] // used by whichever methods return this type
8638    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2WriteOptions) -> Option<Self> {
8639        core::ptr::NonNull::new(raw).map(|raw| WriteOptions { raw })
8640    }
8641}
8642
8643// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
8644// is deliberately NOT implemented — the C++ types make no documented
8645// guarantee about concurrent use, and claiming one we haven't verified
8646// would be unsound. See `@bind thread_safe` in the plan.
8647unsafe impl Send for WriteOptions {}
8648
8649impl core::fmt::Debug for WriteOptions {
8650    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
8651        f.debug_struct("WriteOptions").finish_non_exhaustive()
8652    }
8653}
8654
8655impl WriteOptions {
8656    /// # Panics
8657    /// Panics if the native allocation fails.
8658    pub fn new() -> Self {
8659        // SAFETY: the native constructor returns a live handle; a null here
8660        // means the library is unusable.
8661        unsafe {
8662            let raw = ffi::whiteout_m2_M2WriteOptions_new();
8663            Self::from_raw(raw).expect("native WriteOptions allocation failed")
8664        }
8665    }
8666
8667    pub fn m_2_version(&self) -> u32 {
8668        // SAFETY: plain scalar read through a live handle.
8669        unsafe { ffi::whiteout_m2_M2WriteOptions_get_m2Version(self.raw.as_ptr()) }
8670    }
8671
8672    pub fn set_m_2_version(&mut self, value: u32) {
8673        // SAFETY: plain scalar write through a live handle.
8674        unsafe { ffi::whiteout_m2_M2WriteOptions_set_m2Version(self.raw.as_ptr(), value) }
8675    }
8676
8677    pub fn emit_skeleton(&self) -> bool {
8678        // SAFETY: plain scalar read through a live handle.
8679        unsafe { ffi::whiteout_m2_M2WriteOptions_get_emitSkeleton(self.raw.as_ptr()) != 0 }
8680    }
8681
8682    pub fn set_emit_skeleton(&mut self, value: bool) {
8683        // SAFETY: plain scalar write through a live handle.
8684        unsafe {
8685            ffi::whiteout_m2_M2WriteOptions_set_emitSkeleton(
8686                self.raw.as_ptr(),
8687                if value { 1 } else { 0 },
8688            )
8689        }
8690    }
8691
8692    pub fn base_stem(&self) -> String {
8693        // SAFETY: the native side hands over an owned CString.
8694        unsafe {
8695            crate::support::take_string(ffi::whiteout_m2_M2WriteOptions_get_baseStem(
8696                self.raw.as_ptr(),
8697            ))
8698        }
8699    }
8700
8701    pub fn set_base_stem(&mut self, value: &str) {
8702        let value = std::ffi::CString::new(value).unwrap_or_default();
8703        // SAFETY: the pointer outlives the call.
8704        unsafe { ffi::whiteout_m2_M2WriteOptions_set_baseStem(self.raw.as_ptr(), value.as_ptr()) }
8705    }
8706}
8707
8708impl Default for WriteOptions {
8709    fn default() -> Self {
8710        Self::new()
8711    }
8712}
8713
8714pub struct SerializeResult {
8715    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2SerializeResult>,
8716}
8717
8718impl Drop for SerializeResult {
8719    fn drop(&mut self) {
8720        // SAFETY: `raw` came from a native constructor and Drop runs once.
8721        unsafe { ffi::whiteout_m2_M2SerializeResult_delete(self.raw.as_ptr()) }
8722    }
8723}
8724
8725impl SerializeResult {
8726    /// # Safety
8727    /// `raw` must be a live handle this value takes ownership of.
8728    #[allow(dead_code)] // used by whichever methods return this type
8729    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2SerializeResult) -> Option<Self> {
8730        core::ptr::NonNull::new(raw).map(|raw| SerializeResult { raw })
8731    }
8732}
8733
8734// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
8735// is deliberately NOT implemented — the C++ types make no documented
8736// guarantee about concurrent use, and claiming one we haven't verified
8737// would be unsound. See `@bind thread_safe` in the plan.
8738unsafe impl Send for SerializeResult {}
8739
8740impl core::fmt::Debug for SerializeResult {
8741    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
8742        f.debug_struct("SerializeResult").finish_non_exhaustive()
8743    }
8744}
8745
8746impl SerializeResult {
8747    /// # Panics
8748    /// Panics if the native allocation fails.
8749    pub fn new() -> Self {
8750        // SAFETY: the native constructor returns a live handle; a null here
8751        // means the library is unusable.
8752        unsafe {
8753            let raw = ffi::whiteout_m2_M2SerializeResult_new();
8754            Self::from_raw(raw).expect("native SerializeResult allocation failed")
8755        }
8756    }
8757
8758    /// Zero-copy view of the underlying `std::vector`.
8759    pub fn m_2_data(&self) -> &[u8] {
8760        // SAFETY: `_data`/`_count` describe one contiguous C++
8761        // allocation, borrowed for as long as `self` is.
8762        unsafe {
8763            let n = ffi::whiteout_m2_M2SerializeResult_get_m2Data_count(self.raw.as_ptr());
8764            let p = ffi::whiteout_m2_M2SerializeResult_get_m2Data_data(self.raw.as_ptr());
8765            if p.is_null() || n == 0 {
8766                &[]
8767            } else {
8768                core::slice::from_raw_parts(p, n)
8769            }
8770        }
8771    }
8772
8773    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
8774    pub fn m_2_data_mut(&mut self) -> &mut [u8] {
8775        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
8776        unsafe {
8777            let n = ffi::whiteout_m2_M2SerializeResult_get_m2Data_count(self.raw.as_ptr());
8778            let p =
8779                ffi::whiteout_m2_M2SerializeResult_get_m2Data_data(self.raw.as_ptr()) as *mut u8;
8780            if p.is_null() || n == 0 {
8781                &mut []
8782            } else {
8783                core::slice::from_raw_parts_mut(p, n)
8784            }
8785        }
8786    }
8787
8788    pub fn set_m_2_data(&mut self, values: &[u8]) {
8789        // SAFETY: the native side copies `values` before returning.
8790        unsafe {
8791            ffi::whiteout_m2_M2SerializeResult_assign_m2Data(
8792                self.raw.as_ptr(),
8793                values.as_ptr() as *const _,
8794                values.len(),
8795            )
8796        }
8797    }
8798
8799    pub fn resize_m_2_data(&mut self, count: usize) {
8800        // SAFETY: reallocation is safe here precisely because
8801        // `&mut self` means no slice borrow is outstanding.
8802        unsafe { ffi::whiteout_m2_M2SerializeResult_resize_m2Data(self.raw.as_ptr(), count) }
8803    }
8804}
8805
8806impl Default for SerializeResult {
8807    fn default() -> Self {
8808        Self::new()
8809    }
8810}
8811
8812pub struct Writer {
8813    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2Writer>,
8814}
8815
8816impl Drop for Writer {
8817    fn drop(&mut self) {
8818        // SAFETY: `raw` came from a native constructor and Drop runs once.
8819        unsafe { ffi::whiteout_m2_M2Writer_delete(self.raw.as_ptr()) }
8820    }
8821}
8822
8823impl Writer {
8824    /// # Safety
8825    /// `raw` must be a live handle this value takes ownership of.
8826    #[allow(dead_code)] // used by whichever methods return this type
8827    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2Writer) -> Option<Self> {
8828        core::ptr::NonNull::new(raw).map(|raw| Writer { raw })
8829    }
8830}
8831
8832// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
8833// is deliberately NOT implemented — the C++ types make no documented
8834// guarantee about concurrent use, and claiming one we haven't verified
8835// would be unsound. See `@bind thread_safe` in the plan.
8836unsafe impl Send for Writer {}
8837
8838impl core::fmt::Debug for Writer {
8839    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
8840        f.debug_struct("Writer").finish_non_exhaustive()
8841    }
8842}
8843
8844impl Writer {
8845    /// # Panics
8846    /// Panics if the native allocation fails.
8847    pub fn new() -> Self {
8848        // SAFETY: the native constructor returns a live handle; a null here
8849        // means the library is unusable.
8850        unsafe {
8851            let raw = ffi::whiteout_m2_M2Writer_new();
8852            Self::from_raw(raw).expect("native Writer allocation failed")
8853        }
8854    }
8855
8856    pub fn write_file(
8857        &mut self,
8858        fs: Option<&crate::interfaces::HostFileSystem>,
8859        file_path: &str,
8860        model: &Model,
8861    ) {
8862        let file_path_cstr = std::ffi::CString::new(file_path).unwrap_or_default();
8863        // SAFETY: handle is live for the duration of the call.
8864        unsafe {
8865            ffi::whiteout_m2_M2Writer_write(
8866                self.raw.as_ptr(),
8867                fs.map_or(core::ptr::null_mut(), |v| v.as_ptr()),
8868                file_path_cstr.as_ptr(),
8869                model.raw.as_ptr(),
8870            );
8871        }
8872    }
8873
8874    pub fn write_casc_fs_model(
8875        &mut self,
8876        casc_fs: Option<&crate::interfaces::HostCascFileSystem>,
8877        model: &Model,
8878    ) {
8879        // SAFETY: handle is live for the duration of the call.
8880        unsafe {
8881            ffi::whiteout_m2_M2Writer_write_cascFs_model(
8882                self.raw.as_ptr(),
8883                casc_fs.map_or(core::ptr::null_mut(), |v| v.as_ptr()),
8884                model.raw.as_ptr(),
8885            );
8886        }
8887    }
8888
8889    pub fn write(&mut self, model: &Model) -> Option<SerializeResult> {
8890        // SAFETY: handle is live for the duration of the call.
8891        unsafe {
8892            SerializeResult::from_raw(ffi::whiteout_m2_M2Writer_write_model(
8893                self.raw.as_ptr(),
8894                model.raw.as_ptr(),
8895            ))
8896        }
8897    }
8898
8899    pub fn has_issues(&self) -> bool {
8900        // SAFETY: handle is live for the duration of the call.
8901        unsafe { ffi::whiteout_m2_M2Writer_hasIssues(self.raw.as_ptr()) != 0 }
8902    }
8903
8904    pub fn issues(&self) -> Vec<String> {
8905        // SAFETY: index stays below the reported count.
8906        unsafe {
8907            let n = ffi::whiteout_m2_M2Writer_getIssues_count(self.raw.as_ptr());
8908            (0..n)
8909                .map(|i| {
8910                    crate::support::take_string(ffi::whiteout_m2_M2Writer_getIssues_at(
8911                        self.raw.as_ptr(),
8912                        i,
8913                    ))
8914                })
8915                .collect()
8916        }
8917    }
8918}
8919
8920impl Default for Writer {
8921    fn default() -> Self {
8922        Self::new()
8923    }
8924}
8925
8926pub struct AnimationTrackVector3f {
8927    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2AnimationTrackVector3f>,
8928}
8929
8930impl Drop for AnimationTrackVector3f {
8931    fn drop(&mut self) {
8932        // SAFETY: `raw` came from a native constructor and Drop runs once.
8933        unsafe { ffi::whiteout_m2_M2AnimationTrackVector3f_delete(self.raw.as_ptr()) }
8934    }
8935}
8936
8937impl AnimationTrackVector3f {
8938    /// # Safety
8939    /// `raw` must be a live handle this value takes ownership of.
8940    #[allow(dead_code)] // used by whichever methods return this type
8941    pub(crate) unsafe fn from_raw(
8942        raw: *mut ffi::whiteout_M2AnimationTrackVector3f,
8943    ) -> Option<Self> {
8944        core::ptr::NonNull::new(raw).map(|raw| AnimationTrackVector3f { raw })
8945    }
8946}
8947
8948// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
8949// is deliberately NOT implemented — the C++ types make no documented
8950// guarantee about concurrent use, and claiming one we haven't verified
8951// would be unsound. See `@bind thread_safe` in the plan.
8952unsafe impl Send for AnimationTrackVector3f {}
8953
8954impl core::fmt::Debug for AnimationTrackVector3f {
8955    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
8956        f.debug_struct("AnimationTrackVector3f")
8957            .finish_non_exhaustive()
8958    }
8959}
8960
8961impl AnimationTrackVector3f {
8962    /// # Panics
8963    /// Panics if the native allocation fails.
8964    pub fn new() -> Self {
8965        // SAFETY: the native constructor returns a live handle; a null here
8966        // means the library is unusable.
8967        unsafe {
8968            let raw = ffi::whiteout_m2_M2AnimationTrackVector3f_new();
8969            Self::from_raw(raw).expect("native AnimationTrackVector3f allocation failed")
8970        }
8971    }
8972
8973    pub fn interpolation_type(&self) -> InterpolationType {
8974        // SAFETY: scalar read; the discriminant is validated below.
8975        unsafe {
8976            ffi::whiteout_m2_M2AnimationTrackVector3f_get_interpolationType(self.raw.as_ptr())
8977        }
8978        .try_into()
8979        .expect("unknown enum discriminant from the native library")
8980    }
8981
8982    pub fn set_interpolation_type(&mut self, value: InterpolationType) {
8983        // SAFETY: scalar write through a live handle.
8984        unsafe {
8985            ffi::whiteout_m2_M2AnimationTrackVector3f_set_interpolationType(
8986                self.raw.as_ptr(),
8987                value as i32,
8988            )
8989        }
8990    }
8991
8992    pub fn global_sequence_id(&self) -> u16 {
8993        // SAFETY: plain scalar read through a live handle.
8994        unsafe { ffi::whiteout_m2_M2AnimationTrackVector3f_get_globalSequenceId(self.raw.as_ptr()) }
8995    }
8996
8997    pub fn set_global_sequence_id(&mut self, value: u16) {
8998        // SAFETY: plain scalar write through a live handle.
8999        unsafe {
9000            ffi::whiteout_m2_M2AnimationTrackVector3f_set_globalSequenceId(self.raw.as_ptr(), value)
9001        }
9002    }
9003
9004    /// Number of inner sequences.
9005    pub fn timestamps_len(&self) -> usize {
9006        // SAFETY: scalar read through a live handle.
9007        unsafe { ffi::whiteout_m2_M2AnimationTrackVector3f_get_timestamps_count(self.raw.as_ptr()) }
9008    }
9009
9010    /// Zero-copy view of inner sequence `outer`. Empty when out of range.
9011    ///
9012    /// Each inner vector is contiguous on its own, but the outer one
9013    /// is a vector of vectors — so this borrows per sequence rather
9014    /// than handing back one flat slice.
9015    pub fn timestamps(&self, outer: usize) -> &[u32] {
9016        if outer >= self.timestamps_len() {
9017            return &[];
9018        }
9019        // SAFETY: index checked; the pointer borrows `self`.
9020        unsafe {
9021            let n = ffi::whiteout_m2_M2AnimationTrackVector3f_get_timestamps_inner_count(
9022                self.raw.as_ptr(),
9023                outer,
9024            );
9025            let p = ffi::whiteout_m2_M2AnimationTrackVector3f_get_timestamps_inner_data(
9026                self.raw.as_ptr(),
9027                outer,
9028            );
9029            if p.is_null() || n == 0 {
9030                &[]
9031            } else {
9032                core::slice::from_raw_parts(p, n)
9033            }
9034        }
9035    }
9036
9037    pub fn timestamps_mut(&mut self, outer: usize) -> &mut [u32] {
9038        if outer >= self.timestamps_len() {
9039            return &mut [];
9040        }
9041        // SAFETY: as above; `&mut self` rules out aliasing.
9042        unsafe {
9043            let n = ffi::whiteout_m2_M2AnimationTrackVector3f_get_timestamps_inner_count(
9044                self.raw.as_ptr(),
9045                outer,
9046            );
9047            let p = ffi::whiteout_m2_M2AnimationTrackVector3f_get_timestamps_inner_data(
9048                self.raw.as_ptr(),
9049                outer,
9050            ) as *mut u32;
9051            if p.is_null() || n == 0 {
9052                &mut []
9053            } else {
9054                core::slice::from_raw_parts_mut(p, n)
9055            }
9056        }
9057    }
9058
9059    pub fn set_timestamps(&mut self, outer: usize, values: &[u32]) {
9060        // SAFETY: the native side copies `values` before returning.
9061        unsafe {
9062            ffi::whiteout_m2_M2AnimationTrackVector3f_assign_timestamps_inner(
9063                self.raw.as_ptr(),
9064                outer,
9065                values.as_ptr() as *const _,
9066                values.len(),
9067            )
9068        }
9069    }
9070
9071    /// Resize the outer sequence. Do this before taking any borrow.
9072    pub fn resize_timestamps(&mut self, count: usize) {
9073        // SAFETY: exclusive access, so no borrow is outstanding.
9074        unsafe {
9075            ffi::whiteout_m2_M2AnimationTrackVector3f_resize_timestamps(self.raw.as_ptr(), count)
9076        }
9077    }
9078
9079    pub fn resize_timestamps_inner(&mut self, outer: usize, count: usize) {
9080        // SAFETY: as above.
9081        unsafe {
9082            ffi::whiteout_m2_M2AnimationTrackVector3f_resize_timestamps_inner(
9083                self.raw.as_ptr(),
9084                outer,
9085                count,
9086            )
9087        }
9088    }
9089
9090    /// Number of inner sequences.
9091    pub fn values_len(&self) -> usize {
9092        // SAFETY: scalar read through a live handle.
9093        unsafe { ffi::whiteout_m2_M2AnimationTrackVector3f_get_values_count(self.raw.as_ptr()) }
9094    }
9095
9096    /// Zero-copy view of inner sequence `outer`. Empty when out of range.
9097    ///
9098    /// Each inner vector is contiguous on its own, but the outer one
9099    /// is a vector of vectors — so this borrows per sequence rather
9100    /// than handing back one flat slice.
9101    pub fn values(&self, outer: usize) -> &[crate::math::Vector3f] {
9102        if outer >= self.values_len() {
9103            return &[];
9104        }
9105        // SAFETY: index checked; the pointer borrows `self`.
9106        unsafe {
9107            let n = ffi::whiteout_m2_M2AnimationTrackVector3f_get_values_inner_count(
9108                self.raw.as_ptr(),
9109                outer,
9110            );
9111            let p = ffi::whiteout_m2_M2AnimationTrackVector3f_get_values_inner_data(
9112                self.raw.as_ptr(),
9113                outer,
9114            ) as *const crate::math::Vector3f;
9115            if p.is_null() || n == 0 {
9116                &[]
9117            } else {
9118                core::slice::from_raw_parts(p, n)
9119            }
9120        }
9121    }
9122
9123    pub fn values_mut(&mut self, outer: usize) -> &mut [crate::math::Vector3f] {
9124        if outer >= self.values_len() {
9125            return &mut [];
9126        }
9127        // SAFETY: as above; `&mut self` rules out aliasing.
9128        unsafe {
9129            let n = ffi::whiteout_m2_M2AnimationTrackVector3f_get_values_inner_count(
9130                self.raw.as_ptr(),
9131                outer,
9132            );
9133            let p = ffi::whiteout_m2_M2AnimationTrackVector3f_get_values_inner_data(
9134                self.raw.as_ptr(),
9135                outer,
9136            ) as *const crate::math::Vector3f as *mut crate::math::Vector3f;
9137            if p.is_null() || n == 0 {
9138                &mut []
9139            } else {
9140                core::slice::from_raw_parts_mut(p, n)
9141            }
9142        }
9143    }
9144
9145    pub fn set_values(&mut self, outer: usize, values: &[crate::math::Vector3f]) {
9146        // SAFETY: the native side copies `values` before returning.
9147        unsafe {
9148            ffi::whiteout_m2_M2AnimationTrackVector3f_assign_values_inner(
9149                self.raw.as_ptr(),
9150                outer,
9151                values.as_ptr() as *const _,
9152                values.len(),
9153            )
9154        }
9155    }
9156
9157    /// Resize the outer sequence. Do this before taking any borrow.
9158    pub fn resize_values(&mut self, count: usize) {
9159        // SAFETY: exclusive access, so no borrow is outstanding.
9160        unsafe { ffi::whiteout_m2_M2AnimationTrackVector3f_resize_values(self.raw.as_ptr(), count) }
9161    }
9162
9163    pub fn resize_values_inner(&mut self, outer: usize, count: usize) {
9164        // SAFETY: as above.
9165        unsafe {
9166            ffi::whiteout_m2_M2AnimationTrackVector3f_resize_values_inner(
9167                self.raw.as_ptr(),
9168                outer,
9169                count,
9170            )
9171        }
9172    }
9173}
9174
9175impl Default for AnimationTrackVector3f {
9176    fn default() -> Self {
9177        Self::new()
9178    }
9179}
9180
9181pub struct AnimationTrackM2CompatQuaternion {
9182    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2AnimationTrackM2CompatQuaternion>,
9183}
9184
9185impl Drop for AnimationTrackM2CompatQuaternion {
9186    fn drop(&mut self) {
9187        // SAFETY: `raw` came from a native constructor and Drop runs once.
9188        unsafe { ffi::whiteout_m2_M2AnimationTrackM2CompatQuaternion_delete(self.raw.as_ptr()) }
9189    }
9190}
9191
9192impl AnimationTrackM2CompatQuaternion {
9193    /// # Safety
9194    /// `raw` must be a live handle this value takes ownership of.
9195    #[allow(dead_code)] // used by whichever methods return this type
9196    pub(crate) unsafe fn from_raw(
9197        raw: *mut ffi::whiteout_M2AnimationTrackM2CompatQuaternion,
9198    ) -> Option<Self> {
9199        core::ptr::NonNull::new(raw).map(|raw| AnimationTrackM2CompatQuaternion { raw })
9200    }
9201}
9202
9203// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
9204// is deliberately NOT implemented — the C++ types make no documented
9205// guarantee about concurrent use, and claiming one we haven't verified
9206// would be unsound. See `@bind thread_safe` in the plan.
9207unsafe impl Send for AnimationTrackM2CompatQuaternion {}
9208
9209impl core::fmt::Debug for AnimationTrackM2CompatQuaternion {
9210    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
9211        f.debug_struct("AnimationTrackM2CompatQuaternion")
9212            .finish_non_exhaustive()
9213    }
9214}
9215
9216impl AnimationTrackM2CompatQuaternion {
9217    /// # Panics
9218    /// Panics if the native allocation fails.
9219    pub fn new() -> Self {
9220        // SAFETY: the native constructor returns a live handle; a null here
9221        // means the library is unusable.
9222        unsafe {
9223            let raw = ffi::whiteout_m2_M2AnimationTrackM2CompatQuaternion_new();
9224            Self::from_raw(raw).expect("native AnimationTrackM2CompatQuaternion allocation failed")
9225        }
9226    }
9227
9228    pub fn interpolation_type(&self) -> InterpolationType {
9229        // SAFETY: scalar read; the discriminant is validated below.
9230        unsafe {
9231            ffi::whiteout_m2_M2AnimationTrackM2CompatQuaternion_get_interpolationType(
9232                self.raw.as_ptr(),
9233            )
9234        }
9235        .try_into()
9236        .expect("unknown enum discriminant from the native library")
9237    }
9238
9239    pub fn set_interpolation_type(&mut self, value: InterpolationType) {
9240        // SAFETY: scalar write through a live handle.
9241        unsafe {
9242            ffi::whiteout_m2_M2AnimationTrackM2CompatQuaternion_set_interpolationType(
9243                self.raw.as_ptr(),
9244                value as i32,
9245            )
9246        }
9247    }
9248
9249    pub fn global_sequence_id(&self) -> u16 {
9250        // SAFETY: plain scalar read through a live handle.
9251        unsafe {
9252            ffi::whiteout_m2_M2AnimationTrackM2CompatQuaternion_get_globalSequenceId(
9253                self.raw.as_ptr(),
9254            )
9255        }
9256    }
9257
9258    pub fn set_global_sequence_id(&mut self, value: u16) {
9259        // SAFETY: plain scalar write through a live handle.
9260        unsafe {
9261            ffi::whiteout_m2_M2AnimationTrackM2CompatQuaternion_set_globalSequenceId(
9262                self.raw.as_ptr(),
9263                value,
9264            )
9265        }
9266    }
9267
9268    /// Number of inner sequences.
9269    pub fn timestamps_len(&self) -> usize {
9270        // SAFETY: scalar read through a live handle.
9271        unsafe {
9272            ffi::whiteout_m2_M2AnimationTrackM2CompatQuaternion_get_timestamps_count(
9273                self.raw.as_ptr(),
9274            )
9275        }
9276    }
9277
9278    /// Zero-copy view of inner sequence `outer`. Empty when out of range.
9279    ///
9280    /// Each inner vector is contiguous on its own, but the outer one
9281    /// is a vector of vectors — so this borrows per sequence rather
9282    /// than handing back one flat slice.
9283    pub fn timestamps(&self, outer: usize) -> &[u32] {
9284        if outer >= self.timestamps_len() {
9285            return &[];
9286        }
9287        // SAFETY: index checked; the pointer borrows `self`.
9288        unsafe {
9289            let n = ffi::whiteout_m2_M2AnimationTrackM2CompatQuaternion_get_timestamps_inner_count(
9290                self.raw.as_ptr(),
9291                outer,
9292            );
9293            let p = ffi::whiteout_m2_M2AnimationTrackM2CompatQuaternion_get_timestamps_inner_data(
9294                self.raw.as_ptr(),
9295                outer,
9296            );
9297            if p.is_null() || n == 0 {
9298                &[]
9299            } else {
9300                core::slice::from_raw_parts(p, n)
9301            }
9302        }
9303    }
9304
9305    pub fn timestamps_mut(&mut self, outer: usize) -> &mut [u32] {
9306        if outer >= self.timestamps_len() {
9307            return &mut [];
9308        }
9309        // SAFETY: as above; `&mut self` rules out aliasing.
9310        unsafe {
9311            let n = ffi::whiteout_m2_M2AnimationTrackM2CompatQuaternion_get_timestamps_inner_count(
9312                self.raw.as_ptr(),
9313                outer,
9314            );
9315            let p = ffi::whiteout_m2_M2AnimationTrackM2CompatQuaternion_get_timestamps_inner_data(
9316                self.raw.as_ptr(),
9317                outer,
9318            ) as *mut u32;
9319            if p.is_null() || n == 0 {
9320                &mut []
9321            } else {
9322                core::slice::from_raw_parts_mut(p, n)
9323            }
9324        }
9325    }
9326
9327    pub fn set_timestamps(&mut self, outer: usize, values: &[u32]) {
9328        // SAFETY: the native side copies `values` before returning.
9329        unsafe {
9330            ffi::whiteout_m2_M2AnimationTrackM2CompatQuaternion_assign_timestamps_inner(
9331                self.raw.as_ptr(),
9332                outer,
9333                values.as_ptr() as *const _,
9334                values.len(),
9335            )
9336        }
9337    }
9338
9339    /// Resize the outer sequence. Do this before taking any borrow.
9340    pub fn resize_timestamps(&mut self, count: usize) {
9341        // SAFETY: exclusive access, so no borrow is outstanding.
9342        unsafe {
9343            ffi::whiteout_m2_M2AnimationTrackM2CompatQuaternion_resize_timestamps(
9344                self.raw.as_ptr(),
9345                count,
9346            )
9347        }
9348    }
9349
9350    pub fn resize_timestamps_inner(&mut self, outer: usize, count: usize) {
9351        // SAFETY: as above.
9352        unsafe {
9353            ffi::whiteout_m2_M2AnimationTrackM2CompatQuaternion_resize_timestamps_inner(
9354                self.raw.as_ptr(),
9355                outer,
9356                count,
9357            )
9358        }
9359    }
9360
9361    /// Number of inner sequences.
9362    pub fn values_len(&self) -> usize {
9363        // SAFETY: scalar read through a live handle.
9364        unsafe {
9365            ffi::whiteout_m2_M2AnimationTrackM2CompatQuaternion_get_values_count(self.raw.as_ptr())
9366        }
9367    }
9368
9369    /// Length of inner sequence `outer`.
9370    pub fn values_inner_len(&self, outer: usize) -> usize {
9371        if outer >= self.values_len() {
9372            return 0;
9373        }
9374        // SAFETY: index checked above.
9375        unsafe {
9376            ffi::whiteout_m2_M2AnimationTrackM2CompatQuaternion_get_values_inner_count(
9377                self.raw.as_ptr(),
9378                outer,
9379            )
9380        }
9381    }
9382
9383    /// Borrow element `inner` of sequence `outer` in place.
9384    pub fn values(
9385        &self,
9386        outer: usize,
9387        inner: usize,
9388    ) -> Option<crate::support::Ref<'_, CompatQuaternion>> {
9389        if inner >= self.values_inner_len(outer) {
9390            return None;
9391        }
9392        // SAFETY: both indices checked; the pointer is
9393        // interior to `self`.
9394        unsafe {
9395            Some(crate::support::Ref::new(CompatQuaternion {
9396                raw: core::ptr::NonNull::new_unchecked(
9397                    ffi::whiteout_m2_M2AnimationTrackM2CompatQuaternion_get_values_at(
9398                        self.raw.as_ptr(),
9399                        outer,
9400                        inner,
9401                    ),
9402                ),
9403            }))
9404        }
9405    }
9406
9407    pub fn values_mut(
9408        &mut self,
9409        outer: usize,
9410        inner: usize,
9411    ) -> Option<crate::support::RefMut<'_, CompatQuaternion>> {
9412        if inner >= self.values_inner_len(outer) {
9413            return None;
9414        }
9415        // SAFETY: as above; `&mut self` guarantees exclusivity.
9416        unsafe {
9417            Some(crate::support::RefMut::new(CompatQuaternion {
9418                raw: core::ptr::NonNull::new_unchecked(
9419                    ffi::whiteout_m2_M2AnimationTrackM2CompatQuaternion_get_values_at(
9420                        self.raw.as_ptr(),
9421                        outer,
9422                        inner,
9423                    ),
9424                ),
9425            }))
9426        }
9427    }
9428
9429    /// Resize the outer sequence. Do this before taking a borrow.
9430    pub fn resize_values(&mut self, count: usize) {
9431        // SAFETY: exclusive access, so no borrow is outstanding.
9432        unsafe {
9433            ffi::whiteout_m2_M2AnimationTrackM2CompatQuaternion_resize_values(
9434                self.raw.as_ptr(),
9435                count,
9436            )
9437        }
9438    }
9439
9440    pub fn resize_values_inner(&mut self, outer: usize, count: usize) {
9441        // SAFETY: as above.
9442        unsafe {
9443            ffi::whiteout_m2_M2AnimationTrackM2CompatQuaternion_resize_values_inner(
9444                self.raw.as_ptr(),
9445                outer,
9446                count,
9447            )
9448        }
9449    }
9450}
9451
9452impl Default for AnimationTrackM2CompatQuaternion {
9453    fn default() -> Self {
9454        Self::new()
9455    }
9456}
9457
9458pub struct AnimationTrackI16 {
9459    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2AnimationTrackI16>,
9460}
9461
9462impl Drop for AnimationTrackI16 {
9463    fn drop(&mut self) {
9464        // SAFETY: `raw` came from a native constructor and Drop runs once.
9465        unsafe { ffi::whiteout_m2_M2AnimationTrackI16_delete(self.raw.as_ptr()) }
9466    }
9467}
9468
9469impl AnimationTrackI16 {
9470    /// # Safety
9471    /// `raw` must be a live handle this value takes ownership of.
9472    #[allow(dead_code)] // used by whichever methods return this type
9473    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2AnimationTrackI16) -> Option<Self> {
9474        core::ptr::NonNull::new(raw).map(|raw| AnimationTrackI16 { raw })
9475    }
9476}
9477
9478// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
9479// is deliberately NOT implemented — the C++ types make no documented
9480// guarantee about concurrent use, and claiming one we haven't verified
9481// would be unsound. See `@bind thread_safe` in the plan.
9482unsafe impl Send for AnimationTrackI16 {}
9483
9484impl core::fmt::Debug for AnimationTrackI16 {
9485    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
9486        f.debug_struct("AnimationTrackI16").finish_non_exhaustive()
9487    }
9488}
9489
9490impl AnimationTrackI16 {
9491    /// # Panics
9492    /// Panics if the native allocation fails.
9493    pub fn new() -> Self {
9494        // SAFETY: the native constructor returns a live handle; a null here
9495        // means the library is unusable.
9496        unsafe {
9497            let raw = ffi::whiteout_m2_M2AnimationTrackI16_new();
9498            Self::from_raw(raw).expect("native AnimationTrackI16 allocation failed")
9499        }
9500    }
9501
9502    pub fn interpolation_type(&self) -> InterpolationType {
9503        // SAFETY: scalar read; the discriminant is validated below.
9504        unsafe { ffi::whiteout_m2_M2AnimationTrackI16_get_interpolationType(self.raw.as_ptr()) }
9505            .try_into()
9506            .expect("unknown enum discriminant from the native library")
9507    }
9508
9509    pub fn set_interpolation_type(&mut self, value: InterpolationType) {
9510        // SAFETY: scalar write through a live handle.
9511        unsafe {
9512            ffi::whiteout_m2_M2AnimationTrackI16_set_interpolationType(
9513                self.raw.as_ptr(),
9514                value as i32,
9515            )
9516        }
9517    }
9518
9519    pub fn global_sequence_id(&self) -> u16 {
9520        // SAFETY: plain scalar read through a live handle.
9521        unsafe { ffi::whiteout_m2_M2AnimationTrackI16_get_globalSequenceId(self.raw.as_ptr()) }
9522    }
9523
9524    pub fn set_global_sequence_id(&mut self, value: u16) {
9525        // SAFETY: plain scalar write through a live handle.
9526        unsafe {
9527            ffi::whiteout_m2_M2AnimationTrackI16_set_globalSequenceId(self.raw.as_ptr(), value)
9528        }
9529    }
9530
9531    /// Number of inner sequences.
9532    pub fn timestamps_len(&self) -> usize {
9533        // SAFETY: scalar read through a live handle.
9534        unsafe { ffi::whiteout_m2_M2AnimationTrackI16_get_timestamps_count(self.raw.as_ptr()) }
9535    }
9536
9537    /// Zero-copy view of inner sequence `outer`. Empty when out of range.
9538    ///
9539    /// Each inner vector is contiguous on its own, but the outer one
9540    /// is a vector of vectors — so this borrows per sequence rather
9541    /// than handing back one flat slice.
9542    pub fn timestamps(&self, outer: usize) -> &[u32] {
9543        if outer >= self.timestamps_len() {
9544            return &[];
9545        }
9546        // SAFETY: index checked; the pointer borrows `self`.
9547        unsafe {
9548            let n = ffi::whiteout_m2_M2AnimationTrackI16_get_timestamps_inner_count(
9549                self.raw.as_ptr(),
9550                outer,
9551            );
9552            let p = ffi::whiteout_m2_M2AnimationTrackI16_get_timestamps_inner_data(
9553                self.raw.as_ptr(),
9554                outer,
9555            );
9556            if p.is_null() || n == 0 {
9557                &[]
9558            } else {
9559                core::slice::from_raw_parts(p, n)
9560            }
9561        }
9562    }
9563
9564    pub fn timestamps_mut(&mut self, outer: usize) -> &mut [u32] {
9565        if outer >= self.timestamps_len() {
9566            return &mut [];
9567        }
9568        // SAFETY: as above; `&mut self` rules out aliasing.
9569        unsafe {
9570            let n = ffi::whiteout_m2_M2AnimationTrackI16_get_timestamps_inner_count(
9571                self.raw.as_ptr(),
9572                outer,
9573            );
9574            let p = ffi::whiteout_m2_M2AnimationTrackI16_get_timestamps_inner_data(
9575                self.raw.as_ptr(),
9576                outer,
9577            ) as *mut u32;
9578            if p.is_null() || n == 0 {
9579                &mut []
9580            } else {
9581                core::slice::from_raw_parts_mut(p, n)
9582            }
9583        }
9584    }
9585
9586    pub fn set_timestamps(&mut self, outer: usize, values: &[u32]) {
9587        // SAFETY: the native side copies `values` before returning.
9588        unsafe {
9589            ffi::whiteout_m2_M2AnimationTrackI16_assign_timestamps_inner(
9590                self.raw.as_ptr(),
9591                outer,
9592                values.as_ptr() as *const _,
9593                values.len(),
9594            )
9595        }
9596    }
9597
9598    /// Resize the outer sequence. Do this before taking any borrow.
9599    pub fn resize_timestamps(&mut self, count: usize) {
9600        // SAFETY: exclusive access, so no borrow is outstanding.
9601        unsafe { ffi::whiteout_m2_M2AnimationTrackI16_resize_timestamps(self.raw.as_ptr(), count) }
9602    }
9603
9604    pub fn resize_timestamps_inner(&mut self, outer: usize, count: usize) {
9605        // SAFETY: as above.
9606        unsafe {
9607            ffi::whiteout_m2_M2AnimationTrackI16_resize_timestamps_inner(
9608                self.raw.as_ptr(),
9609                outer,
9610                count,
9611            )
9612        }
9613    }
9614
9615    /// Number of inner sequences.
9616    pub fn values_len(&self) -> usize {
9617        // SAFETY: scalar read through a live handle.
9618        unsafe { ffi::whiteout_m2_M2AnimationTrackI16_get_values_count(self.raw.as_ptr()) }
9619    }
9620
9621    /// Zero-copy view of inner sequence `outer`. Empty when out of range.
9622    ///
9623    /// Each inner vector is contiguous on its own, but the outer one
9624    /// is a vector of vectors — so this borrows per sequence rather
9625    /// than handing back one flat slice.
9626    pub fn values(&self, outer: usize) -> &[i16] {
9627        if outer >= self.values_len() {
9628            return &[];
9629        }
9630        // SAFETY: index checked; the pointer borrows `self`.
9631        unsafe {
9632            let n = ffi::whiteout_m2_M2AnimationTrackI16_get_values_inner_count(
9633                self.raw.as_ptr(),
9634                outer,
9635            );
9636            let p = ffi::whiteout_m2_M2AnimationTrackI16_get_values_inner_data(
9637                self.raw.as_ptr(),
9638                outer,
9639            );
9640            if p.is_null() || n == 0 {
9641                &[]
9642            } else {
9643                core::slice::from_raw_parts(p, n)
9644            }
9645        }
9646    }
9647
9648    pub fn values_mut(&mut self, outer: usize) -> &mut [i16] {
9649        if outer >= self.values_len() {
9650            return &mut [];
9651        }
9652        // SAFETY: as above; `&mut self` rules out aliasing.
9653        unsafe {
9654            let n = ffi::whiteout_m2_M2AnimationTrackI16_get_values_inner_count(
9655                self.raw.as_ptr(),
9656                outer,
9657            );
9658            let p = ffi::whiteout_m2_M2AnimationTrackI16_get_values_inner_data(
9659                self.raw.as_ptr(),
9660                outer,
9661            ) as *mut i16;
9662            if p.is_null() || n == 0 {
9663                &mut []
9664            } else {
9665                core::slice::from_raw_parts_mut(p, n)
9666            }
9667        }
9668    }
9669
9670    pub fn set_values(&mut self, outer: usize, values: &[i16]) {
9671        // SAFETY: the native side copies `values` before returning.
9672        unsafe {
9673            ffi::whiteout_m2_M2AnimationTrackI16_assign_values_inner(
9674                self.raw.as_ptr(),
9675                outer,
9676                values.as_ptr() as *const _,
9677                values.len(),
9678            )
9679        }
9680    }
9681
9682    /// Resize the outer sequence. Do this before taking any borrow.
9683    pub fn resize_values(&mut self, count: usize) {
9684        // SAFETY: exclusive access, so no borrow is outstanding.
9685        unsafe { ffi::whiteout_m2_M2AnimationTrackI16_resize_values(self.raw.as_ptr(), count) }
9686    }
9687
9688    pub fn resize_values_inner(&mut self, outer: usize, count: usize) {
9689        // SAFETY: as above.
9690        unsafe {
9691            ffi::whiteout_m2_M2AnimationTrackI16_resize_values_inner(
9692                self.raw.as_ptr(),
9693                outer,
9694                count,
9695            )
9696        }
9697    }
9698}
9699
9700impl Default for AnimationTrackI16 {
9701    fn default() -> Self {
9702        Self::new()
9703    }
9704}
9705
9706pub struct AnimationTrackF32 {
9707    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2AnimationTrackF32>,
9708}
9709
9710impl Drop for AnimationTrackF32 {
9711    fn drop(&mut self) {
9712        // SAFETY: `raw` came from a native constructor and Drop runs once.
9713        unsafe { ffi::whiteout_m2_M2AnimationTrackF32_delete(self.raw.as_ptr()) }
9714    }
9715}
9716
9717impl AnimationTrackF32 {
9718    /// # Safety
9719    /// `raw` must be a live handle this value takes ownership of.
9720    #[allow(dead_code)] // used by whichever methods return this type
9721    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2AnimationTrackF32) -> Option<Self> {
9722        core::ptr::NonNull::new(raw).map(|raw| AnimationTrackF32 { raw })
9723    }
9724}
9725
9726// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
9727// is deliberately NOT implemented — the C++ types make no documented
9728// guarantee about concurrent use, and claiming one we haven't verified
9729// would be unsound. See `@bind thread_safe` in the plan.
9730unsafe impl Send for AnimationTrackF32 {}
9731
9732impl core::fmt::Debug for AnimationTrackF32 {
9733    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
9734        f.debug_struct("AnimationTrackF32").finish_non_exhaustive()
9735    }
9736}
9737
9738impl AnimationTrackF32 {
9739    /// # Panics
9740    /// Panics if the native allocation fails.
9741    pub fn new() -> Self {
9742        // SAFETY: the native constructor returns a live handle; a null here
9743        // means the library is unusable.
9744        unsafe {
9745            let raw = ffi::whiteout_m2_M2AnimationTrackF32_new();
9746            Self::from_raw(raw).expect("native AnimationTrackF32 allocation failed")
9747        }
9748    }
9749
9750    pub fn interpolation_type(&self) -> InterpolationType {
9751        // SAFETY: scalar read; the discriminant is validated below.
9752        unsafe { ffi::whiteout_m2_M2AnimationTrackF32_get_interpolationType(self.raw.as_ptr()) }
9753            .try_into()
9754            .expect("unknown enum discriminant from the native library")
9755    }
9756
9757    pub fn set_interpolation_type(&mut self, value: InterpolationType) {
9758        // SAFETY: scalar write through a live handle.
9759        unsafe {
9760            ffi::whiteout_m2_M2AnimationTrackF32_set_interpolationType(
9761                self.raw.as_ptr(),
9762                value as i32,
9763            )
9764        }
9765    }
9766
9767    pub fn global_sequence_id(&self) -> u16 {
9768        // SAFETY: plain scalar read through a live handle.
9769        unsafe { ffi::whiteout_m2_M2AnimationTrackF32_get_globalSequenceId(self.raw.as_ptr()) }
9770    }
9771
9772    pub fn set_global_sequence_id(&mut self, value: u16) {
9773        // SAFETY: plain scalar write through a live handle.
9774        unsafe {
9775            ffi::whiteout_m2_M2AnimationTrackF32_set_globalSequenceId(self.raw.as_ptr(), value)
9776        }
9777    }
9778
9779    /// Number of inner sequences.
9780    pub fn timestamps_len(&self) -> usize {
9781        // SAFETY: scalar read through a live handle.
9782        unsafe { ffi::whiteout_m2_M2AnimationTrackF32_get_timestamps_count(self.raw.as_ptr()) }
9783    }
9784
9785    /// Zero-copy view of inner sequence `outer`. Empty when out of range.
9786    ///
9787    /// Each inner vector is contiguous on its own, but the outer one
9788    /// is a vector of vectors — so this borrows per sequence rather
9789    /// than handing back one flat slice.
9790    pub fn timestamps(&self, outer: usize) -> &[u32] {
9791        if outer >= self.timestamps_len() {
9792            return &[];
9793        }
9794        // SAFETY: index checked; the pointer borrows `self`.
9795        unsafe {
9796            let n = ffi::whiteout_m2_M2AnimationTrackF32_get_timestamps_inner_count(
9797                self.raw.as_ptr(),
9798                outer,
9799            );
9800            let p = ffi::whiteout_m2_M2AnimationTrackF32_get_timestamps_inner_data(
9801                self.raw.as_ptr(),
9802                outer,
9803            );
9804            if p.is_null() || n == 0 {
9805                &[]
9806            } else {
9807                core::slice::from_raw_parts(p, n)
9808            }
9809        }
9810    }
9811
9812    pub fn timestamps_mut(&mut self, outer: usize) -> &mut [u32] {
9813        if outer >= self.timestamps_len() {
9814            return &mut [];
9815        }
9816        // SAFETY: as above; `&mut self` rules out aliasing.
9817        unsafe {
9818            let n = ffi::whiteout_m2_M2AnimationTrackF32_get_timestamps_inner_count(
9819                self.raw.as_ptr(),
9820                outer,
9821            );
9822            let p = ffi::whiteout_m2_M2AnimationTrackF32_get_timestamps_inner_data(
9823                self.raw.as_ptr(),
9824                outer,
9825            ) as *mut u32;
9826            if p.is_null() || n == 0 {
9827                &mut []
9828            } else {
9829                core::slice::from_raw_parts_mut(p, n)
9830            }
9831        }
9832    }
9833
9834    pub fn set_timestamps(&mut self, outer: usize, values: &[u32]) {
9835        // SAFETY: the native side copies `values` before returning.
9836        unsafe {
9837            ffi::whiteout_m2_M2AnimationTrackF32_assign_timestamps_inner(
9838                self.raw.as_ptr(),
9839                outer,
9840                values.as_ptr() as *const _,
9841                values.len(),
9842            )
9843        }
9844    }
9845
9846    /// Resize the outer sequence. Do this before taking any borrow.
9847    pub fn resize_timestamps(&mut self, count: usize) {
9848        // SAFETY: exclusive access, so no borrow is outstanding.
9849        unsafe { ffi::whiteout_m2_M2AnimationTrackF32_resize_timestamps(self.raw.as_ptr(), count) }
9850    }
9851
9852    pub fn resize_timestamps_inner(&mut self, outer: usize, count: usize) {
9853        // SAFETY: as above.
9854        unsafe {
9855            ffi::whiteout_m2_M2AnimationTrackF32_resize_timestamps_inner(
9856                self.raw.as_ptr(),
9857                outer,
9858                count,
9859            )
9860        }
9861    }
9862
9863    /// Number of inner sequences.
9864    pub fn values_len(&self) -> usize {
9865        // SAFETY: scalar read through a live handle.
9866        unsafe { ffi::whiteout_m2_M2AnimationTrackF32_get_values_count(self.raw.as_ptr()) }
9867    }
9868
9869    /// Zero-copy view of inner sequence `outer`. Empty when out of range.
9870    ///
9871    /// Each inner vector is contiguous on its own, but the outer one
9872    /// is a vector of vectors — so this borrows per sequence rather
9873    /// than handing back one flat slice.
9874    pub fn values(&self, outer: usize) -> &[f32] {
9875        if outer >= self.values_len() {
9876            return &[];
9877        }
9878        // SAFETY: index checked; the pointer borrows `self`.
9879        unsafe {
9880            let n = ffi::whiteout_m2_M2AnimationTrackF32_get_values_inner_count(
9881                self.raw.as_ptr(),
9882                outer,
9883            );
9884            let p = ffi::whiteout_m2_M2AnimationTrackF32_get_values_inner_data(
9885                self.raw.as_ptr(),
9886                outer,
9887            );
9888            if p.is_null() || n == 0 {
9889                &[]
9890            } else {
9891                core::slice::from_raw_parts(p, n)
9892            }
9893        }
9894    }
9895
9896    pub fn values_mut(&mut self, outer: usize) -> &mut [f32] {
9897        if outer >= self.values_len() {
9898            return &mut [];
9899        }
9900        // SAFETY: as above; `&mut self` rules out aliasing.
9901        unsafe {
9902            let n = ffi::whiteout_m2_M2AnimationTrackF32_get_values_inner_count(
9903                self.raw.as_ptr(),
9904                outer,
9905            );
9906            let p = ffi::whiteout_m2_M2AnimationTrackF32_get_values_inner_data(
9907                self.raw.as_ptr(),
9908                outer,
9909            ) as *mut f32;
9910            if p.is_null() || n == 0 {
9911                &mut []
9912            } else {
9913                core::slice::from_raw_parts_mut(p, n)
9914            }
9915        }
9916    }
9917
9918    pub fn set_values(&mut self, outer: usize, values: &[f32]) {
9919        // SAFETY: the native side copies `values` before returning.
9920        unsafe {
9921            ffi::whiteout_m2_M2AnimationTrackF32_assign_values_inner(
9922                self.raw.as_ptr(),
9923                outer,
9924                values.as_ptr() as *const _,
9925                values.len(),
9926            )
9927        }
9928    }
9929
9930    /// Resize the outer sequence. Do this before taking any borrow.
9931    pub fn resize_values(&mut self, count: usize) {
9932        // SAFETY: exclusive access, so no borrow is outstanding.
9933        unsafe { ffi::whiteout_m2_M2AnimationTrackF32_resize_values(self.raw.as_ptr(), count) }
9934    }
9935
9936    pub fn resize_values_inner(&mut self, outer: usize, count: usize) {
9937        // SAFETY: as above.
9938        unsafe {
9939            ffi::whiteout_m2_M2AnimationTrackF32_resize_values_inner(
9940                self.raw.as_ptr(),
9941                outer,
9942                count,
9943            )
9944        }
9945    }
9946}
9947
9948impl Default for AnimationTrackF32 {
9949    fn default() -> Self {
9950        Self::new()
9951    }
9952}
9953
9954pub struct AnimationTrackU8 {
9955    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2AnimationTrackU8>,
9956}
9957
9958impl Drop for AnimationTrackU8 {
9959    fn drop(&mut self) {
9960        // SAFETY: `raw` came from a native constructor and Drop runs once.
9961        unsafe { ffi::whiteout_m2_M2AnimationTrackU8_delete(self.raw.as_ptr()) }
9962    }
9963}
9964
9965impl AnimationTrackU8 {
9966    /// # Safety
9967    /// `raw` must be a live handle this value takes ownership of.
9968    #[allow(dead_code)] // used by whichever methods return this type
9969    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2AnimationTrackU8) -> Option<Self> {
9970        core::ptr::NonNull::new(raw).map(|raw| AnimationTrackU8 { raw })
9971    }
9972}
9973
9974// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
9975// is deliberately NOT implemented — the C++ types make no documented
9976// guarantee about concurrent use, and claiming one we haven't verified
9977// would be unsound. See `@bind thread_safe` in the plan.
9978unsafe impl Send for AnimationTrackU8 {}
9979
9980impl core::fmt::Debug for AnimationTrackU8 {
9981    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
9982        f.debug_struct("AnimationTrackU8").finish_non_exhaustive()
9983    }
9984}
9985
9986impl AnimationTrackU8 {
9987    /// # Panics
9988    /// Panics if the native allocation fails.
9989    pub fn new() -> Self {
9990        // SAFETY: the native constructor returns a live handle; a null here
9991        // means the library is unusable.
9992        unsafe {
9993            let raw = ffi::whiteout_m2_M2AnimationTrackU8_new();
9994            Self::from_raw(raw).expect("native AnimationTrackU8 allocation failed")
9995        }
9996    }
9997
9998    pub fn interpolation_type(&self) -> InterpolationType {
9999        // SAFETY: scalar read; the discriminant is validated below.
10000        unsafe { ffi::whiteout_m2_M2AnimationTrackU8_get_interpolationType(self.raw.as_ptr()) }
10001            .try_into()
10002            .expect("unknown enum discriminant from the native library")
10003    }
10004
10005    pub fn set_interpolation_type(&mut self, value: InterpolationType) {
10006        // SAFETY: scalar write through a live handle.
10007        unsafe {
10008            ffi::whiteout_m2_M2AnimationTrackU8_set_interpolationType(
10009                self.raw.as_ptr(),
10010                value as i32,
10011            )
10012        }
10013    }
10014
10015    pub fn global_sequence_id(&self) -> u16 {
10016        // SAFETY: plain scalar read through a live handle.
10017        unsafe { ffi::whiteout_m2_M2AnimationTrackU8_get_globalSequenceId(self.raw.as_ptr()) }
10018    }
10019
10020    pub fn set_global_sequence_id(&mut self, value: u16) {
10021        // SAFETY: plain scalar write through a live handle.
10022        unsafe {
10023            ffi::whiteout_m2_M2AnimationTrackU8_set_globalSequenceId(self.raw.as_ptr(), value)
10024        }
10025    }
10026
10027    /// Number of inner sequences.
10028    pub fn timestamps_len(&self) -> usize {
10029        // SAFETY: scalar read through a live handle.
10030        unsafe { ffi::whiteout_m2_M2AnimationTrackU8_get_timestamps_count(self.raw.as_ptr()) }
10031    }
10032
10033    /// Zero-copy view of inner sequence `outer`. Empty when out of range.
10034    ///
10035    /// Each inner vector is contiguous on its own, but the outer one
10036    /// is a vector of vectors — so this borrows per sequence rather
10037    /// than handing back one flat slice.
10038    pub fn timestamps(&self, outer: usize) -> &[u32] {
10039        if outer >= self.timestamps_len() {
10040            return &[];
10041        }
10042        // SAFETY: index checked; the pointer borrows `self`.
10043        unsafe {
10044            let n = ffi::whiteout_m2_M2AnimationTrackU8_get_timestamps_inner_count(
10045                self.raw.as_ptr(),
10046                outer,
10047            );
10048            let p = ffi::whiteout_m2_M2AnimationTrackU8_get_timestamps_inner_data(
10049                self.raw.as_ptr(),
10050                outer,
10051            );
10052            if p.is_null() || n == 0 {
10053                &[]
10054            } else {
10055                core::slice::from_raw_parts(p, n)
10056            }
10057        }
10058    }
10059
10060    pub fn timestamps_mut(&mut self, outer: usize) -> &mut [u32] {
10061        if outer >= self.timestamps_len() {
10062            return &mut [];
10063        }
10064        // SAFETY: as above; `&mut self` rules out aliasing.
10065        unsafe {
10066            let n = ffi::whiteout_m2_M2AnimationTrackU8_get_timestamps_inner_count(
10067                self.raw.as_ptr(),
10068                outer,
10069            );
10070            let p = ffi::whiteout_m2_M2AnimationTrackU8_get_timestamps_inner_data(
10071                self.raw.as_ptr(),
10072                outer,
10073            ) as *mut u32;
10074            if p.is_null() || n == 0 {
10075                &mut []
10076            } else {
10077                core::slice::from_raw_parts_mut(p, n)
10078            }
10079        }
10080    }
10081
10082    pub fn set_timestamps(&mut self, outer: usize, values: &[u32]) {
10083        // SAFETY: the native side copies `values` before returning.
10084        unsafe {
10085            ffi::whiteout_m2_M2AnimationTrackU8_assign_timestamps_inner(
10086                self.raw.as_ptr(),
10087                outer,
10088                values.as_ptr() as *const _,
10089                values.len(),
10090            )
10091        }
10092    }
10093
10094    /// Resize the outer sequence. Do this before taking any borrow.
10095    pub fn resize_timestamps(&mut self, count: usize) {
10096        // SAFETY: exclusive access, so no borrow is outstanding.
10097        unsafe { ffi::whiteout_m2_M2AnimationTrackU8_resize_timestamps(self.raw.as_ptr(), count) }
10098    }
10099
10100    pub fn resize_timestamps_inner(&mut self, outer: usize, count: usize) {
10101        // SAFETY: as above.
10102        unsafe {
10103            ffi::whiteout_m2_M2AnimationTrackU8_resize_timestamps_inner(
10104                self.raw.as_ptr(),
10105                outer,
10106                count,
10107            )
10108        }
10109    }
10110
10111    /// Number of inner sequences.
10112    pub fn values_len(&self) -> usize {
10113        // SAFETY: scalar read through a live handle.
10114        unsafe { ffi::whiteout_m2_M2AnimationTrackU8_get_values_count(self.raw.as_ptr()) }
10115    }
10116
10117    /// Zero-copy view of inner sequence `outer`. Empty when out of range.
10118    ///
10119    /// Each inner vector is contiguous on its own, but the outer one
10120    /// is a vector of vectors — so this borrows per sequence rather
10121    /// than handing back one flat slice.
10122    pub fn values(&self, outer: usize) -> &[u8] {
10123        if outer >= self.values_len() {
10124            return &[];
10125        }
10126        // SAFETY: index checked; the pointer borrows `self`.
10127        unsafe {
10128            let n = ffi::whiteout_m2_M2AnimationTrackU8_get_values_inner_count(
10129                self.raw.as_ptr(),
10130                outer,
10131            );
10132            let p =
10133                ffi::whiteout_m2_M2AnimationTrackU8_get_values_inner_data(self.raw.as_ptr(), outer);
10134            if p.is_null() || n == 0 {
10135                &[]
10136            } else {
10137                core::slice::from_raw_parts(p, n)
10138            }
10139        }
10140    }
10141
10142    pub fn values_mut(&mut self, outer: usize) -> &mut [u8] {
10143        if outer >= self.values_len() {
10144            return &mut [];
10145        }
10146        // SAFETY: as above; `&mut self` rules out aliasing.
10147        unsafe {
10148            let n = ffi::whiteout_m2_M2AnimationTrackU8_get_values_inner_count(
10149                self.raw.as_ptr(),
10150                outer,
10151            );
10152            let p =
10153                ffi::whiteout_m2_M2AnimationTrackU8_get_values_inner_data(self.raw.as_ptr(), outer)
10154                    as *mut u8;
10155            if p.is_null() || n == 0 {
10156                &mut []
10157            } else {
10158                core::slice::from_raw_parts_mut(p, n)
10159            }
10160        }
10161    }
10162
10163    pub fn set_values(&mut self, outer: usize, values: &[u8]) {
10164        // SAFETY: the native side copies `values` before returning.
10165        unsafe {
10166            ffi::whiteout_m2_M2AnimationTrackU8_assign_values_inner(
10167                self.raw.as_ptr(),
10168                outer,
10169                values.as_ptr() as *const _,
10170                values.len(),
10171            )
10172        }
10173    }
10174
10175    /// Resize the outer sequence. Do this before taking any borrow.
10176    pub fn resize_values(&mut self, count: usize) {
10177        // SAFETY: exclusive access, so no borrow is outstanding.
10178        unsafe { ffi::whiteout_m2_M2AnimationTrackU8_resize_values(self.raw.as_ptr(), count) }
10179    }
10180
10181    pub fn resize_values_inner(&mut self, outer: usize, count: usize) {
10182        // SAFETY: as above.
10183        unsafe {
10184            ffi::whiteout_m2_M2AnimationTrackU8_resize_values_inner(self.raw.as_ptr(), outer, count)
10185        }
10186    }
10187}
10188
10189impl Default for AnimationTrackU8 {
10190    fn default() -> Self {
10191        Self::new()
10192    }
10193}
10194
10195pub struct AnimationTrackM2CameraSpline {
10196    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2AnimationTrackM2CameraSpline>,
10197}
10198
10199impl Drop for AnimationTrackM2CameraSpline {
10200    fn drop(&mut self) {
10201        // SAFETY: `raw` came from a native constructor and Drop runs once.
10202        unsafe { ffi::whiteout_m2_M2AnimationTrackM2CameraSpline_delete(self.raw.as_ptr()) }
10203    }
10204}
10205
10206impl AnimationTrackM2CameraSpline {
10207    /// # Safety
10208    /// `raw` must be a live handle this value takes ownership of.
10209    #[allow(dead_code)] // used by whichever methods return this type
10210    pub(crate) unsafe fn from_raw(
10211        raw: *mut ffi::whiteout_M2AnimationTrackM2CameraSpline,
10212    ) -> Option<Self> {
10213        core::ptr::NonNull::new(raw).map(|raw| AnimationTrackM2CameraSpline { raw })
10214    }
10215}
10216
10217// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
10218// is deliberately NOT implemented — the C++ types make no documented
10219// guarantee about concurrent use, and claiming one we haven't verified
10220// would be unsound. See `@bind thread_safe` in the plan.
10221unsafe impl Send for AnimationTrackM2CameraSpline {}
10222
10223impl core::fmt::Debug for AnimationTrackM2CameraSpline {
10224    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
10225        f.debug_struct("AnimationTrackM2CameraSpline")
10226            .finish_non_exhaustive()
10227    }
10228}
10229
10230impl AnimationTrackM2CameraSpline {
10231    /// # Panics
10232    /// Panics if the native allocation fails.
10233    pub fn new() -> Self {
10234        // SAFETY: the native constructor returns a live handle; a null here
10235        // means the library is unusable.
10236        unsafe {
10237            let raw = ffi::whiteout_m2_M2AnimationTrackM2CameraSpline_new();
10238            Self::from_raw(raw).expect("native AnimationTrackM2CameraSpline allocation failed")
10239        }
10240    }
10241
10242    pub fn interpolation_type(&self) -> InterpolationType {
10243        // SAFETY: scalar read; the discriminant is validated below.
10244        unsafe {
10245            ffi::whiteout_m2_M2AnimationTrackM2CameraSpline_get_interpolationType(self.raw.as_ptr())
10246        }
10247        .try_into()
10248        .expect("unknown enum discriminant from the native library")
10249    }
10250
10251    pub fn set_interpolation_type(&mut self, value: InterpolationType) {
10252        // SAFETY: scalar write through a live handle.
10253        unsafe {
10254            ffi::whiteout_m2_M2AnimationTrackM2CameraSpline_set_interpolationType(
10255                self.raw.as_ptr(),
10256                value as i32,
10257            )
10258        }
10259    }
10260
10261    pub fn global_sequence_id(&self) -> u16 {
10262        // SAFETY: plain scalar read through a live handle.
10263        unsafe {
10264            ffi::whiteout_m2_M2AnimationTrackM2CameraSpline_get_globalSequenceId(self.raw.as_ptr())
10265        }
10266    }
10267
10268    pub fn set_global_sequence_id(&mut self, value: u16) {
10269        // SAFETY: plain scalar write through a live handle.
10270        unsafe {
10271            ffi::whiteout_m2_M2AnimationTrackM2CameraSpline_set_globalSequenceId(
10272                self.raw.as_ptr(),
10273                value,
10274            )
10275        }
10276    }
10277
10278    /// Number of inner sequences.
10279    pub fn timestamps_len(&self) -> usize {
10280        // SAFETY: scalar read through a live handle.
10281        unsafe {
10282            ffi::whiteout_m2_M2AnimationTrackM2CameraSpline_get_timestamps_count(self.raw.as_ptr())
10283        }
10284    }
10285
10286    /// Zero-copy view of inner sequence `outer`. Empty when out of range.
10287    ///
10288    /// Each inner vector is contiguous on its own, but the outer one
10289    /// is a vector of vectors — so this borrows per sequence rather
10290    /// than handing back one flat slice.
10291    pub fn timestamps(&self, outer: usize) -> &[u32] {
10292        if outer >= self.timestamps_len() {
10293            return &[];
10294        }
10295        // SAFETY: index checked; the pointer borrows `self`.
10296        unsafe {
10297            let n = ffi::whiteout_m2_M2AnimationTrackM2CameraSpline_get_timestamps_inner_count(
10298                self.raw.as_ptr(),
10299                outer,
10300            );
10301            let p = ffi::whiteout_m2_M2AnimationTrackM2CameraSpline_get_timestamps_inner_data(
10302                self.raw.as_ptr(),
10303                outer,
10304            );
10305            if p.is_null() || n == 0 {
10306                &[]
10307            } else {
10308                core::slice::from_raw_parts(p, n)
10309            }
10310        }
10311    }
10312
10313    pub fn timestamps_mut(&mut self, outer: usize) -> &mut [u32] {
10314        if outer >= self.timestamps_len() {
10315            return &mut [];
10316        }
10317        // SAFETY: as above; `&mut self` rules out aliasing.
10318        unsafe {
10319            let n = ffi::whiteout_m2_M2AnimationTrackM2CameraSpline_get_timestamps_inner_count(
10320                self.raw.as_ptr(),
10321                outer,
10322            );
10323            let p = ffi::whiteout_m2_M2AnimationTrackM2CameraSpline_get_timestamps_inner_data(
10324                self.raw.as_ptr(),
10325                outer,
10326            ) as *mut u32;
10327            if p.is_null() || n == 0 {
10328                &mut []
10329            } else {
10330                core::slice::from_raw_parts_mut(p, n)
10331            }
10332        }
10333    }
10334
10335    pub fn set_timestamps(&mut self, outer: usize, values: &[u32]) {
10336        // SAFETY: the native side copies `values` before returning.
10337        unsafe {
10338            ffi::whiteout_m2_M2AnimationTrackM2CameraSpline_assign_timestamps_inner(
10339                self.raw.as_ptr(),
10340                outer,
10341                values.as_ptr() as *const _,
10342                values.len(),
10343            )
10344        }
10345    }
10346
10347    /// Resize the outer sequence. Do this before taking any borrow.
10348    pub fn resize_timestamps(&mut self, count: usize) {
10349        // SAFETY: exclusive access, so no borrow is outstanding.
10350        unsafe {
10351            ffi::whiteout_m2_M2AnimationTrackM2CameraSpline_resize_timestamps(
10352                self.raw.as_ptr(),
10353                count,
10354            )
10355        }
10356    }
10357
10358    pub fn resize_timestamps_inner(&mut self, outer: usize, count: usize) {
10359        // SAFETY: as above.
10360        unsafe {
10361            ffi::whiteout_m2_M2AnimationTrackM2CameraSpline_resize_timestamps_inner(
10362                self.raw.as_ptr(),
10363                outer,
10364                count,
10365            )
10366        }
10367    }
10368
10369    /// Number of inner sequences.
10370    pub fn values_len(&self) -> usize {
10371        // SAFETY: scalar read through a live handle.
10372        unsafe {
10373            ffi::whiteout_m2_M2AnimationTrackM2CameraSpline_get_values_count(self.raw.as_ptr())
10374        }
10375    }
10376
10377    /// Length of inner sequence `outer`.
10378    pub fn values_inner_len(&self, outer: usize) -> usize {
10379        if outer >= self.values_len() {
10380            return 0;
10381        }
10382        // SAFETY: index checked above.
10383        unsafe {
10384            ffi::whiteout_m2_M2AnimationTrackM2CameraSpline_get_values_inner_count(
10385                self.raw.as_ptr(),
10386                outer,
10387            )
10388        }
10389    }
10390
10391    /// Borrow element `inner` of sequence `outer` in place.
10392    pub fn values(
10393        &self,
10394        outer: usize,
10395        inner: usize,
10396    ) -> Option<crate::support::Ref<'_, CameraSpline>> {
10397        if inner >= self.values_inner_len(outer) {
10398            return None;
10399        }
10400        // SAFETY: both indices checked; the pointer is
10401        // interior to `self`.
10402        unsafe {
10403            Some(crate::support::Ref::new(CameraSpline {
10404                raw: core::ptr::NonNull::new_unchecked(
10405                    ffi::whiteout_m2_M2AnimationTrackM2CameraSpline_get_values_at(
10406                        self.raw.as_ptr(),
10407                        outer,
10408                        inner,
10409                    ),
10410                ),
10411            }))
10412        }
10413    }
10414
10415    pub fn values_mut(
10416        &mut self,
10417        outer: usize,
10418        inner: usize,
10419    ) -> Option<crate::support::RefMut<'_, CameraSpline>> {
10420        if inner >= self.values_inner_len(outer) {
10421            return None;
10422        }
10423        // SAFETY: as above; `&mut self` guarantees exclusivity.
10424        unsafe {
10425            Some(crate::support::RefMut::new(CameraSpline {
10426                raw: core::ptr::NonNull::new_unchecked(
10427                    ffi::whiteout_m2_M2AnimationTrackM2CameraSpline_get_values_at(
10428                        self.raw.as_ptr(),
10429                        outer,
10430                        inner,
10431                    ),
10432                ),
10433            }))
10434        }
10435    }
10436
10437    /// Resize the outer sequence. Do this before taking a borrow.
10438    pub fn resize_values(&mut self, count: usize) {
10439        // SAFETY: exclusive access, so no borrow is outstanding.
10440        unsafe {
10441            ffi::whiteout_m2_M2AnimationTrackM2CameraSpline_resize_values(self.raw.as_ptr(), count)
10442        }
10443    }
10444
10445    pub fn resize_values_inner(&mut self, outer: usize, count: usize) {
10446        // SAFETY: as above.
10447        unsafe {
10448            ffi::whiteout_m2_M2AnimationTrackM2CameraSpline_resize_values_inner(
10449                self.raw.as_ptr(),
10450                outer,
10451                count,
10452            )
10453        }
10454    }
10455}
10456
10457impl Default for AnimationTrackM2CameraSpline {
10458    fn default() -> Self {
10459        Self::new()
10460    }
10461}
10462
10463pub struct AnimationTrackU16 {
10464    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2AnimationTrackU16>,
10465}
10466
10467impl Drop for AnimationTrackU16 {
10468    fn drop(&mut self) {
10469        // SAFETY: `raw` came from a native constructor and Drop runs once.
10470        unsafe { ffi::whiteout_m2_M2AnimationTrackU16_delete(self.raw.as_ptr()) }
10471    }
10472}
10473
10474impl AnimationTrackU16 {
10475    /// # Safety
10476    /// `raw` must be a live handle this value takes ownership of.
10477    #[allow(dead_code)] // used by whichever methods return this type
10478    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M2AnimationTrackU16) -> Option<Self> {
10479        core::ptr::NonNull::new(raw).map(|raw| AnimationTrackU16 { raw })
10480    }
10481}
10482
10483// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
10484// is deliberately NOT implemented — the C++ types make no documented
10485// guarantee about concurrent use, and claiming one we haven't verified
10486// would be unsound. See `@bind thread_safe` in the plan.
10487unsafe impl Send for AnimationTrackU16 {}
10488
10489impl core::fmt::Debug for AnimationTrackU16 {
10490    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
10491        f.debug_struct("AnimationTrackU16").finish_non_exhaustive()
10492    }
10493}
10494
10495impl AnimationTrackU16 {
10496    /// # Panics
10497    /// Panics if the native allocation fails.
10498    pub fn new() -> Self {
10499        // SAFETY: the native constructor returns a live handle; a null here
10500        // means the library is unusable.
10501        unsafe {
10502            let raw = ffi::whiteout_m2_M2AnimationTrackU16_new();
10503            Self::from_raw(raw).expect("native AnimationTrackU16 allocation failed")
10504        }
10505    }
10506
10507    pub fn interpolation_type(&self) -> InterpolationType {
10508        // SAFETY: scalar read; the discriminant is validated below.
10509        unsafe { ffi::whiteout_m2_M2AnimationTrackU16_get_interpolationType(self.raw.as_ptr()) }
10510            .try_into()
10511            .expect("unknown enum discriminant from the native library")
10512    }
10513
10514    pub fn set_interpolation_type(&mut self, value: InterpolationType) {
10515        // SAFETY: scalar write through a live handle.
10516        unsafe {
10517            ffi::whiteout_m2_M2AnimationTrackU16_set_interpolationType(
10518                self.raw.as_ptr(),
10519                value as i32,
10520            )
10521        }
10522    }
10523
10524    pub fn global_sequence_id(&self) -> u16 {
10525        // SAFETY: plain scalar read through a live handle.
10526        unsafe { ffi::whiteout_m2_M2AnimationTrackU16_get_globalSequenceId(self.raw.as_ptr()) }
10527    }
10528
10529    pub fn set_global_sequence_id(&mut self, value: u16) {
10530        // SAFETY: plain scalar write through a live handle.
10531        unsafe {
10532            ffi::whiteout_m2_M2AnimationTrackU16_set_globalSequenceId(self.raw.as_ptr(), value)
10533        }
10534    }
10535
10536    /// Number of inner sequences.
10537    pub fn timestamps_len(&self) -> usize {
10538        // SAFETY: scalar read through a live handle.
10539        unsafe { ffi::whiteout_m2_M2AnimationTrackU16_get_timestamps_count(self.raw.as_ptr()) }
10540    }
10541
10542    /// Zero-copy view of inner sequence `outer`. Empty when out of range.
10543    ///
10544    /// Each inner vector is contiguous on its own, but the outer one
10545    /// is a vector of vectors — so this borrows per sequence rather
10546    /// than handing back one flat slice.
10547    pub fn timestamps(&self, outer: usize) -> &[u32] {
10548        if outer >= self.timestamps_len() {
10549            return &[];
10550        }
10551        // SAFETY: index checked; the pointer borrows `self`.
10552        unsafe {
10553            let n = ffi::whiteout_m2_M2AnimationTrackU16_get_timestamps_inner_count(
10554                self.raw.as_ptr(),
10555                outer,
10556            );
10557            let p = ffi::whiteout_m2_M2AnimationTrackU16_get_timestamps_inner_data(
10558                self.raw.as_ptr(),
10559                outer,
10560            );
10561            if p.is_null() || n == 0 {
10562                &[]
10563            } else {
10564                core::slice::from_raw_parts(p, n)
10565            }
10566        }
10567    }
10568
10569    pub fn timestamps_mut(&mut self, outer: usize) -> &mut [u32] {
10570        if outer >= self.timestamps_len() {
10571            return &mut [];
10572        }
10573        // SAFETY: as above; `&mut self` rules out aliasing.
10574        unsafe {
10575            let n = ffi::whiteout_m2_M2AnimationTrackU16_get_timestamps_inner_count(
10576                self.raw.as_ptr(),
10577                outer,
10578            );
10579            let p = ffi::whiteout_m2_M2AnimationTrackU16_get_timestamps_inner_data(
10580                self.raw.as_ptr(),
10581                outer,
10582            ) as *mut u32;
10583            if p.is_null() || n == 0 {
10584                &mut []
10585            } else {
10586                core::slice::from_raw_parts_mut(p, n)
10587            }
10588        }
10589    }
10590
10591    pub fn set_timestamps(&mut self, outer: usize, values: &[u32]) {
10592        // SAFETY: the native side copies `values` before returning.
10593        unsafe {
10594            ffi::whiteout_m2_M2AnimationTrackU16_assign_timestamps_inner(
10595                self.raw.as_ptr(),
10596                outer,
10597                values.as_ptr() as *const _,
10598                values.len(),
10599            )
10600        }
10601    }
10602
10603    /// Resize the outer sequence. Do this before taking any borrow.
10604    pub fn resize_timestamps(&mut self, count: usize) {
10605        // SAFETY: exclusive access, so no borrow is outstanding.
10606        unsafe { ffi::whiteout_m2_M2AnimationTrackU16_resize_timestamps(self.raw.as_ptr(), count) }
10607    }
10608
10609    pub fn resize_timestamps_inner(&mut self, outer: usize, count: usize) {
10610        // SAFETY: as above.
10611        unsafe {
10612            ffi::whiteout_m2_M2AnimationTrackU16_resize_timestamps_inner(
10613                self.raw.as_ptr(),
10614                outer,
10615                count,
10616            )
10617        }
10618    }
10619
10620    /// Number of inner sequences.
10621    pub fn values_len(&self) -> usize {
10622        // SAFETY: scalar read through a live handle.
10623        unsafe { ffi::whiteout_m2_M2AnimationTrackU16_get_values_count(self.raw.as_ptr()) }
10624    }
10625
10626    /// Zero-copy view of inner sequence `outer`. Empty when out of range.
10627    ///
10628    /// Each inner vector is contiguous on its own, but the outer one
10629    /// is a vector of vectors — so this borrows per sequence rather
10630    /// than handing back one flat slice.
10631    pub fn values(&self, outer: usize) -> &[u16] {
10632        if outer >= self.values_len() {
10633            return &[];
10634        }
10635        // SAFETY: index checked; the pointer borrows `self`.
10636        unsafe {
10637            let n = ffi::whiteout_m2_M2AnimationTrackU16_get_values_inner_count(
10638                self.raw.as_ptr(),
10639                outer,
10640            );
10641            let p = ffi::whiteout_m2_M2AnimationTrackU16_get_values_inner_data(
10642                self.raw.as_ptr(),
10643                outer,
10644            );
10645            if p.is_null() || n == 0 {
10646                &[]
10647            } else {
10648                core::slice::from_raw_parts(p, n)
10649            }
10650        }
10651    }
10652
10653    pub fn values_mut(&mut self, outer: usize) -> &mut [u16] {
10654        if outer >= self.values_len() {
10655            return &mut [];
10656        }
10657        // SAFETY: as above; `&mut self` rules out aliasing.
10658        unsafe {
10659            let n = ffi::whiteout_m2_M2AnimationTrackU16_get_values_inner_count(
10660                self.raw.as_ptr(),
10661                outer,
10662            );
10663            let p = ffi::whiteout_m2_M2AnimationTrackU16_get_values_inner_data(
10664                self.raw.as_ptr(),
10665                outer,
10666            ) as *mut u16;
10667            if p.is_null() || n == 0 {
10668                &mut []
10669            } else {
10670                core::slice::from_raw_parts_mut(p, n)
10671            }
10672        }
10673    }
10674
10675    pub fn set_values(&mut self, outer: usize, values: &[u16]) {
10676        // SAFETY: the native side copies `values` before returning.
10677        unsafe {
10678            ffi::whiteout_m2_M2AnimationTrackU16_assign_values_inner(
10679                self.raw.as_ptr(),
10680                outer,
10681                values.as_ptr() as *const _,
10682                values.len(),
10683            )
10684        }
10685    }
10686
10687    /// Resize the outer sequence. Do this before taking any borrow.
10688    pub fn resize_values(&mut self, count: usize) {
10689        // SAFETY: exclusive access, so no borrow is outstanding.
10690        unsafe { ffi::whiteout_m2_M2AnimationTrackU16_resize_values(self.raw.as_ptr(), count) }
10691    }
10692
10693    pub fn resize_values_inner(&mut self, outer: usize, count: usize) {
10694        // SAFETY: as above.
10695        unsafe {
10696            ffi::whiteout_m2_M2AnimationTrackU16_resize_values_inner(
10697                self.raw.as_ptr(),
10698                outer,
10699                count,
10700            )
10701        }
10702    }
10703}
10704
10705impl Default for AnimationTrackU16 {
10706    fn default() -> Self {
10707        Self::new()
10708    }
10709}
10710
10711pub struct ParticleAnimationTrackVector3f {
10712    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2ParticleAnimationTrackVector3f>,
10713}
10714
10715impl Drop for ParticleAnimationTrackVector3f {
10716    fn drop(&mut self) {
10717        // SAFETY: `raw` came from a native constructor and Drop runs once.
10718        unsafe { ffi::whiteout_m2_M2ParticleAnimationTrackVector3f_delete(self.raw.as_ptr()) }
10719    }
10720}
10721
10722impl ParticleAnimationTrackVector3f {
10723    /// # Safety
10724    /// `raw` must be a live handle this value takes ownership of.
10725    #[allow(dead_code)] // used by whichever methods return this type
10726    pub(crate) unsafe fn from_raw(
10727        raw: *mut ffi::whiteout_M2ParticleAnimationTrackVector3f,
10728    ) -> Option<Self> {
10729        core::ptr::NonNull::new(raw).map(|raw| ParticleAnimationTrackVector3f { raw })
10730    }
10731}
10732
10733// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
10734// is deliberately NOT implemented — the C++ types make no documented
10735// guarantee about concurrent use, and claiming one we haven't verified
10736// would be unsound. See `@bind thread_safe` in the plan.
10737unsafe impl Send for ParticleAnimationTrackVector3f {}
10738
10739impl core::fmt::Debug for ParticleAnimationTrackVector3f {
10740    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
10741        f.debug_struct("ParticleAnimationTrackVector3f")
10742            .finish_non_exhaustive()
10743    }
10744}
10745
10746impl ParticleAnimationTrackVector3f {
10747    /// # Panics
10748    /// Panics if the native allocation fails.
10749    pub fn new() -> Self {
10750        // SAFETY: the native constructor returns a live handle; a null here
10751        // means the library is unusable.
10752        unsafe {
10753            let raw = ffi::whiteout_m2_M2ParticleAnimationTrackVector3f_new();
10754            Self::from_raw(raw).expect("native ParticleAnimationTrackVector3f allocation failed")
10755        }
10756    }
10757
10758    /// Zero-copy view of the underlying `std::vector`.
10759    pub fn values(&self) -> &[crate::math::Vector3f] {
10760        // SAFETY: `_data`/`_count` describe one contiguous C++
10761        // allocation, borrowed for as long as `self` is.
10762        unsafe {
10763            let n = ffi::whiteout_m2_M2ParticleAnimationTrackVector3f_get_values_count(
10764                self.raw.as_ptr(),
10765            );
10766            let p = ffi::whiteout_m2_M2ParticleAnimationTrackVector3f_get_values_data(
10767                self.raw.as_ptr(),
10768            ) as *const crate::math::Vector3f;
10769            if p.is_null() || n == 0 {
10770                &[]
10771            } else {
10772                core::slice::from_raw_parts(p, n)
10773            }
10774        }
10775    }
10776
10777    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
10778    pub fn values_mut(&mut self) -> &mut [crate::math::Vector3f] {
10779        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
10780        unsafe {
10781            let n = ffi::whiteout_m2_M2ParticleAnimationTrackVector3f_get_values_count(
10782                self.raw.as_ptr(),
10783            );
10784            let p = ffi::whiteout_m2_M2ParticleAnimationTrackVector3f_get_values_data(
10785                self.raw.as_ptr(),
10786            ) as *const crate::math::Vector3f as *mut crate::math::Vector3f;
10787            if p.is_null() || n == 0 {
10788                &mut []
10789            } else {
10790                core::slice::from_raw_parts_mut(p, n)
10791            }
10792        }
10793    }
10794
10795    pub fn set_values(&mut self, values: &[crate::math::Vector3f]) {
10796        // SAFETY: the native side copies `values` before returning.
10797        unsafe {
10798            ffi::whiteout_m2_M2ParticleAnimationTrackVector3f_assign_values(
10799                self.raw.as_ptr(),
10800                values.as_ptr() as *const _,
10801                values.len(),
10802            )
10803        }
10804    }
10805
10806    pub fn resize_values(&mut self, count: usize) {
10807        // SAFETY: reallocation is safe here precisely because
10808        // `&mut self` means no slice borrow is outstanding.
10809        unsafe {
10810            ffi::whiteout_m2_M2ParticleAnimationTrackVector3f_resize_values(
10811                self.raw.as_ptr(),
10812                count,
10813            )
10814        }
10815    }
10816}
10817
10818impl Default for ParticleAnimationTrackVector3f {
10819    fn default() -> Self {
10820        Self::new()
10821    }
10822}
10823
10824pub struct ParticleAnimationTrackVector2f {
10825    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M2ParticleAnimationTrackVector2f>,
10826}
10827
10828impl Drop for ParticleAnimationTrackVector2f {
10829    fn drop(&mut self) {
10830        // SAFETY: `raw` came from a native constructor and Drop runs once.
10831        unsafe { ffi::whiteout_m2_M2ParticleAnimationTrackVector2f_delete(self.raw.as_ptr()) }
10832    }
10833}
10834
10835impl ParticleAnimationTrackVector2f {
10836    /// # Safety
10837    /// `raw` must be a live handle this value takes ownership of.
10838    #[allow(dead_code)] // used by whichever methods return this type
10839    pub(crate) unsafe fn from_raw(
10840        raw: *mut ffi::whiteout_M2ParticleAnimationTrackVector2f,
10841    ) -> Option<Self> {
10842        core::ptr::NonNull::new(raw).map(|raw| ParticleAnimationTrackVector2f { raw })
10843    }
10844}
10845
10846// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
10847// is deliberately NOT implemented — the C++ types make no documented
10848// guarantee about concurrent use, and claiming one we haven't verified
10849// would be unsound. See `@bind thread_safe` in the plan.
10850unsafe impl Send for ParticleAnimationTrackVector2f {}
10851
10852impl core::fmt::Debug for ParticleAnimationTrackVector2f {
10853    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
10854        f.debug_struct("ParticleAnimationTrackVector2f")
10855            .finish_non_exhaustive()
10856    }
10857}
10858
10859impl ParticleAnimationTrackVector2f {
10860    /// # Panics
10861    /// Panics if the native allocation fails.
10862    pub fn new() -> Self {
10863        // SAFETY: the native constructor returns a live handle; a null here
10864        // means the library is unusable.
10865        unsafe {
10866            let raw = ffi::whiteout_m2_M2ParticleAnimationTrackVector2f_new();
10867            Self::from_raw(raw).expect("native ParticleAnimationTrackVector2f allocation failed")
10868        }
10869    }
10870
10871    /// Zero-copy view of the underlying `std::vector`.
10872    pub fn values(&self) -> &[crate::math::Vector2f] {
10873        // SAFETY: `_data`/`_count` describe one contiguous C++
10874        // allocation, borrowed for as long as `self` is.
10875        unsafe {
10876            let n = ffi::whiteout_m2_M2ParticleAnimationTrackVector2f_get_values_count(
10877                self.raw.as_ptr(),
10878            );
10879            let p = ffi::whiteout_m2_M2ParticleAnimationTrackVector2f_get_values_data(
10880                self.raw.as_ptr(),
10881            ) as *const crate::math::Vector2f;
10882            if p.is_null() || n == 0 {
10883                &[]
10884            } else {
10885                core::slice::from_raw_parts(p, n)
10886            }
10887        }
10888    }
10889
10890    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
10891    pub fn values_mut(&mut self) -> &mut [crate::math::Vector2f] {
10892        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
10893        unsafe {
10894            let n = ffi::whiteout_m2_M2ParticleAnimationTrackVector2f_get_values_count(
10895                self.raw.as_ptr(),
10896            );
10897            let p = ffi::whiteout_m2_M2ParticleAnimationTrackVector2f_get_values_data(
10898                self.raw.as_ptr(),
10899            ) as *const crate::math::Vector2f as *mut crate::math::Vector2f;
10900            if p.is_null() || n == 0 {
10901                &mut []
10902            } else {
10903                core::slice::from_raw_parts_mut(p, n)
10904            }
10905        }
10906    }
10907
10908    pub fn set_values(&mut self, values: &[crate::math::Vector2f]) {
10909        // SAFETY: the native side copies `values` before returning.
10910        unsafe {
10911            ffi::whiteout_m2_M2ParticleAnimationTrackVector2f_assign_values(
10912                self.raw.as_ptr(),
10913                values.as_ptr() as *const _,
10914                values.len(),
10915            )
10916        }
10917    }
10918
10919    pub fn resize_values(&mut self, count: usize) {
10920        // SAFETY: reallocation is safe here precisely because
10921        // `&mut self` means no slice borrow is outstanding.
10922        unsafe {
10923            ffi::whiteout_m2_M2ParticleAnimationTrackVector2f_resize_values(
10924                self.raw.as_ptr(),
10925                count,
10926            )
10927        }
10928    }
10929}
10930
10931impl Default for ParticleAnimationTrackVector2f {
10932    fn default() -> Self {
10933        Self::new()
10934    }
10935}
10936
10937#[doc(hidden)]
10938pub mod ffi {
10939    #![allow(missing_debug_implementations)]
10940
10941    #[allow(unused_imports)]
10942    use crate::support::{RawBytes, RawCString};
10943
10944    #[repr(C)]
10945    pub struct whiteout_M2CompatQuaternion {
10946        _private: [u8; 0],
10947    }
10948    #[repr(C)]
10949    pub struct whiteout_M2ColorBGRA {
10950        _private: [u8; 0],
10951    }
10952    #[repr(C)]
10953    pub struct whiteout_M2Extent {
10954        _private: [u8; 0],
10955    }
10956    #[repr(C)]
10957    pub struct whiteout_M2AnimationTrackBase {
10958        _private: [u8; 0],
10959    }
10960    #[repr(C)]
10961    pub struct whiteout_M2ParticleEmitterExtension {
10962        _private: [u8; 0],
10963    }
10964    #[repr(C)]
10965    pub struct whiteout_M2LodProfile {
10966        _private: [u8; 0],
10967    }
10968    #[repr(C)]
10969    pub struct whiteout_M2WaterfallData {
10970        _private: [u8; 0],
10971    }
10972    #[repr(C)]
10973    pub struct whiteout_M2ParticleGeosetData {
10974        _private: [u8; 0],
10975    }
10976    #[repr(C)]
10977    pub struct whiteout_M2EdgeFadeData {
10978        _private: [u8; 0],
10979    }
10980    #[repr(C)]
10981    pub struct whiteout_M2DistanceFadeData {
10982        _private: [u8; 0],
10983    }
10984    #[repr(C)]
10985    pub struct whiteout_M2DetailedLightData {
10986        _private: [u8; 0],
10987    }
10988    #[repr(C)]
10989    pub struct whiteout_M2DebugOcclusionData {
10990        _private: [u8; 0],
10991    }
10992    #[repr(C)]
10993    pub struct whiteout_M2TexturedLightData {
10994        _private: [u8; 0],
10995    }
10996    #[repr(C)]
10997    pub struct whiteout_M2PhysicsCollision {
10998        _private: [u8; 0],
10999    }
11000    #[repr(C)]
11001    pub struct whiteout_M2SkinSection {
11002        _private: [u8; 0],
11003    }
11004    #[repr(C)]
11005    pub struct whiteout_M2Batch {
11006        _private: [u8; 0],
11007    }
11008    #[repr(C)]
11009    pub struct whiteout_M2ShadowBatch {
11010        _private: [u8; 0],
11011    }
11012    #[repr(C)]
11013    pub struct whiteout_M2SkinProfile {
11014        _private: [u8; 0],
11015    }
11016    #[repr(C)]
11017    pub struct whiteout_M2GlobalFlags {
11018        _private: [u8; 0],
11019    }
11020    #[repr(C)]
11021    pub struct whiteout_M2GlobalSequence {
11022        _private: [u8; 0],
11023    }
11024    #[repr(C)]
11025    pub struct whiteout_M2Sequence {
11026        _private: [u8; 0],
11027    }
11028    #[repr(C)]
11029    pub struct whiteout_M2Vertex {
11030        _private: [u8; 0],
11031    }
11032    #[repr(C)]
11033    pub struct whiteout_M2Bone {
11034        _private: [u8; 0],
11035    }
11036    #[repr(C)]
11037    pub struct whiteout_M2Texture {
11038        _private: [u8; 0],
11039    }
11040    #[repr(C)]
11041    pub struct whiteout_M2Material {
11042        _private: [u8; 0],
11043    }
11044    #[repr(C)]
11045    pub struct whiteout_M2TextureWeight {
11046        _private: [u8; 0],
11047    }
11048    #[repr(C)]
11049    pub struct whiteout_M2TextureTransform {
11050        _private: [u8; 0],
11051    }
11052    #[repr(C)]
11053    pub struct whiteout_M2ColorAnimation {
11054        _private: [u8; 0],
11055    }
11056    #[repr(C)]
11057    pub struct whiteout_M2Light {
11058        _private: [u8; 0],
11059    }
11060    #[repr(C)]
11061    pub struct whiteout_M2CameraSpline {
11062        _private: [u8; 0],
11063    }
11064    #[repr(C)]
11065    pub struct whiteout_M2Camera {
11066        _private: [u8; 0],
11067    }
11068    #[repr(C)]
11069    pub struct whiteout_M2Attachment {
11070        _private: [u8; 0],
11071    }
11072    #[repr(C)]
11073    pub struct whiteout_M2RibbonEmitter {
11074        _private: [u8; 0],
11075    }
11076    #[repr(C)]
11077    pub struct whiteout_M2Box {
11078        _private: [u8; 0],
11079    }
11080    #[repr(C)]
11081    pub struct whiteout_M2ParticleEmitter {
11082        _private: [u8; 0],
11083    }
11084    #[repr(C)]
11085    pub struct whiteout_M2Event {
11086        _private: [u8; 0],
11087    }
11088    #[repr(C)]
11089    pub struct whiteout_M2Model {
11090        _private: [u8; 0],
11091    }
11092    #[repr(C)]
11093    pub struct whiteout_M2Parser {
11094        _private: [u8; 0],
11095    }
11096    #[repr(C)]
11097    pub struct whiteout_M2WriteOptions {
11098        _private: [u8; 0],
11099    }
11100    #[repr(C)]
11101    pub struct whiteout_M2SerializeResult {
11102        _private: [u8; 0],
11103    }
11104    #[repr(C)]
11105    pub struct whiteout_M2Writer {
11106        _private: [u8; 0],
11107    }
11108    #[repr(C)]
11109    pub struct whiteout_M2AnimationTrackVector3f {
11110        _private: [u8; 0],
11111    }
11112    #[repr(C)]
11113    pub struct whiteout_M2AnimationTrackM2CompatQuaternion {
11114        _private: [u8; 0],
11115    }
11116    #[repr(C)]
11117    pub struct whiteout_M2AnimationTrackI16 {
11118        _private: [u8; 0],
11119    }
11120    #[repr(C)]
11121    pub struct whiteout_M2AnimationTrackF32 {
11122        _private: [u8; 0],
11123    }
11124    #[repr(C)]
11125    pub struct whiteout_M2AnimationTrackU8 {
11126        _private: [u8; 0],
11127    }
11128    #[repr(C)]
11129    pub struct whiteout_M2AnimationTrackM2CameraSpline {
11130        _private: [u8; 0],
11131    }
11132    #[repr(C)]
11133    pub struct whiteout_M2AnimationTrackU16 {
11134        _private: [u8; 0],
11135    }
11136    #[repr(C)]
11137    pub struct whiteout_M2ParticleAnimationTrackVector3f {
11138        _private: [u8; 0],
11139    }
11140    #[repr(C)]
11141    pub struct whiteout_M2ParticleAnimationTrackVector2f {
11142        _private: [u8; 0],
11143    }
11144
11145    extern "C" {
11146        // CompatQuaternion
11147        pub fn whiteout_m2_M2CompatQuaternion_new() -> *mut whiteout_M2CompatQuaternion;
11148        pub fn whiteout_m2_M2CompatQuaternion_delete(self_: *mut whiteout_M2CompatQuaternion);
11149        // ColorBGRA
11150        pub fn whiteout_m2_M2ColorBGRA_new() -> *mut whiteout_M2ColorBGRA;
11151        pub fn whiteout_m2_M2ColorBGRA_delete(self_: *mut whiteout_M2ColorBGRA);
11152        // Extent
11153        pub fn whiteout_m2_M2Extent_new() -> *mut whiteout_M2Extent;
11154        pub fn whiteout_m2_M2Extent_delete(self_: *mut whiteout_M2Extent);
11155        pub fn whiteout_m2_M2Extent_get_minimum(
11156            self_: *mut whiteout_M2Extent,
11157        ) -> *mut core::ffi::c_void;
11158        pub fn whiteout_m2_M2Extent_set_minimum(
11159            self_: *mut whiteout_M2Extent,
11160            value: *const core::ffi::c_void,
11161        );
11162        pub fn whiteout_m2_M2Extent_get_maximum(
11163            self_: *mut whiteout_M2Extent,
11164        ) -> *mut core::ffi::c_void;
11165        pub fn whiteout_m2_M2Extent_set_maximum(
11166            self_: *mut whiteout_M2Extent,
11167            value: *const core::ffi::c_void,
11168        );
11169        pub fn whiteout_m2_M2Extent_get_sphereRadius(self_: *mut whiteout_M2Extent) -> f32;
11170        pub fn whiteout_m2_M2Extent_set_sphereRadius(self_: *mut whiteout_M2Extent, value: f32);
11171        // AnimationTrackBase
11172        pub fn whiteout_m2_M2AnimationTrackBase_new() -> *mut whiteout_M2AnimationTrackBase;
11173        pub fn whiteout_m2_M2AnimationTrackBase_delete(self_: *mut whiteout_M2AnimationTrackBase);
11174        pub fn whiteout_m2_M2AnimationTrackBase_get_interpolationType(
11175            self_: *mut whiteout_M2AnimationTrackBase,
11176        ) -> i32;
11177        pub fn whiteout_m2_M2AnimationTrackBase_set_interpolationType(
11178            self_: *mut whiteout_M2AnimationTrackBase,
11179            value: i32,
11180        );
11181        pub fn whiteout_m2_M2AnimationTrackBase_get_globalSequenceId(
11182            self_: *mut whiteout_M2AnimationTrackBase,
11183        ) -> u16;
11184        pub fn whiteout_m2_M2AnimationTrackBase_set_globalSequenceId(
11185            self_: *mut whiteout_M2AnimationTrackBase,
11186            value: u16,
11187        );
11188        pub fn whiteout_m2_M2AnimationTrackBase_get_timestamps_count(
11189            self_: *mut whiteout_M2AnimationTrackBase,
11190        ) -> usize;
11191        pub fn whiteout_m2_M2AnimationTrackBase_get_timestamps_inner_count(
11192            self_: *mut whiteout_M2AnimationTrackBase,
11193            outer: usize,
11194        ) -> usize;
11195        pub fn whiteout_m2_M2AnimationTrackBase_resize_timestamps(
11196            self_: *mut whiteout_M2AnimationTrackBase,
11197            count: usize,
11198        );
11199        pub fn whiteout_m2_M2AnimationTrackBase_resize_timestamps_inner(
11200            self_: *mut whiteout_M2AnimationTrackBase,
11201            outer: usize,
11202            count: usize,
11203        );
11204        pub fn whiteout_m2_M2AnimationTrackBase_get_timestamps_inner_data(
11205            self_: *mut whiteout_M2AnimationTrackBase,
11206            outer: usize,
11207        ) -> *const u32;
11208        pub fn whiteout_m2_M2AnimationTrackBase_assign_timestamps_inner(
11209            self_: *mut whiteout_M2AnimationTrackBase,
11210            outer: usize,
11211            data: *const u32,
11212            count: usize,
11213        );
11214        // ParticleEmitterExtension
11215        pub fn whiteout_m2_M2ParticleEmitterExtension_new(
11216        ) -> *mut whiteout_M2ParticleEmitterExtension;
11217        pub fn whiteout_m2_M2ParticleEmitterExtension_delete(
11218            self_: *mut whiteout_M2ParticleEmitterExtension,
11219        );
11220        pub fn whiteout_m2_M2ParticleEmitterExtension_get_zSource(
11221            self_: *mut whiteout_M2ParticleEmitterExtension,
11222        ) -> f32;
11223        pub fn whiteout_m2_M2ParticleEmitterExtension_set_zSource(
11224            self_: *mut whiteout_M2ParticleEmitterExtension,
11225            value: f32,
11226        );
11227        pub fn whiteout_m2_M2ParticleEmitterExtension_get_colorMult(
11228            self_: *mut whiteout_M2ParticleEmitterExtension,
11229        ) -> f32;
11230        pub fn whiteout_m2_M2ParticleEmitterExtension_set_colorMult(
11231            self_: *mut whiteout_M2ParticleEmitterExtension,
11232            value: f32,
11233        );
11234        pub fn whiteout_m2_M2ParticleEmitterExtension_get_alphaMult(
11235            self_: *mut whiteout_M2ParticleEmitterExtension,
11236        ) -> f32;
11237        pub fn whiteout_m2_M2ParticleEmitterExtension_set_alphaMult(
11238            self_: *mut whiteout_M2ParticleEmitterExtension,
11239            value: f32,
11240        );
11241        // LodProfile
11242        pub fn whiteout_m2_M2LodProfile_new() -> *mut whiteout_M2LodProfile;
11243        pub fn whiteout_m2_M2LodProfile_delete(self_: *mut whiteout_M2LodProfile);
11244        pub fn whiteout_m2_M2LodProfile_get_flags(self_: *mut whiteout_M2LodProfile) -> u16;
11245        pub fn whiteout_m2_M2LodProfile_set_flags(self_: *mut whiteout_M2LodProfile, value: u16);
11246        pub fn whiteout_m2_M2LodProfile_get_numLodLevels(self_: *mut whiteout_M2LodProfile) -> u16;
11247        pub fn whiteout_m2_M2LodProfile_set_numLodLevels(
11248            self_: *mut whiteout_M2LodProfile,
11249            value: u16,
11250        );
11251        pub fn whiteout_m2_M2LodProfile_get_lodDistance(self_: *mut whiteout_M2LodProfile) -> f32;
11252        pub fn whiteout_m2_M2LodProfile_set_lodDistance(
11253            self_: *mut whiteout_M2LodProfile,
11254            value: f32,
11255        );
11256        pub fn whiteout_m2_M2LodProfile_particleBoneLod_size() -> usize;
11257        pub fn whiteout_m2_M2LodProfile_get_particleBoneLod_at(
11258            self_: *mut whiteout_M2LodProfile,
11259            index: usize,
11260        ) -> u8;
11261        pub fn whiteout_m2_M2LodProfile_set_particleBoneLod_at(
11262            self_: *mut whiteout_M2LodProfile,
11263            index: usize,
11264            value: u8,
11265        );
11266        pub fn whiteout_m2_M2LodProfile_get_reserved0(self_: *mut whiteout_M2LodProfile) -> u8;
11267        pub fn whiteout_m2_M2LodProfile_set_reserved0(self_: *mut whiteout_M2LodProfile, value: u8);
11268        pub fn whiteout_m2_M2LodProfile_get_lodFlags(self_: *mut whiteout_M2LodProfile) -> u8;
11269        pub fn whiteout_m2_M2LodProfile_set_lodFlags(self_: *mut whiteout_M2LodProfile, value: u8);
11270        pub fn whiteout_m2_M2LodProfile_get_lodBatchCount(self_: *mut whiteout_M2LodProfile) -> u8;
11271        pub fn whiteout_m2_M2LodProfile_set_lodBatchCount(
11272            self_: *mut whiteout_M2LodProfile,
11273            value: u8,
11274        );
11275        pub fn whiteout_m2_M2LodProfile_get_reserved1(self_: *mut whiteout_M2LodProfile) -> u8;
11276        pub fn whiteout_m2_M2LodProfile_set_reserved1(self_: *mut whiteout_M2LodProfile, value: u8);
11277        // WaterfallData
11278        pub fn whiteout_m2_M2WaterfallData_new() -> *mut whiteout_M2WaterfallData;
11279        pub fn whiteout_m2_M2WaterfallData_delete(self_: *mut whiteout_M2WaterfallData);
11280        pub fn whiteout_m2_M2WaterfallData_get_bumpScale(
11281            self_: *mut whiteout_M2WaterfallData,
11282        ) -> f32;
11283        pub fn whiteout_m2_M2WaterfallData_set_bumpScale(
11284            self_: *mut whiteout_M2WaterfallData,
11285            value: f32,
11286        );
11287        pub fn whiteout_m2_M2WaterfallData_get_value0_x(
11288            self_: *mut whiteout_M2WaterfallData,
11289        ) -> f32;
11290        pub fn whiteout_m2_M2WaterfallData_set_value0_x(
11291            self_: *mut whiteout_M2WaterfallData,
11292            value: f32,
11293        );
11294        pub fn whiteout_m2_M2WaterfallData_get_value0_y(
11295            self_: *mut whiteout_M2WaterfallData,
11296        ) -> f32;
11297        pub fn whiteout_m2_M2WaterfallData_set_value0_y(
11298            self_: *mut whiteout_M2WaterfallData,
11299            value: f32,
11300        );
11301        pub fn whiteout_m2_M2WaterfallData_get_value0_z(
11302            self_: *mut whiteout_M2WaterfallData,
11303        ) -> f32;
11304        pub fn whiteout_m2_M2WaterfallData_set_value0_z(
11305            self_: *mut whiteout_M2WaterfallData,
11306            value: f32,
11307        );
11308        pub fn whiteout_m2_M2WaterfallData_get_value1_w(
11309            self_: *mut whiteout_M2WaterfallData,
11310        ) -> f32;
11311        pub fn whiteout_m2_M2WaterfallData_set_value1_w(
11312            self_: *mut whiteout_M2WaterfallData,
11313            value: f32,
11314        );
11315        pub fn whiteout_m2_M2WaterfallData_get_value0_w(
11316            self_: *mut whiteout_M2WaterfallData,
11317        ) -> f32;
11318        pub fn whiteout_m2_M2WaterfallData_set_value0_w(
11319            self_: *mut whiteout_M2WaterfallData,
11320            value: f32,
11321        );
11322        pub fn whiteout_m2_M2WaterfallData_get_value1_x(
11323            self_: *mut whiteout_M2WaterfallData,
11324        ) -> f32;
11325        pub fn whiteout_m2_M2WaterfallData_set_value1_x(
11326            self_: *mut whiteout_M2WaterfallData,
11327            value: f32,
11328        );
11329        pub fn whiteout_m2_M2WaterfallData_get_value1_y(
11330            self_: *mut whiteout_M2WaterfallData,
11331        ) -> f32;
11332        pub fn whiteout_m2_M2WaterfallData_set_value1_y(
11333            self_: *mut whiteout_M2WaterfallData,
11334            value: f32,
11335        );
11336        pub fn whiteout_m2_M2WaterfallData_get_value2_w(
11337            self_: *mut whiteout_M2WaterfallData,
11338        ) -> f32;
11339        pub fn whiteout_m2_M2WaterfallData_set_value2_w(
11340            self_: *mut whiteout_M2WaterfallData,
11341            value: f32,
11342        );
11343        pub fn whiteout_m2_M2WaterfallData_get_value3_y(
11344            self_: *mut whiteout_M2WaterfallData,
11345        ) -> f32;
11346        pub fn whiteout_m2_M2WaterfallData_set_value3_y(
11347            self_: *mut whiteout_M2WaterfallData,
11348            value: f32,
11349        );
11350        pub fn whiteout_m2_M2WaterfallData_get_value3_x(
11351            self_: *mut whiteout_M2WaterfallData,
11352        ) -> f32;
11353        pub fn whiteout_m2_M2WaterfallData_set_value3_x(
11354            self_: *mut whiteout_M2WaterfallData,
11355            value: f32,
11356        );
11357        pub fn whiteout_m2_M2WaterfallData_get_baseColor(
11358            self_: *mut whiteout_M2WaterfallData,
11359        ) -> *mut core::ffi::c_void;
11360        pub fn whiteout_m2_M2WaterfallData_set_baseColor(
11361            self_: *mut whiteout_M2WaterfallData,
11362            value: *const core::ffi::c_void,
11363        );
11364        pub fn whiteout_m2_M2WaterfallData_get_flags(self_: *mut whiteout_M2WaterfallData) -> u16;
11365        pub fn whiteout_m2_M2WaterfallData_set_flags(
11366            self_: *mut whiteout_M2WaterfallData,
11367            value: u16,
11368        );
11369        pub fn whiteout_m2_M2WaterfallData_get_unknown0(
11370            self_: *mut whiteout_M2WaterfallData,
11371        ) -> u16;
11372        pub fn whiteout_m2_M2WaterfallData_set_unknown0(
11373            self_: *mut whiteout_M2WaterfallData,
11374            value: u16,
11375        );
11376        pub fn whiteout_m2_M2WaterfallData_get_value3_w(
11377            self_: *mut whiteout_M2WaterfallData,
11378        ) -> f32;
11379        pub fn whiteout_m2_M2WaterfallData_set_value3_w(
11380            self_: *mut whiteout_M2WaterfallData,
11381            value: f32,
11382        );
11383        pub fn whiteout_m2_M2WaterfallData_get_value3_z(
11384            self_: *mut whiteout_M2WaterfallData,
11385        ) -> f32;
11386        pub fn whiteout_m2_M2WaterfallData_set_value3_z(
11387            self_: *mut whiteout_M2WaterfallData,
11388            value: f32,
11389        );
11390        pub fn whiteout_m2_M2WaterfallData_get_value4_y(
11391            self_: *mut whiteout_M2WaterfallData,
11392        ) -> f32;
11393        pub fn whiteout_m2_M2WaterfallData_set_value4_y(
11394            self_: *mut whiteout_M2WaterfallData,
11395            value: f32,
11396        );
11397        pub fn whiteout_m2_M2WaterfallData_get_unknown1(
11398            self_: *mut whiteout_M2WaterfallData,
11399        ) -> f32;
11400        pub fn whiteout_m2_M2WaterfallData_set_unknown1(
11401            self_: *mut whiteout_M2WaterfallData,
11402            value: f32,
11403        );
11404        pub fn whiteout_m2_M2WaterfallData_get_unknown2(
11405            self_: *mut whiteout_M2WaterfallData,
11406        ) -> f32;
11407        pub fn whiteout_m2_M2WaterfallData_set_unknown2(
11408            self_: *mut whiteout_M2WaterfallData,
11409            value: f32,
11410        );
11411        pub fn whiteout_m2_M2WaterfallData_get_unknown3(
11412            self_: *mut whiteout_M2WaterfallData,
11413        ) -> f32;
11414        pub fn whiteout_m2_M2WaterfallData_set_unknown3(
11415            self_: *mut whiteout_M2WaterfallData,
11416            value: f32,
11417        );
11418        pub fn whiteout_m2_M2WaterfallData_get_unknown4(
11419            self_: *mut whiteout_M2WaterfallData,
11420        ) -> f32;
11421        pub fn whiteout_m2_M2WaterfallData_set_unknown4(
11422            self_: *mut whiteout_M2WaterfallData,
11423            value: f32,
11424        );
11425        // ParticleGeosetData
11426        pub fn whiteout_m2_M2ParticleGeosetData_new() -> *mut whiteout_M2ParticleGeosetData;
11427        pub fn whiteout_m2_M2ParticleGeosetData_delete(self_: *mut whiteout_M2ParticleGeosetData);
11428        pub fn whiteout_m2_M2ParticleGeosetData_get_geoset(
11429            self_: *mut whiteout_M2ParticleGeosetData,
11430        ) -> u16;
11431        pub fn whiteout_m2_M2ParticleGeosetData_set_geoset(
11432            self_: *mut whiteout_M2ParticleGeosetData,
11433            value: u16,
11434        );
11435        // EdgeFadeData
11436        pub fn whiteout_m2_M2EdgeFadeData_new() -> *mut whiteout_M2EdgeFadeData;
11437        pub fn whiteout_m2_M2EdgeFadeData_delete(self_: *mut whiteout_M2EdgeFadeData);
11438        pub fn whiteout_m2_M2EdgeFadeData_value0_size() -> usize;
11439        pub fn whiteout_m2_M2EdgeFadeData_get_value0_at(
11440            self_: *mut whiteout_M2EdgeFadeData,
11441            index: usize,
11442        ) -> f32;
11443        pub fn whiteout_m2_M2EdgeFadeData_set_value0_at(
11444            self_: *mut whiteout_M2EdgeFadeData,
11445            index: usize,
11446            value: f32,
11447        );
11448        pub fn whiteout_m2_M2EdgeFadeData_get_value8(self_: *mut whiteout_M2EdgeFadeData) -> f32;
11449        pub fn whiteout_m2_M2EdgeFadeData_set_value8(
11450            self_: *mut whiteout_M2EdgeFadeData,
11451            value: f32,
11452        );
11453        pub fn whiteout_m2_M2EdgeFadeData_valueC_size() -> usize;
11454        pub fn whiteout_m2_M2EdgeFadeData_get_valueC_at(
11455            self_: *mut whiteout_M2EdgeFadeData,
11456            index: usize,
11457        ) -> u8;
11458        pub fn whiteout_m2_M2EdgeFadeData_set_valueC_at(
11459            self_: *mut whiteout_M2EdgeFadeData,
11460            index: usize,
11461            value: u8,
11462        );
11463        // DistanceFadeData
11464        pub fn whiteout_m2_M2DistanceFadeData_new() -> *mut whiteout_M2DistanceFadeData;
11465        pub fn whiteout_m2_M2DistanceFadeData_delete(self_: *mut whiteout_M2DistanceFadeData);
11466        pub fn whiteout_m2_M2DistanceFadeData_get_squaredFarDist(
11467            self_: *mut whiteout_M2DistanceFadeData,
11468        ) -> f32;
11469        pub fn whiteout_m2_M2DistanceFadeData_set_squaredFarDist(
11470            self_: *mut whiteout_M2DistanceFadeData,
11471            value: f32,
11472        );
11473        pub fn whiteout_m2_M2DistanceFadeData_get_squaredNearDist(
11474            self_: *mut whiteout_M2DistanceFadeData,
11475        ) -> f32;
11476        pub fn whiteout_m2_M2DistanceFadeData_set_squaredNearDist(
11477            self_: *mut whiteout_M2DistanceFadeData,
11478            value: f32,
11479        );
11480        pub fn whiteout_m2_M2DistanceFadeData_reserved_size() -> usize;
11481        pub fn whiteout_m2_M2DistanceFadeData_get_reserved_at(
11482            self_: *mut whiteout_M2DistanceFadeData,
11483            index: usize,
11484        ) -> u32;
11485        pub fn whiteout_m2_M2DistanceFadeData_set_reserved_at(
11486            self_: *mut whiteout_M2DistanceFadeData,
11487            index: usize,
11488            value: u32,
11489        );
11490        // DetailedLightData
11491        pub fn whiteout_m2_M2DetailedLightData_new() -> *mut whiteout_M2DetailedLightData;
11492        pub fn whiteout_m2_M2DetailedLightData_delete(self_: *mut whiteout_M2DetailedLightData);
11493        pub fn whiteout_m2_M2DetailedLightData_get_flags(
11494            self_: *mut whiteout_M2DetailedLightData,
11495        ) -> u16;
11496        pub fn whiteout_m2_M2DetailedLightData_set_flags(
11497            self_: *mut whiteout_M2DetailedLightData,
11498            value: u16,
11499        );
11500        pub fn whiteout_m2_M2DetailedLightData_get_unknown0(
11501            self_: *mut whiteout_M2DetailedLightData,
11502        ) -> u16;
11503        pub fn whiteout_m2_M2DetailedLightData_set_unknown0(
11504            self_: *mut whiteout_M2DetailedLightData,
11505            value: u16,
11506        );
11507        pub fn whiteout_m2_M2DetailedLightData_get_unknown1(
11508            self_: *mut whiteout_M2DetailedLightData,
11509        ) -> u32;
11510        pub fn whiteout_m2_M2DetailedLightData_set_unknown1(
11511            self_: *mut whiteout_M2DetailedLightData,
11512            value: u32,
11513        );
11514        // DebugOcclusionData
11515        pub fn whiteout_m2_M2DebugOcclusionData_new() -> *mut whiteout_M2DebugOcclusionData;
11516        pub fn whiteout_m2_M2DebugOcclusionData_delete(self_: *mut whiteout_M2DebugOcclusionData);
11517        pub fn whiteout_m2_M2DebugOcclusionData_get_unknown1_1(
11518            self_: *mut whiteout_M2DebugOcclusionData,
11519        ) -> f32;
11520        pub fn whiteout_m2_M2DebugOcclusionData_set_unknown1_1(
11521            self_: *mut whiteout_M2DebugOcclusionData,
11522            value: f32,
11523        );
11524        pub fn whiteout_m2_M2DebugOcclusionData_get_unknown1_2(
11525            self_: *mut whiteout_M2DebugOcclusionData,
11526        ) -> f32;
11527        pub fn whiteout_m2_M2DebugOcclusionData_set_unknown1_2(
11528            self_: *mut whiteout_M2DebugOcclusionData,
11529            value: f32,
11530        );
11531        pub fn whiteout_m2_M2DebugOcclusionData_get_unknown1_3(
11532            self_: *mut whiteout_M2DebugOcclusionData,
11533        ) -> u32;
11534        pub fn whiteout_m2_M2DebugOcclusionData_set_unknown1_3(
11535            self_: *mut whiteout_M2DebugOcclusionData,
11536            value: u32,
11537        );
11538        pub fn whiteout_m2_M2DebugOcclusionData_get_unknown1_4(
11539            self_: *mut whiteout_M2DebugOcclusionData,
11540        ) -> u32;
11541        pub fn whiteout_m2_M2DebugOcclusionData_set_unknown1_4(
11542            self_: *mut whiteout_M2DebugOcclusionData,
11543            value: u32,
11544        );
11545        // TexturedLightData
11546        pub fn whiteout_m2_M2TexturedLightData_new() -> *mut whiteout_M2TexturedLightData;
11547        pub fn whiteout_m2_M2TexturedLightData_delete(self_: *mut whiteout_M2TexturedLightData);
11548        pub fn whiteout_m2_M2TexturedLightData_get_unknown0(
11549            self_: *mut whiteout_M2TexturedLightData,
11550        ) -> f32;
11551        pub fn whiteout_m2_M2TexturedLightData_set_unknown0(
11552            self_: *mut whiteout_M2TexturedLightData,
11553            value: f32,
11554        );
11555        pub fn whiteout_m2_M2TexturedLightData_get_unknown1(
11556            self_: *mut whiteout_M2TexturedLightData,
11557        ) -> f32;
11558        pub fn whiteout_m2_M2TexturedLightData_set_unknown1(
11559            self_: *mut whiteout_M2TexturedLightData,
11560            value: f32,
11561        );
11562        pub fn whiteout_m2_M2TexturedLightData_get_textureLookup(
11563            self_: *mut whiteout_M2TexturedLightData,
11564        ) -> i32;
11565        pub fn whiteout_m2_M2TexturedLightData_set_textureLookup(
11566            self_: *mut whiteout_M2TexturedLightData,
11567            value: i32,
11568        );
11569        pub fn whiteout_m2_M2TexturedLightData_get_unknown2(
11570            self_: *mut whiteout_M2TexturedLightData,
11571        ) -> i32;
11572        pub fn whiteout_m2_M2TexturedLightData_set_unknown2(
11573            self_: *mut whiteout_M2TexturedLightData,
11574            value: i32,
11575        );
11576        // PhysicsCollision
11577        pub fn whiteout_m2_M2PhysicsCollision_new() -> *mut whiteout_M2PhysicsCollision;
11578        pub fn whiteout_m2_M2PhysicsCollision_delete(self_: *mut whiteout_M2PhysicsCollision);
11579        pub fn whiteout_m2_M2PhysicsCollision_get_vertexPositions_count(
11580            self_: *mut whiteout_M2PhysicsCollision,
11581        ) -> usize;
11582        pub fn whiteout_m2_M2PhysicsCollision_resize_vertexPositions(
11583            self_: *mut whiteout_M2PhysicsCollision,
11584            count: usize,
11585        );
11586        pub fn whiteout_m2_M2PhysicsCollision_get_vertexPositions_data(
11587            self_: *mut whiteout_M2PhysicsCollision,
11588        ) -> *const f32;
11589        pub fn whiteout_m2_M2PhysicsCollision_assign_vertexPositions(
11590            self_: *mut whiteout_M2PhysicsCollision,
11591            data: *const f32,
11592            count: usize,
11593        );
11594        pub fn whiteout_m2_M2PhysicsCollision_get_faceNormals_count(
11595            self_: *mut whiteout_M2PhysicsCollision,
11596        ) -> usize;
11597        pub fn whiteout_m2_M2PhysicsCollision_resize_faceNormals(
11598            self_: *mut whiteout_M2PhysicsCollision,
11599            count: usize,
11600        );
11601        pub fn whiteout_m2_M2PhysicsCollision_get_faceNormals_data(
11602            self_: *mut whiteout_M2PhysicsCollision,
11603        ) -> *const f32;
11604        pub fn whiteout_m2_M2PhysicsCollision_assign_faceNormals(
11605            self_: *mut whiteout_M2PhysicsCollision,
11606            data: *const f32,
11607            count: usize,
11608        );
11609        pub fn whiteout_m2_M2PhysicsCollision_get_indices_count(
11610            self_: *mut whiteout_M2PhysicsCollision,
11611        ) -> usize;
11612        pub fn whiteout_m2_M2PhysicsCollision_resize_indices(
11613            self_: *mut whiteout_M2PhysicsCollision,
11614            count: usize,
11615        );
11616        pub fn whiteout_m2_M2PhysicsCollision_get_indices_data(
11617            self_: *mut whiteout_M2PhysicsCollision,
11618        ) -> *const i16;
11619        pub fn whiteout_m2_M2PhysicsCollision_assign_indices(
11620            self_: *mut whiteout_M2PhysicsCollision,
11621            data: *const i16,
11622            count: usize,
11623        );
11624        pub fn whiteout_m2_M2PhysicsCollision_get_flags_count(
11625            self_: *mut whiteout_M2PhysicsCollision,
11626        ) -> usize;
11627        pub fn whiteout_m2_M2PhysicsCollision_resize_flags(
11628            self_: *mut whiteout_M2PhysicsCollision,
11629            count: usize,
11630        );
11631        pub fn whiteout_m2_M2PhysicsCollision_get_flags_data(
11632            self_: *mut whiteout_M2PhysicsCollision,
11633        ) -> *const i16;
11634        pub fn whiteout_m2_M2PhysicsCollision_assign_flags(
11635            self_: *mut whiteout_M2PhysicsCollision,
11636            data: *const i16,
11637            count: usize,
11638        );
11639        // SkinSection
11640        pub fn whiteout_m2_M2SkinSection_new() -> *mut whiteout_M2SkinSection;
11641        pub fn whiteout_m2_M2SkinSection_delete(self_: *mut whiteout_M2SkinSection);
11642        pub fn whiteout_m2_M2SkinSection_get_skinSectionId(
11643            self_: *mut whiteout_M2SkinSection,
11644        ) -> u16;
11645        pub fn whiteout_m2_M2SkinSection_set_skinSectionId(
11646            self_: *mut whiteout_M2SkinSection,
11647            value: u16,
11648        );
11649        pub fn whiteout_m2_M2SkinSection_get_level(self_: *mut whiteout_M2SkinSection) -> u16;
11650        pub fn whiteout_m2_M2SkinSection_set_level(self_: *mut whiteout_M2SkinSection, value: u16);
11651        pub fn whiteout_m2_M2SkinSection_get_vertexStart(self_: *mut whiteout_M2SkinSection)
11652            -> u16;
11653        pub fn whiteout_m2_M2SkinSection_set_vertexStart(
11654            self_: *mut whiteout_M2SkinSection,
11655            value: u16,
11656        );
11657        pub fn whiteout_m2_M2SkinSection_get_vertexCount(self_: *mut whiteout_M2SkinSection)
11658            -> u16;
11659        pub fn whiteout_m2_M2SkinSection_set_vertexCount(
11660            self_: *mut whiteout_M2SkinSection,
11661            value: u16,
11662        );
11663        pub fn whiteout_m2_M2SkinSection_get_indexStart(self_: *mut whiteout_M2SkinSection) -> u16;
11664        pub fn whiteout_m2_M2SkinSection_set_indexStart(
11665            self_: *mut whiteout_M2SkinSection,
11666            value: u16,
11667        );
11668        pub fn whiteout_m2_M2SkinSection_get_indexCount(self_: *mut whiteout_M2SkinSection) -> u16;
11669        pub fn whiteout_m2_M2SkinSection_set_indexCount(
11670            self_: *mut whiteout_M2SkinSection,
11671            value: u16,
11672        );
11673        pub fn whiteout_m2_M2SkinSection_get_boneCount(self_: *mut whiteout_M2SkinSection) -> u16;
11674        pub fn whiteout_m2_M2SkinSection_set_boneCount(
11675            self_: *mut whiteout_M2SkinSection,
11676            value: u16,
11677        );
11678        pub fn whiteout_m2_M2SkinSection_get_boneComboIndex(
11679            self_: *mut whiteout_M2SkinSection,
11680        ) -> u16;
11681        pub fn whiteout_m2_M2SkinSection_set_boneComboIndex(
11682            self_: *mut whiteout_M2SkinSection,
11683            value: u16,
11684        );
11685        pub fn whiteout_m2_M2SkinSection_get_boneInfluences(
11686            self_: *mut whiteout_M2SkinSection,
11687        ) -> u16;
11688        pub fn whiteout_m2_M2SkinSection_set_boneInfluences(
11689            self_: *mut whiteout_M2SkinSection,
11690            value: u16,
11691        );
11692        pub fn whiteout_m2_M2SkinSection_get_centerBoneIndex(
11693            self_: *mut whiteout_M2SkinSection,
11694        ) -> u16;
11695        pub fn whiteout_m2_M2SkinSection_set_centerBoneIndex(
11696            self_: *mut whiteout_M2SkinSection,
11697            value: u16,
11698        );
11699        pub fn whiteout_m2_M2SkinSection_get_centerPosition(
11700            self_: *mut whiteout_M2SkinSection,
11701        ) -> *mut core::ffi::c_void;
11702        pub fn whiteout_m2_M2SkinSection_set_centerPosition(
11703            self_: *mut whiteout_M2SkinSection,
11704            value: *const core::ffi::c_void,
11705        );
11706        pub fn whiteout_m2_M2SkinSection_get_sortCenterPosition(
11707            self_: *mut whiteout_M2SkinSection,
11708        ) -> *mut core::ffi::c_void;
11709        pub fn whiteout_m2_M2SkinSection_set_sortCenterPosition(
11710            self_: *mut whiteout_M2SkinSection,
11711            value: *const core::ffi::c_void,
11712        );
11713        pub fn whiteout_m2_M2SkinSection_get_sortRadius(self_: *mut whiteout_M2SkinSection) -> f32;
11714        pub fn whiteout_m2_M2SkinSection_set_sortRadius(
11715            self_: *mut whiteout_M2SkinSection,
11716            value: f32,
11717        );
11718        // Batch
11719        pub fn whiteout_m2_M2Batch_new() -> *mut whiteout_M2Batch;
11720        pub fn whiteout_m2_M2Batch_delete(self_: *mut whiteout_M2Batch);
11721        pub fn whiteout_m2_M2Batch_get_flags(self_: *mut whiteout_M2Batch) -> u8;
11722        pub fn whiteout_m2_M2Batch_set_flags(self_: *mut whiteout_M2Batch, value: u8);
11723        pub fn whiteout_m2_M2Batch_get_priorityPlane(self_: *mut whiteout_M2Batch) -> i8;
11724        pub fn whiteout_m2_M2Batch_set_priorityPlane(self_: *mut whiteout_M2Batch, value: i8);
11725        pub fn whiteout_m2_M2Batch_get_shaderId(self_: *mut whiteout_M2Batch) -> u16;
11726        pub fn whiteout_m2_M2Batch_set_shaderId(self_: *mut whiteout_M2Batch, value: u16);
11727        pub fn whiteout_m2_M2Batch_get_skinSectionIndex(self_: *mut whiteout_M2Batch) -> u16;
11728        pub fn whiteout_m2_M2Batch_set_skinSectionIndex(self_: *mut whiteout_M2Batch, value: u16);
11729        pub fn whiteout_m2_M2Batch_get_geosetIndex(self_: *mut whiteout_M2Batch) -> u16;
11730        pub fn whiteout_m2_M2Batch_set_geosetIndex(self_: *mut whiteout_M2Batch, value: u16);
11731        pub fn whiteout_m2_M2Batch_get_colorIndex(self_: *mut whiteout_M2Batch) -> i16;
11732        pub fn whiteout_m2_M2Batch_set_colorIndex(self_: *mut whiteout_M2Batch, value: i16);
11733        pub fn whiteout_m2_M2Batch_get_materialIndex(self_: *mut whiteout_M2Batch) -> u16;
11734        pub fn whiteout_m2_M2Batch_set_materialIndex(self_: *mut whiteout_M2Batch, value: u16);
11735        pub fn whiteout_m2_M2Batch_get_materialLayer(self_: *mut whiteout_M2Batch) -> u16;
11736        pub fn whiteout_m2_M2Batch_set_materialLayer(self_: *mut whiteout_M2Batch, value: u16);
11737        pub fn whiteout_m2_M2Batch_get_textureCount(self_: *mut whiteout_M2Batch) -> u16;
11738        pub fn whiteout_m2_M2Batch_set_textureCount(self_: *mut whiteout_M2Batch, value: u16);
11739        pub fn whiteout_m2_M2Batch_get_textureComboIndex(self_: *mut whiteout_M2Batch) -> u16;
11740        pub fn whiteout_m2_M2Batch_set_textureComboIndex(self_: *mut whiteout_M2Batch, value: u16);
11741        pub fn whiteout_m2_M2Batch_get_textureCoordComboIndex(self_: *mut whiteout_M2Batch) -> u16;
11742        pub fn whiteout_m2_M2Batch_set_textureCoordComboIndex(
11743            self_: *mut whiteout_M2Batch,
11744            value: u16,
11745        );
11746        pub fn whiteout_m2_M2Batch_get_textureWeightComboIndex(self_: *mut whiteout_M2Batch)
11747            -> u16;
11748        pub fn whiteout_m2_M2Batch_set_textureWeightComboIndex(
11749            self_: *mut whiteout_M2Batch,
11750            value: u16,
11751        );
11752        pub fn whiteout_m2_M2Batch_get_textureTransformComboIndex(
11753            self_: *mut whiteout_M2Batch,
11754        ) -> u16;
11755        pub fn whiteout_m2_M2Batch_set_textureTransformComboIndex(
11756            self_: *mut whiteout_M2Batch,
11757            value: u16,
11758        );
11759        // ShadowBatch
11760        pub fn whiteout_m2_M2ShadowBatch_new() -> *mut whiteout_M2ShadowBatch;
11761        pub fn whiteout_m2_M2ShadowBatch_delete(self_: *mut whiteout_M2ShadowBatch);
11762        pub fn whiteout_m2_M2ShadowBatch_get_flags(self_: *mut whiteout_M2ShadowBatch) -> u8;
11763        pub fn whiteout_m2_M2ShadowBatch_set_flags(self_: *mut whiteout_M2ShadowBatch, value: u8);
11764        pub fn whiteout_m2_M2ShadowBatch_get_flags2(self_: *mut whiteout_M2ShadowBatch) -> u8;
11765        pub fn whiteout_m2_M2ShadowBatch_set_flags2(self_: *mut whiteout_M2ShadowBatch, value: u8);
11766        pub fn whiteout_m2_M2ShadowBatch_get_unknown0(self_: *mut whiteout_M2ShadowBatch) -> u16;
11767        pub fn whiteout_m2_M2ShadowBatch_set_unknown0(
11768            self_: *mut whiteout_M2ShadowBatch,
11769            value: u16,
11770        );
11771        pub fn whiteout_m2_M2ShadowBatch_get_submeshId(self_: *mut whiteout_M2ShadowBatch) -> u16;
11772        pub fn whiteout_m2_M2ShadowBatch_set_submeshId(
11773            self_: *mut whiteout_M2ShadowBatch,
11774            value: u16,
11775        );
11776        pub fn whiteout_m2_M2ShadowBatch_get_textureId(self_: *mut whiteout_M2ShadowBatch) -> u16;
11777        pub fn whiteout_m2_M2ShadowBatch_set_textureId(
11778            self_: *mut whiteout_M2ShadowBatch,
11779            value: u16,
11780        );
11781        pub fn whiteout_m2_M2ShadowBatch_get_colorId(self_: *mut whiteout_M2ShadowBatch) -> u16;
11782        pub fn whiteout_m2_M2ShadowBatch_set_colorId(
11783            self_: *mut whiteout_M2ShadowBatch,
11784            value: u16,
11785        );
11786        pub fn whiteout_m2_M2ShadowBatch_get_transparencyId(
11787            self_: *mut whiteout_M2ShadowBatch,
11788        ) -> u16;
11789        pub fn whiteout_m2_M2ShadowBatch_set_transparencyId(
11790            self_: *mut whiteout_M2ShadowBatch,
11791            value: u16,
11792        );
11793        // SkinProfile
11794        pub fn whiteout_m2_M2SkinProfile_new() -> *mut whiteout_M2SkinProfile;
11795        pub fn whiteout_m2_M2SkinProfile_delete(self_: *mut whiteout_M2SkinProfile);
11796        pub fn whiteout_m2_M2SkinProfile_get_vertices_count(
11797            self_: *mut whiteout_M2SkinProfile,
11798        ) -> usize;
11799        pub fn whiteout_m2_M2SkinProfile_resize_vertices(
11800            self_: *mut whiteout_M2SkinProfile,
11801            count: usize,
11802        );
11803        pub fn whiteout_m2_M2SkinProfile_get_vertices_data(
11804            self_: *mut whiteout_M2SkinProfile,
11805        ) -> *const u16;
11806        pub fn whiteout_m2_M2SkinProfile_assign_vertices(
11807            self_: *mut whiteout_M2SkinProfile,
11808            data: *const u16,
11809            count: usize,
11810        );
11811        pub fn whiteout_m2_M2SkinProfile_get_indices_count(
11812            self_: *mut whiteout_M2SkinProfile,
11813        ) -> usize;
11814        pub fn whiteout_m2_M2SkinProfile_resize_indices(
11815            self_: *mut whiteout_M2SkinProfile,
11816            count: usize,
11817        );
11818        pub fn whiteout_m2_M2SkinProfile_get_indices_data(
11819            self_: *mut whiteout_M2SkinProfile,
11820        ) -> *const u16;
11821        pub fn whiteout_m2_M2SkinProfile_assign_indices(
11822            self_: *mut whiteout_M2SkinProfile,
11823            data: *const u16,
11824            count: usize,
11825        );
11826        pub fn whiteout_m2_M2SkinProfile_get_submeshes_count(
11827            self_: *mut whiteout_M2SkinProfile,
11828        ) -> usize;
11829        pub fn whiteout_m2_M2SkinProfile_resize_submeshes(
11830            self_: *mut whiteout_M2SkinProfile,
11831            count: usize,
11832        );
11833        pub fn whiteout_m2_M2SkinProfile_get_submeshes_at(
11834            self_: *mut whiteout_M2SkinProfile,
11835            index: usize,
11836        ) -> *mut whiteout_M2SkinSection;
11837        pub fn whiteout_m2_M2SkinProfile_get_batches_count(
11838            self_: *mut whiteout_M2SkinProfile,
11839        ) -> usize;
11840        pub fn whiteout_m2_M2SkinProfile_resize_batches(
11841            self_: *mut whiteout_M2SkinProfile,
11842            count: usize,
11843        );
11844        pub fn whiteout_m2_M2SkinProfile_get_batches_at(
11845            self_: *mut whiteout_M2SkinProfile,
11846            index: usize,
11847        ) -> *mut whiteout_M2Batch;
11848        pub fn whiteout_m2_M2SkinProfile_get_lodVertexBase(
11849            self_: *mut whiteout_M2SkinProfile,
11850        ) -> u32;
11851        pub fn whiteout_m2_M2SkinProfile_set_lodVertexBase(
11852            self_: *mut whiteout_M2SkinProfile,
11853            value: u32,
11854        );
11855        pub fn whiteout_m2_M2SkinProfile_get_shadowBatches_count(
11856            self_: *mut whiteout_M2SkinProfile,
11857        ) -> usize;
11858        pub fn whiteout_m2_M2SkinProfile_resize_shadowBatches(
11859            self_: *mut whiteout_M2SkinProfile,
11860            count: usize,
11861        );
11862        pub fn whiteout_m2_M2SkinProfile_get_shadowBatches_at(
11863            self_: *mut whiteout_M2SkinProfile,
11864            index: usize,
11865        ) -> *mut whiteout_M2ShadowBatch;
11866        // GlobalFlags
11867        pub fn whiteout_m2_M2GlobalFlags_new() -> *mut whiteout_M2GlobalFlags;
11868        pub fn whiteout_m2_M2GlobalFlags_delete(self_: *mut whiteout_M2GlobalFlags);
11869        pub fn whiteout_m2_M2GlobalFlags_get_value(self_: *mut whiteout_M2GlobalFlags) -> i32;
11870        pub fn whiteout_m2_M2GlobalFlags_set_value(self_: *mut whiteout_M2GlobalFlags, value: i32);
11871        // GlobalSequence
11872        pub fn whiteout_m2_M2GlobalSequence_new() -> *mut whiteout_M2GlobalSequence;
11873        pub fn whiteout_m2_M2GlobalSequence_delete(self_: *mut whiteout_M2GlobalSequence);
11874        pub fn whiteout_m2_M2GlobalSequence_get_timestamp(
11875            self_: *mut whiteout_M2GlobalSequence,
11876        ) -> u32;
11877        pub fn whiteout_m2_M2GlobalSequence_set_timestamp(
11878            self_: *mut whiteout_M2GlobalSequence,
11879            value: u32,
11880        );
11881        // Sequence
11882        pub fn whiteout_m2_M2Sequence_new() -> *mut whiteout_M2Sequence;
11883        pub fn whiteout_m2_M2Sequence_delete(self_: *mut whiteout_M2Sequence);
11884        pub fn whiteout_m2_M2Sequence_get_id(self_: *mut whiteout_M2Sequence) -> u16;
11885        pub fn whiteout_m2_M2Sequence_set_id(self_: *mut whiteout_M2Sequence, value: u16);
11886        pub fn whiteout_m2_M2Sequence_get_variationIndex(self_: *mut whiteout_M2Sequence) -> u16;
11887        pub fn whiteout_m2_M2Sequence_set_variationIndex(
11888            self_: *mut whiteout_M2Sequence,
11889            value: u16,
11890        );
11891        pub fn whiteout_m2_M2Sequence_get_duration(self_: *mut whiteout_M2Sequence) -> u32;
11892        pub fn whiteout_m2_M2Sequence_set_duration(self_: *mut whiteout_M2Sequence, value: u32);
11893        pub fn whiteout_m2_M2Sequence_get_movespeed(self_: *mut whiteout_M2Sequence) -> f32;
11894        pub fn whiteout_m2_M2Sequence_set_movespeed(self_: *mut whiteout_M2Sequence, value: f32);
11895        pub fn whiteout_m2_M2Sequence_get_flags(self_: *mut whiteout_M2Sequence) -> i32;
11896        pub fn whiteout_m2_M2Sequence_set_flags(self_: *mut whiteout_M2Sequence, value: i32);
11897        pub fn whiteout_m2_M2Sequence_get_frequency(self_: *mut whiteout_M2Sequence) -> i16;
11898        pub fn whiteout_m2_M2Sequence_set_frequency(self_: *mut whiteout_M2Sequence, value: i16);
11899        pub fn whiteout_m2_M2Sequence_get_padding(self_: *mut whiteout_M2Sequence) -> u16;
11900        pub fn whiteout_m2_M2Sequence_set_padding(self_: *mut whiteout_M2Sequence, value: u16);
11901        pub fn whiteout_m2_M2Sequence_get_replayMin(self_: *mut whiteout_M2Sequence) -> u32;
11902        pub fn whiteout_m2_M2Sequence_set_replayMin(self_: *mut whiteout_M2Sequence, value: u32);
11903        pub fn whiteout_m2_M2Sequence_get_replayMax(self_: *mut whiteout_M2Sequence) -> u32;
11904        pub fn whiteout_m2_M2Sequence_set_replayMax(self_: *mut whiteout_M2Sequence, value: u32);
11905        pub fn whiteout_m2_M2Sequence_get_blendTimeIn(self_: *mut whiteout_M2Sequence) -> u16;
11906        pub fn whiteout_m2_M2Sequence_set_blendTimeIn(self_: *mut whiteout_M2Sequence, value: u16);
11907        pub fn whiteout_m2_M2Sequence_get_blendTimeOut(self_: *mut whiteout_M2Sequence) -> u16;
11908        pub fn whiteout_m2_M2Sequence_set_blendTimeOut(self_: *mut whiteout_M2Sequence, value: u16);
11909        pub fn whiteout_m2_M2Sequence_get_bounding(
11910            self_: *mut whiteout_M2Sequence,
11911        ) -> *mut whiteout_M2Extent;
11912        pub fn whiteout_m2_M2Sequence_set_bounding(
11913            self_: *mut whiteout_M2Sequence,
11914            value: *const whiteout_M2Extent,
11915        );
11916        pub fn whiteout_m2_M2Sequence_get_variationNext(self_: *mut whiteout_M2Sequence) -> i16;
11917        pub fn whiteout_m2_M2Sequence_set_variationNext(
11918            self_: *mut whiteout_M2Sequence,
11919            value: i16,
11920        );
11921        pub fn whiteout_m2_M2Sequence_get_aliasNext(self_: *mut whiteout_M2Sequence) -> u16;
11922        pub fn whiteout_m2_M2Sequence_set_aliasNext(self_: *mut whiteout_M2Sequence, value: u16);
11923        // Vertex
11924        pub fn whiteout_m2_M2Vertex_new() -> *mut whiteout_M2Vertex;
11925        pub fn whiteout_m2_M2Vertex_delete(self_: *mut whiteout_M2Vertex);
11926        pub fn whiteout_m2_M2Vertex_get_position(
11927            self_: *mut whiteout_M2Vertex,
11928        ) -> *mut core::ffi::c_void;
11929        pub fn whiteout_m2_M2Vertex_set_position(
11930            self_: *mut whiteout_M2Vertex,
11931            value: *const core::ffi::c_void,
11932        );
11933        pub fn whiteout_m2_M2Vertex_boneWeights_size() -> usize;
11934        pub fn whiteout_m2_M2Vertex_get_boneWeights_at(
11935            self_: *mut whiteout_M2Vertex,
11936            index: usize,
11937        ) -> u8;
11938        pub fn whiteout_m2_M2Vertex_set_boneWeights_at(
11939            self_: *mut whiteout_M2Vertex,
11940            index: usize,
11941            value: u8,
11942        );
11943        pub fn whiteout_m2_M2Vertex_boneIndices_size() -> usize;
11944        pub fn whiteout_m2_M2Vertex_get_boneIndices_at(
11945            self_: *mut whiteout_M2Vertex,
11946            index: usize,
11947        ) -> u8;
11948        pub fn whiteout_m2_M2Vertex_set_boneIndices_at(
11949            self_: *mut whiteout_M2Vertex,
11950            index: usize,
11951            value: u8,
11952        );
11953        pub fn whiteout_m2_M2Vertex_get_normal(
11954            self_: *mut whiteout_M2Vertex,
11955        ) -> *mut core::ffi::c_void;
11956        pub fn whiteout_m2_M2Vertex_set_normal(
11957            self_: *mut whiteout_M2Vertex,
11958            value: *const core::ffi::c_void,
11959        );
11960        pub fn whiteout_m2_M2Vertex_texCoords_size() -> usize;
11961        pub fn whiteout_m2_M2Vertex_get_texCoords_at(
11962            self_: *mut whiteout_M2Vertex,
11963            index: usize,
11964        ) -> *mut core::ffi::c_void;
11965        // Bone
11966        pub fn whiteout_m2_M2Bone_new() -> *mut whiteout_M2Bone;
11967        pub fn whiteout_m2_M2Bone_delete(self_: *mut whiteout_M2Bone);
11968        pub fn whiteout_m2_M2Bone_get_keyBoneId(self_: *mut whiteout_M2Bone) -> i32;
11969        pub fn whiteout_m2_M2Bone_set_keyBoneId(self_: *mut whiteout_M2Bone, value: i32);
11970        pub fn whiteout_m2_M2Bone_get_flags(self_: *mut whiteout_M2Bone) -> u32;
11971        pub fn whiteout_m2_M2Bone_set_flags(self_: *mut whiteout_M2Bone, value: u32);
11972        pub fn whiteout_m2_M2Bone_get_parentBoneId(self_: *mut whiteout_M2Bone) -> i16;
11973        pub fn whiteout_m2_M2Bone_set_parentBoneId(self_: *mut whiteout_M2Bone, value: i16);
11974        pub fn whiteout_m2_M2Bone_get_submeshId(self_: *mut whiteout_M2Bone) -> u16;
11975        pub fn whiteout_m2_M2Bone_set_submeshId(self_: *mut whiteout_M2Bone, value: u16);
11976        pub fn whiteout_m2_M2Bone_get_boneNameCRC(self_: *mut whiteout_M2Bone) -> u32;
11977        pub fn whiteout_m2_M2Bone_set_boneNameCRC(self_: *mut whiteout_M2Bone, value: u32);
11978        pub fn whiteout_m2_M2Bone_get_translation(
11979            self_: *mut whiteout_M2Bone,
11980        ) -> *mut whiteout_M2AnimationTrackVector3f;
11981        pub fn whiteout_m2_M2Bone_set_translation(
11982            self_: *mut whiteout_M2Bone,
11983            value: *const whiteout_M2AnimationTrackVector3f,
11984        );
11985        pub fn whiteout_m2_M2Bone_get_rotation(
11986            self_: *mut whiteout_M2Bone,
11987        ) -> *mut whiteout_M2AnimationTrackM2CompatQuaternion;
11988        pub fn whiteout_m2_M2Bone_set_rotation(
11989            self_: *mut whiteout_M2Bone,
11990            value: *const whiteout_M2AnimationTrackM2CompatQuaternion,
11991        );
11992        pub fn whiteout_m2_M2Bone_get_scale(
11993            self_: *mut whiteout_M2Bone,
11994        ) -> *mut whiteout_M2AnimationTrackVector3f;
11995        pub fn whiteout_m2_M2Bone_set_scale(
11996            self_: *mut whiteout_M2Bone,
11997            value: *const whiteout_M2AnimationTrackVector3f,
11998        );
11999        pub fn whiteout_m2_M2Bone_get_pivot(self_: *mut whiteout_M2Bone) -> *mut core::ffi::c_void;
12000        pub fn whiteout_m2_M2Bone_set_pivot(
12001            self_: *mut whiteout_M2Bone,
12002            value: *const core::ffi::c_void,
12003        );
12004        // Texture
12005        pub fn whiteout_m2_M2Texture_new() -> *mut whiteout_M2Texture;
12006        pub fn whiteout_m2_M2Texture_delete(self_: *mut whiteout_M2Texture);
12007        pub fn whiteout_m2_M2Texture_get_type(self_: *mut whiteout_M2Texture) -> u32;
12008        pub fn whiteout_m2_M2Texture_set_type(self_: *mut whiteout_M2Texture, value: u32);
12009        pub fn whiteout_m2_M2Texture_get_flags(self_: *mut whiteout_M2Texture) -> u32;
12010        pub fn whiteout_m2_M2Texture_set_flags(self_: *mut whiteout_M2Texture, value: u32);
12011        pub fn whiteout_m2_M2Texture_get_filename(self_: *mut whiteout_M2Texture) -> RawCString;
12012        pub fn whiteout_m2_M2Texture_set_filename(
12013            self_: *mut whiteout_M2Texture,
12014            value: *const core::ffi::c_char,
12015        );
12016        // Material
12017        pub fn whiteout_m2_M2Material_new() -> *mut whiteout_M2Material;
12018        pub fn whiteout_m2_M2Material_delete(self_: *mut whiteout_M2Material);
12019        pub fn whiteout_m2_M2Material_get_flags(self_: *mut whiteout_M2Material) -> u16;
12020        pub fn whiteout_m2_M2Material_set_flags(self_: *mut whiteout_M2Material, value: u16);
12021        pub fn whiteout_m2_M2Material_get_blendingMode(self_: *mut whiteout_M2Material) -> u16;
12022        pub fn whiteout_m2_M2Material_set_blendingMode(self_: *mut whiteout_M2Material, value: u16);
12023        // TextureWeight
12024        pub fn whiteout_m2_M2TextureWeight_new() -> *mut whiteout_M2TextureWeight;
12025        pub fn whiteout_m2_M2TextureWeight_delete(self_: *mut whiteout_M2TextureWeight);
12026        pub fn whiteout_m2_M2TextureWeight_get_weight(
12027            self_: *mut whiteout_M2TextureWeight,
12028        ) -> *mut whiteout_M2AnimationTrackI16;
12029        pub fn whiteout_m2_M2TextureWeight_set_weight(
12030            self_: *mut whiteout_M2TextureWeight,
12031            value: *const whiteout_M2AnimationTrackI16,
12032        );
12033        // TextureTransform
12034        pub fn whiteout_m2_M2TextureTransform_new() -> *mut whiteout_M2TextureTransform;
12035        pub fn whiteout_m2_M2TextureTransform_delete(self_: *mut whiteout_M2TextureTransform);
12036        pub fn whiteout_m2_M2TextureTransform_get_translation(
12037            self_: *mut whiteout_M2TextureTransform,
12038        ) -> *mut whiteout_M2AnimationTrackVector3f;
12039        pub fn whiteout_m2_M2TextureTransform_set_translation(
12040            self_: *mut whiteout_M2TextureTransform,
12041            value: *const whiteout_M2AnimationTrackVector3f,
12042        );
12043        pub fn whiteout_m2_M2TextureTransform_get_rotation(
12044            self_: *mut whiteout_M2TextureTransform,
12045        ) -> *mut whiteout_M2AnimationTrackM2CompatQuaternion;
12046        pub fn whiteout_m2_M2TextureTransform_set_rotation(
12047            self_: *mut whiteout_M2TextureTransform,
12048            value: *const whiteout_M2AnimationTrackM2CompatQuaternion,
12049        );
12050        pub fn whiteout_m2_M2TextureTransform_get_scaling(
12051            self_: *mut whiteout_M2TextureTransform,
12052        ) -> *mut whiteout_M2AnimationTrackVector3f;
12053        pub fn whiteout_m2_M2TextureTransform_set_scaling(
12054            self_: *mut whiteout_M2TextureTransform,
12055            value: *const whiteout_M2AnimationTrackVector3f,
12056        );
12057        // ColorAnimation
12058        pub fn whiteout_m2_M2ColorAnimation_new() -> *mut whiteout_M2ColorAnimation;
12059        pub fn whiteout_m2_M2ColorAnimation_delete(self_: *mut whiteout_M2ColorAnimation);
12060        pub fn whiteout_m2_M2ColorAnimation_get_color(
12061            self_: *mut whiteout_M2ColorAnimation,
12062        ) -> *mut whiteout_M2AnimationTrackVector3f;
12063        pub fn whiteout_m2_M2ColorAnimation_set_color(
12064            self_: *mut whiteout_M2ColorAnimation,
12065            value: *const whiteout_M2AnimationTrackVector3f,
12066        );
12067        pub fn whiteout_m2_M2ColorAnimation_get_alpha(
12068            self_: *mut whiteout_M2ColorAnimation,
12069        ) -> *mut whiteout_M2AnimationTrackI16;
12070        pub fn whiteout_m2_M2ColorAnimation_set_alpha(
12071            self_: *mut whiteout_M2ColorAnimation,
12072            value: *const whiteout_M2AnimationTrackI16,
12073        );
12074        // Light
12075        pub fn whiteout_m2_M2Light_new() -> *mut whiteout_M2Light;
12076        pub fn whiteout_m2_M2Light_delete(self_: *mut whiteout_M2Light);
12077        pub fn whiteout_m2_M2Light_get_type(self_: *mut whiteout_M2Light) -> u16;
12078        pub fn whiteout_m2_M2Light_set_type(self_: *mut whiteout_M2Light, value: u16);
12079        pub fn whiteout_m2_M2Light_get_boneId(self_: *mut whiteout_M2Light) -> i16;
12080        pub fn whiteout_m2_M2Light_set_boneId(self_: *mut whiteout_M2Light, value: i16);
12081        pub fn whiteout_m2_M2Light_get_position(
12082            self_: *mut whiteout_M2Light,
12083        ) -> *mut core::ffi::c_void;
12084        pub fn whiteout_m2_M2Light_set_position(
12085            self_: *mut whiteout_M2Light,
12086            value: *const core::ffi::c_void,
12087        );
12088        pub fn whiteout_m2_M2Light_get_ambientColor(
12089            self_: *mut whiteout_M2Light,
12090        ) -> *mut whiteout_M2AnimationTrackVector3f;
12091        pub fn whiteout_m2_M2Light_set_ambientColor(
12092            self_: *mut whiteout_M2Light,
12093            value: *const whiteout_M2AnimationTrackVector3f,
12094        );
12095        pub fn whiteout_m2_M2Light_get_ambientIntensity(
12096            self_: *mut whiteout_M2Light,
12097        ) -> *mut whiteout_M2AnimationTrackF32;
12098        pub fn whiteout_m2_M2Light_set_ambientIntensity(
12099            self_: *mut whiteout_M2Light,
12100            value: *const whiteout_M2AnimationTrackF32,
12101        );
12102        pub fn whiteout_m2_M2Light_get_diffuseColor(
12103            self_: *mut whiteout_M2Light,
12104        ) -> *mut whiteout_M2AnimationTrackVector3f;
12105        pub fn whiteout_m2_M2Light_set_diffuseColor(
12106            self_: *mut whiteout_M2Light,
12107            value: *const whiteout_M2AnimationTrackVector3f,
12108        );
12109        pub fn whiteout_m2_M2Light_get_diffuseIntensity(
12110            self_: *mut whiteout_M2Light,
12111        ) -> *mut whiteout_M2AnimationTrackF32;
12112        pub fn whiteout_m2_M2Light_set_diffuseIntensity(
12113            self_: *mut whiteout_M2Light,
12114            value: *const whiteout_M2AnimationTrackF32,
12115        );
12116        pub fn whiteout_m2_M2Light_get_attenuationStart(
12117            self_: *mut whiteout_M2Light,
12118        ) -> *mut whiteout_M2AnimationTrackF32;
12119        pub fn whiteout_m2_M2Light_set_attenuationStart(
12120            self_: *mut whiteout_M2Light,
12121            value: *const whiteout_M2AnimationTrackF32,
12122        );
12123        pub fn whiteout_m2_M2Light_get_attenuationEnd(
12124            self_: *mut whiteout_M2Light,
12125        ) -> *mut whiteout_M2AnimationTrackF32;
12126        pub fn whiteout_m2_M2Light_set_attenuationEnd(
12127            self_: *mut whiteout_M2Light,
12128            value: *const whiteout_M2AnimationTrackF32,
12129        );
12130        pub fn whiteout_m2_M2Light_get_visibility(
12131            self_: *mut whiteout_M2Light,
12132        ) -> *mut whiteout_M2AnimationTrackU8;
12133        pub fn whiteout_m2_M2Light_set_visibility(
12134            self_: *mut whiteout_M2Light,
12135            value: *const whiteout_M2AnimationTrackU8,
12136        );
12137        // CameraSpline
12138        pub fn whiteout_m2_M2CameraSpline_new() -> *mut whiteout_M2CameraSpline;
12139        pub fn whiteout_m2_M2CameraSpline_delete(self_: *mut whiteout_M2CameraSpline);
12140        pub fn whiteout_m2_M2CameraSpline_get_value(
12141            self_: *mut whiteout_M2CameraSpline,
12142        ) -> *mut core::ffi::c_void;
12143        pub fn whiteout_m2_M2CameraSpline_set_value(
12144            self_: *mut whiteout_M2CameraSpline,
12145            value: *const core::ffi::c_void,
12146        );
12147        pub fn whiteout_m2_M2CameraSpline_get_inTangent(
12148            self_: *mut whiteout_M2CameraSpline,
12149        ) -> *mut core::ffi::c_void;
12150        pub fn whiteout_m2_M2CameraSpline_set_inTangent(
12151            self_: *mut whiteout_M2CameraSpline,
12152            value: *const core::ffi::c_void,
12153        );
12154        pub fn whiteout_m2_M2CameraSpline_get_outTangent(
12155            self_: *mut whiteout_M2CameraSpline,
12156        ) -> *mut core::ffi::c_void;
12157        pub fn whiteout_m2_M2CameraSpline_set_outTangent(
12158            self_: *mut whiteout_M2CameraSpline,
12159            value: *const core::ffi::c_void,
12160        );
12161        // Camera
12162        pub fn whiteout_m2_M2Camera_new() -> *mut whiteout_M2Camera;
12163        pub fn whiteout_m2_M2Camera_delete(self_: *mut whiteout_M2Camera);
12164        pub fn whiteout_m2_M2Camera_get_type(self_: *mut whiteout_M2Camera) -> u32;
12165        pub fn whiteout_m2_M2Camera_set_type(self_: *mut whiteout_M2Camera, value: u32);
12166        pub fn whiteout_m2_M2Camera_get_fieldOfView(self_: *mut whiteout_M2Camera) -> f32;
12167        pub fn whiteout_m2_M2Camera_set_fieldOfView(self_: *mut whiteout_M2Camera, value: f32);
12168        pub fn whiteout_m2_M2Camera_get_farClip(self_: *mut whiteout_M2Camera) -> f32;
12169        pub fn whiteout_m2_M2Camera_set_farClip(self_: *mut whiteout_M2Camera, value: f32);
12170        pub fn whiteout_m2_M2Camera_get_nearClip(self_: *mut whiteout_M2Camera) -> f32;
12171        pub fn whiteout_m2_M2Camera_set_nearClip(self_: *mut whiteout_M2Camera, value: f32);
12172        pub fn whiteout_m2_M2Camera_get_positions(
12173            self_: *mut whiteout_M2Camera,
12174        ) -> *mut whiteout_M2AnimationTrackM2CameraSpline;
12175        pub fn whiteout_m2_M2Camera_set_positions(
12176            self_: *mut whiteout_M2Camera,
12177            value: *const whiteout_M2AnimationTrackM2CameraSpline,
12178        );
12179        pub fn whiteout_m2_M2Camera_get_positionBase(
12180            self_: *mut whiteout_M2Camera,
12181        ) -> *mut core::ffi::c_void;
12182        pub fn whiteout_m2_M2Camera_set_positionBase(
12183            self_: *mut whiteout_M2Camera,
12184            value: *const core::ffi::c_void,
12185        );
12186        pub fn whiteout_m2_M2Camera_get_targetPositions(
12187            self_: *mut whiteout_M2Camera,
12188        ) -> *mut whiteout_M2AnimationTrackM2CameraSpline;
12189        pub fn whiteout_m2_M2Camera_set_targetPositions(
12190            self_: *mut whiteout_M2Camera,
12191            value: *const whiteout_M2AnimationTrackM2CameraSpline,
12192        );
12193        pub fn whiteout_m2_M2Camera_get_targetPositionBase(
12194            self_: *mut whiteout_M2Camera,
12195        ) -> *mut core::ffi::c_void;
12196        pub fn whiteout_m2_M2Camera_set_targetPositionBase(
12197            self_: *mut whiteout_M2Camera,
12198            value: *const core::ffi::c_void,
12199        );
12200        pub fn whiteout_m2_M2Camera_get_roll(
12201            self_: *mut whiteout_M2Camera,
12202        ) -> *mut whiteout_M2AnimationTrackF32;
12203        pub fn whiteout_m2_M2Camera_set_roll(
12204            self_: *mut whiteout_M2Camera,
12205            value: *const whiteout_M2AnimationTrackF32,
12206        );
12207        pub fn whiteout_m2_M2Camera_get_fieldOfViewTrack(
12208            self_: *mut whiteout_M2Camera,
12209        ) -> *mut whiteout_M2AnimationTrackF32;
12210        pub fn whiteout_m2_M2Camera_set_fieldOfViewTrack(
12211            self_: *mut whiteout_M2Camera,
12212            value: *const whiteout_M2AnimationTrackF32,
12213        );
12214        // Attachment
12215        pub fn whiteout_m2_M2Attachment_new() -> *mut whiteout_M2Attachment;
12216        pub fn whiteout_m2_M2Attachment_delete(self_: *mut whiteout_M2Attachment);
12217        pub fn whiteout_m2_M2Attachment_get_id(self_: *mut whiteout_M2Attachment) -> u32;
12218        pub fn whiteout_m2_M2Attachment_set_id(self_: *mut whiteout_M2Attachment, value: u32);
12219        pub fn whiteout_m2_M2Attachment_get_boneId(self_: *mut whiteout_M2Attachment) -> u16;
12220        pub fn whiteout_m2_M2Attachment_set_boneId(self_: *mut whiteout_M2Attachment, value: u16);
12221        pub fn whiteout_m2_M2Attachment_get_unknown(self_: *mut whiteout_M2Attachment) -> u16;
12222        pub fn whiteout_m2_M2Attachment_set_unknown(self_: *mut whiteout_M2Attachment, value: u16);
12223        pub fn whiteout_m2_M2Attachment_get_position(
12224            self_: *mut whiteout_M2Attachment,
12225        ) -> *mut core::ffi::c_void;
12226        pub fn whiteout_m2_M2Attachment_set_position(
12227            self_: *mut whiteout_M2Attachment,
12228            value: *const core::ffi::c_void,
12229        );
12230        pub fn whiteout_m2_M2Attachment_get_animate(
12231            self_: *mut whiteout_M2Attachment,
12232        ) -> *mut whiteout_M2AnimationTrackU8;
12233        pub fn whiteout_m2_M2Attachment_set_animate(
12234            self_: *mut whiteout_M2Attachment,
12235            value: *const whiteout_M2AnimationTrackU8,
12236        );
12237        // RibbonEmitter
12238        pub fn whiteout_m2_M2RibbonEmitter_new() -> *mut whiteout_M2RibbonEmitter;
12239        pub fn whiteout_m2_M2RibbonEmitter_delete(self_: *mut whiteout_M2RibbonEmitter);
12240        pub fn whiteout_m2_M2RibbonEmitter_get_ribbonId(
12241            self_: *mut whiteout_M2RibbonEmitter,
12242        ) -> u32;
12243        pub fn whiteout_m2_M2RibbonEmitter_set_ribbonId(
12244            self_: *mut whiteout_M2RibbonEmitter,
12245            value: u32,
12246        );
12247        pub fn whiteout_m2_M2RibbonEmitter_get_boneId(self_: *mut whiteout_M2RibbonEmitter) -> u32;
12248        pub fn whiteout_m2_M2RibbonEmitter_set_boneId(
12249            self_: *mut whiteout_M2RibbonEmitter,
12250            value: u32,
12251        );
12252        pub fn whiteout_m2_M2RibbonEmitter_get_position(
12253            self_: *mut whiteout_M2RibbonEmitter,
12254        ) -> *mut core::ffi::c_void;
12255        pub fn whiteout_m2_M2RibbonEmitter_set_position(
12256            self_: *mut whiteout_M2RibbonEmitter,
12257            value: *const core::ffi::c_void,
12258        );
12259        pub fn whiteout_m2_M2RibbonEmitter_get_textureIndices_count(
12260            self_: *mut whiteout_M2RibbonEmitter,
12261        ) -> usize;
12262        pub fn whiteout_m2_M2RibbonEmitter_resize_textureIndices(
12263            self_: *mut whiteout_M2RibbonEmitter,
12264            count: usize,
12265        );
12266        pub fn whiteout_m2_M2RibbonEmitter_get_textureIndices_data(
12267            self_: *mut whiteout_M2RibbonEmitter,
12268        ) -> *const u16;
12269        pub fn whiteout_m2_M2RibbonEmitter_assign_textureIndices(
12270            self_: *mut whiteout_M2RibbonEmitter,
12271            data: *const u16,
12272            count: usize,
12273        );
12274        pub fn whiteout_m2_M2RibbonEmitter_get_materialIndices_count(
12275            self_: *mut whiteout_M2RibbonEmitter,
12276        ) -> usize;
12277        pub fn whiteout_m2_M2RibbonEmitter_resize_materialIndices(
12278            self_: *mut whiteout_M2RibbonEmitter,
12279            count: usize,
12280        );
12281        pub fn whiteout_m2_M2RibbonEmitter_get_materialIndices_data(
12282            self_: *mut whiteout_M2RibbonEmitter,
12283        ) -> *const u16;
12284        pub fn whiteout_m2_M2RibbonEmitter_assign_materialIndices(
12285            self_: *mut whiteout_M2RibbonEmitter,
12286            data: *const u16,
12287            count: usize,
12288        );
12289        pub fn whiteout_m2_M2RibbonEmitter_get_colorTrack(
12290            self_: *mut whiteout_M2RibbonEmitter,
12291        ) -> *mut whiteout_M2AnimationTrackVector3f;
12292        pub fn whiteout_m2_M2RibbonEmitter_set_colorTrack(
12293            self_: *mut whiteout_M2RibbonEmitter,
12294            value: *const whiteout_M2AnimationTrackVector3f,
12295        );
12296        pub fn whiteout_m2_M2RibbonEmitter_get_alphaTrack(
12297            self_: *mut whiteout_M2RibbonEmitter,
12298        ) -> *mut whiteout_M2AnimationTrackI16;
12299        pub fn whiteout_m2_M2RibbonEmitter_set_alphaTrack(
12300            self_: *mut whiteout_M2RibbonEmitter,
12301            value: *const whiteout_M2AnimationTrackI16,
12302        );
12303        pub fn whiteout_m2_M2RibbonEmitter_get_heightAbove(
12304            self_: *mut whiteout_M2RibbonEmitter,
12305        ) -> *mut whiteout_M2AnimationTrackF32;
12306        pub fn whiteout_m2_M2RibbonEmitter_set_heightAbove(
12307            self_: *mut whiteout_M2RibbonEmitter,
12308            value: *const whiteout_M2AnimationTrackF32,
12309        );
12310        pub fn whiteout_m2_M2RibbonEmitter_get_heightBelow(
12311            self_: *mut whiteout_M2RibbonEmitter,
12312        ) -> *mut whiteout_M2AnimationTrackF32;
12313        pub fn whiteout_m2_M2RibbonEmitter_set_heightBelow(
12314            self_: *mut whiteout_M2RibbonEmitter,
12315            value: *const whiteout_M2AnimationTrackF32,
12316        );
12317        pub fn whiteout_m2_M2RibbonEmitter_get_edgesPerSecond(
12318            self_: *mut whiteout_M2RibbonEmitter,
12319        ) -> f32;
12320        pub fn whiteout_m2_M2RibbonEmitter_set_edgesPerSecond(
12321            self_: *mut whiteout_M2RibbonEmitter,
12322            value: f32,
12323        );
12324        pub fn whiteout_m2_M2RibbonEmitter_get_edgeLifetime(
12325            self_: *mut whiteout_M2RibbonEmitter,
12326        ) -> f32;
12327        pub fn whiteout_m2_M2RibbonEmitter_set_edgeLifetime(
12328            self_: *mut whiteout_M2RibbonEmitter,
12329            value: f32,
12330        );
12331        pub fn whiteout_m2_M2RibbonEmitter_get_gravity(self_: *mut whiteout_M2RibbonEmitter)
12332            -> f32;
12333        pub fn whiteout_m2_M2RibbonEmitter_set_gravity(
12334            self_: *mut whiteout_M2RibbonEmitter,
12335            value: f32,
12336        );
12337        pub fn whiteout_m2_M2RibbonEmitter_get_textureRows(
12338            self_: *mut whiteout_M2RibbonEmitter,
12339        ) -> u16;
12340        pub fn whiteout_m2_M2RibbonEmitter_set_textureRows(
12341            self_: *mut whiteout_M2RibbonEmitter,
12342            value: u16,
12343        );
12344        pub fn whiteout_m2_M2RibbonEmitter_get_textureCols(
12345            self_: *mut whiteout_M2RibbonEmitter,
12346        ) -> u16;
12347        pub fn whiteout_m2_M2RibbonEmitter_set_textureCols(
12348            self_: *mut whiteout_M2RibbonEmitter,
12349            value: u16,
12350        );
12351        pub fn whiteout_m2_M2RibbonEmitter_get_texSlot(
12352            self_: *mut whiteout_M2RibbonEmitter,
12353        ) -> *mut whiteout_M2AnimationTrackU16;
12354        pub fn whiteout_m2_M2RibbonEmitter_set_texSlot(
12355            self_: *mut whiteout_M2RibbonEmitter,
12356            value: *const whiteout_M2AnimationTrackU16,
12357        );
12358        pub fn whiteout_m2_M2RibbonEmitter_get_visibility(
12359            self_: *mut whiteout_M2RibbonEmitter,
12360        ) -> *mut whiteout_M2AnimationTrackU8;
12361        pub fn whiteout_m2_M2RibbonEmitter_set_visibility(
12362            self_: *mut whiteout_M2RibbonEmitter,
12363            value: *const whiteout_M2AnimationTrackU8,
12364        );
12365        pub fn whiteout_m2_M2RibbonEmitter_get_priorityPlane(
12366            self_: *mut whiteout_M2RibbonEmitter,
12367        ) -> i16;
12368        pub fn whiteout_m2_M2RibbonEmitter_set_priorityPlane(
12369            self_: *mut whiteout_M2RibbonEmitter,
12370            value: i16,
12371        );
12372        pub fn whiteout_m2_M2RibbonEmitter_get_ribbonColorIndex(
12373            self_: *mut whiteout_M2RibbonEmitter,
12374        ) -> i8;
12375        pub fn whiteout_m2_M2RibbonEmitter_set_ribbonColorIndex(
12376            self_: *mut whiteout_M2RibbonEmitter,
12377            value: i8,
12378        );
12379        pub fn whiteout_m2_M2RibbonEmitter_get_textureTransformIndex(
12380            self_: *mut whiteout_M2RibbonEmitter,
12381        ) -> i8;
12382        pub fn whiteout_m2_M2RibbonEmitter_set_textureTransformIndex(
12383            self_: *mut whiteout_M2RibbonEmitter,
12384            value: i8,
12385        );
12386        // Box
12387        pub fn whiteout_m2_M2Box_new() -> *mut whiteout_M2Box;
12388        pub fn whiteout_m2_M2Box_delete(self_: *mut whiteout_M2Box);
12389        pub fn whiteout_m2_M2Box_get_minimum(self_: *mut whiteout_M2Box) -> *mut core::ffi::c_void;
12390        pub fn whiteout_m2_M2Box_set_minimum(
12391            self_: *mut whiteout_M2Box,
12392            value: *const core::ffi::c_void,
12393        );
12394        pub fn whiteout_m2_M2Box_get_maximum(self_: *mut whiteout_M2Box) -> *mut core::ffi::c_void;
12395        pub fn whiteout_m2_M2Box_set_maximum(
12396            self_: *mut whiteout_M2Box,
12397            value: *const core::ffi::c_void,
12398        );
12399        // ParticleEmitter
12400        pub fn whiteout_m2_M2ParticleEmitter_new() -> *mut whiteout_M2ParticleEmitter;
12401        pub fn whiteout_m2_M2ParticleEmitter_delete(self_: *mut whiteout_M2ParticleEmitter);
12402        pub fn whiteout_m2_M2ParticleEmitter_get_particleId(
12403            self_: *mut whiteout_M2ParticleEmitter,
12404        ) -> u32;
12405        pub fn whiteout_m2_M2ParticleEmitter_set_particleId(
12406            self_: *mut whiteout_M2ParticleEmitter,
12407            value: u32,
12408        );
12409        pub fn whiteout_m2_M2ParticleEmitter_get_flags(
12410            self_: *mut whiteout_M2ParticleEmitter,
12411        ) -> i32;
12412        pub fn whiteout_m2_M2ParticleEmitter_set_flags(
12413            self_: *mut whiteout_M2ParticleEmitter,
12414            value: i32,
12415        );
12416        pub fn whiteout_m2_M2ParticleEmitter_get_position(
12417            self_: *mut whiteout_M2ParticleEmitter,
12418        ) -> *mut core::ffi::c_void;
12419        pub fn whiteout_m2_M2ParticleEmitter_set_position(
12420            self_: *mut whiteout_M2ParticleEmitter,
12421            value: *const core::ffi::c_void,
12422        );
12423        pub fn whiteout_m2_M2ParticleEmitter_get_boneId(
12424            self_: *mut whiteout_M2ParticleEmitter,
12425        ) -> u16;
12426        pub fn whiteout_m2_M2ParticleEmitter_set_boneId(
12427            self_: *mut whiteout_M2ParticleEmitter,
12428            value: u16,
12429        );
12430        pub fn whiteout_m2_M2ParticleEmitter_get_particleModelFilename(
12431            self_: *mut whiteout_M2ParticleEmitter,
12432        ) -> RawCString;
12433        pub fn whiteout_m2_M2ParticleEmitter_set_particleModelFilename(
12434            self_: *mut whiteout_M2ParticleEmitter,
12435            value: *const core::ffi::c_char,
12436        );
12437        pub fn whiteout_m2_M2ParticleEmitter_get_childEmittersModelFilename(
12438            self_: *mut whiteout_M2ParticleEmitter,
12439        ) -> RawCString;
12440        pub fn whiteout_m2_M2ParticleEmitter_set_childEmittersModelFilename(
12441            self_: *mut whiteout_M2ParticleEmitter,
12442            value: *const core::ffi::c_char,
12443        );
12444        pub fn whiteout_m2_M2ParticleEmitter_get_blendingType(
12445            self_: *mut whiteout_M2ParticleEmitter,
12446        ) -> i32;
12447        pub fn whiteout_m2_M2ParticleEmitter_set_blendingType(
12448            self_: *mut whiteout_M2ParticleEmitter,
12449            value: i32,
12450        );
12451        pub fn whiteout_m2_M2ParticleEmitter_get_emitterType(
12452            self_: *mut whiteout_M2ParticleEmitter,
12453        ) -> i32;
12454        pub fn whiteout_m2_M2ParticleEmitter_set_emitterType(
12455            self_: *mut whiteout_M2ParticleEmitter,
12456            value: i32,
12457        );
12458        pub fn whiteout_m2_M2ParticleEmitter_get_particleColorIndex(
12459            self_: *mut whiteout_M2ParticleEmitter,
12460        ) -> u16;
12461        pub fn whiteout_m2_M2ParticleEmitter_set_particleColorIndex(
12462            self_: *mut whiteout_M2ParticleEmitter,
12463            value: u16,
12464        );
12465        pub fn whiteout_m2_M2ParticleEmitter_get_textureTilerotation(
12466            self_: *mut whiteout_M2ParticleEmitter,
12467        ) -> i16;
12468        pub fn whiteout_m2_M2ParticleEmitter_set_textureTilerotation(
12469            self_: *mut whiteout_M2ParticleEmitter,
12470            value: i16,
12471        );
12472        pub fn whiteout_m2_M2ParticleEmitter_get_rows(
12473            self_: *mut whiteout_M2ParticleEmitter,
12474        ) -> u16;
12475        pub fn whiteout_m2_M2ParticleEmitter_set_rows(
12476            self_: *mut whiteout_M2ParticleEmitter,
12477            value: u16,
12478        );
12479        pub fn whiteout_m2_M2ParticleEmitter_get_columns(
12480            self_: *mut whiteout_M2ParticleEmitter,
12481        ) -> u16;
12482        pub fn whiteout_m2_M2ParticleEmitter_set_columns(
12483            self_: *mut whiteout_M2ParticleEmitter,
12484            value: u16,
12485        );
12486        pub fn whiteout_m2_M2ParticleEmitter_get_emissionSpeed(
12487            self_: *mut whiteout_M2ParticleEmitter,
12488        ) -> *mut whiteout_M2AnimationTrackF32;
12489        pub fn whiteout_m2_M2ParticleEmitter_set_emissionSpeed(
12490            self_: *mut whiteout_M2ParticleEmitter,
12491            value: *const whiteout_M2AnimationTrackF32,
12492        );
12493        pub fn whiteout_m2_M2ParticleEmitter_get_speedVariation(
12494            self_: *mut whiteout_M2ParticleEmitter,
12495        ) -> *mut whiteout_M2AnimationTrackF32;
12496        pub fn whiteout_m2_M2ParticleEmitter_set_speedVariation(
12497            self_: *mut whiteout_M2ParticleEmitter,
12498            value: *const whiteout_M2AnimationTrackF32,
12499        );
12500        pub fn whiteout_m2_M2ParticleEmitter_get_verticalRange(
12501            self_: *mut whiteout_M2ParticleEmitter,
12502        ) -> *mut whiteout_M2AnimationTrackF32;
12503        pub fn whiteout_m2_M2ParticleEmitter_set_verticalRange(
12504            self_: *mut whiteout_M2ParticleEmitter,
12505            value: *const whiteout_M2AnimationTrackF32,
12506        );
12507        pub fn whiteout_m2_M2ParticleEmitter_get_horizontalRange(
12508            self_: *mut whiteout_M2ParticleEmitter,
12509        ) -> *mut whiteout_M2AnimationTrackF32;
12510        pub fn whiteout_m2_M2ParticleEmitter_set_horizontalRange(
12511            self_: *mut whiteout_M2ParticleEmitter,
12512            value: *const whiteout_M2AnimationTrackF32,
12513        );
12514        pub fn whiteout_m2_M2ParticleEmitter_get_gravity(
12515            self_: *mut whiteout_M2ParticleEmitter,
12516        ) -> *mut whiteout_M2AnimationTrackF32;
12517        pub fn whiteout_m2_M2ParticleEmitter_set_gravity(
12518            self_: *mut whiteout_M2ParticleEmitter,
12519            value: *const whiteout_M2AnimationTrackF32,
12520        );
12521        pub fn whiteout_m2_M2ParticleEmitter_get_lifespan(
12522            self_: *mut whiteout_M2ParticleEmitter,
12523        ) -> *mut whiteout_M2AnimationTrackF32;
12524        pub fn whiteout_m2_M2ParticleEmitter_set_lifespan(
12525            self_: *mut whiteout_M2ParticleEmitter,
12526            value: *const whiteout_M2AnimationTrackF32,
12527        );
12528        pub fn whiteout_m2_M2ParticleEmitter_get_lifespanVariation(
12529            self_: *mut whiteout_M2ParticleEmitter,
12530        ) -> f32;
12531        pub fn whiteout_m2_M2ParticleEmitter_set_lifespanVariation(
12532            self_: *mut whiteout_M2ParticleEmitter,
12533            value: f32,
12534        );
12535        pub fn whiteout_m2_M2ParticleEmitter_get_emissionRate(
12536            self_: *mut whiteout_M2ParticleEmitter,
12537        ) -> *mut whiteout_M2AnimationTrackF32;
12538        pub fn whiteout_m2_M2ParticleEmitter_set_emissionRate(
12539            self_: *mut whiteout_M2ParticleEmitter,
12540            value: *const whiteout_M2AnimationTrackF32,
12541        );
12542        pub fn whiteout_m2_M2ParticleEmitter_get_emissionRateVariation(
12543            self_: *mut whiteout_M2ParticleEmitter,
12544        ) -> f32;
12545        pub fn whiteout_m2_M2ParticleEmitter_set_emissionRateVariation(
12546            self_: *mut whiteout_M2ParticleEmitter,
12547            value: f32,
12548        );
12549        pub fn whiteout_m2_M2ParticleEmitter_get_emissionAreaWidth(
12550            self_: *mut whiteout_M2ParticleEmitter,
12551        ) -> *mut whiteout_M2AnimationTrackF32;
12552        pub fn whiteout_m2_M2ParticleEmitter_set_emissionAreaWidth(
12553            self_: *mut whiteout_M2ParticleEmitter,
12554            value: *const whiteout_M2AnimationTrackF32,
12555        );
12556        pub fn whiteout_m2_M2ParticleEmitter_get_emissionAreaLength(
12557            self_: *mut whiteout_M2ParticleEmitter,
12558        ) -> *mut whiteout_M2AnimationTrackF32;
12559        pub fn whiteout_m2_M2ParticleEmitter_set_emissionAreaLength(
12560            self_: *mut whiteout_M2ParticleEmitter,
12561            value: *const whiteout_M2AnimationTrackF32,
12562        );
12563        pub fn whiteout_m2_M2ParticleEmitter_get_zSource(
12564            self_: *mut whiteout_M2ParticleEmitter,
12565        ) -> *mut whiteout_M2AnimationTrackF32;
12566        pub fn whiteout_m2_M2ParticleEmitter_set_zSource(
12567            self_: *mut whiteout_M2ParticleEmitter,
12568            value: *const whiteout_M2AnimationTrackF32,
12569        );
12570        pub fn whiteout_m2_M2ParticleEmitter_get_colorTrack(
12571            self_: *mut whiteout_M2ParticleEmitter,
12572        ) -> *mut whiteout_M2ParticleAnimationTrackVector3f;
12573        pub fn whiteout_m2_M2ParticleEmitter_set_colorTrack(
12574            self_: *mut whiteout_M2ParticleEmitter,
12575            value: *const whiteout_M2ParticleAnimationTrackVector3f,
12576        );
12577        pub fn whiteout_m2_M2ParticleEmitter_get_scaleTrack(
12578            self_: *mut whiteout_M2ParticleEmitter,
12579        ) -> *mut whiteout_M2ParticleAnimationTrackVector2f;
12580        pub fn whiteout_m2_M2ParticleEmitter_set_scaleTrack(
12581            self_: *mut whiteout_M2ParticleEmitter,
12582            value: *const whiteout_M2ParticleAnimationTrackVector2f,
12583        );
12584        pub fn whiteout_m2_M2ParticleEmitter_get_scaleVary(
12585            self_: *mut whiteout_M2ParticleEmitter,
12586        ) -> *mut core::ffi::c_void;
12587        pub fn whiteout_m2_M2ParticleEmitter_set_scaleVary(
12588            self_: *mut whiteout_M2ParticleEmitter,
12589            value: *const core::ffi::c_void,
12590        );
12591        pub fn whiteout_m2_M2ParticleEmitter_get_tailLength(
12592            self_: *mut whiteout_M2ParticleEmitter,
12593        ) -> f32;
12594        pub fn whiteout_m2_M2ParticleEmitter_set_tailLength(
12595            self_: *mut whiteout_M2ParticleEmitter,
12596            value: f32,
12597        );
12598        pub fn whiteout_m2_M2ParticleEmitter_get_twinkleSpeed(
12599            self_: *mut whiteout_M2ParticleEmitter,
12600        ) -> f32;
12601        pub fn whiteout_m2_M2ParticleEmitter_set_twinkleSpeed(
12602            self_: *mut whiteout_M2ParticleEmitter,
12603            value: f32,
12604        );
12605        pub fn whiteout_m2_M2ParticleEmitter_get_twinklePercent(
12606            self_: *mut whiteout_M2ParticleEmitter,
12607        ) -> f32;
12608        pub fn whiteout_m2_M2ParticleEmitter_set_twinklePercent(
12609            self_: *mut whiteout_M2ParticleEmitter,
12610            value: f32,
12611        );
12612        pub fn whiteout_m2_M2ParticleEmitter_get_twinkleScale(
12613            self_: *mut whiteout_M2ParticleEmitter,
12614        ) -> *mut core::ffi::c_void;
12615        pub fn whiteout_m2_M2ParticleEmitter_set_twinkleScale(
12616            self_: *mut whiteout_M2ParticleEmitter,
12617            value: *const core::ffi::c_void,
12618        );
12619        pub fn whiteout_m2_M2ParticleEmitter_get_inheritVelocityScale(
12620            self_: *mut whiteout_M2ParticleEmitter,
12621        ) -> f32;
12622        pub fn whiteout_m2_M2ParticleEmitter_set_inheritVelocityScale(
12623            self_: *mut whiteout_M2ParticleEmitter,
12624            value: f32,
12625        );
12626        pub fn whiteout_m2_M2ParticleEmitter_get_drag(
12627            self_: *mut whiteout_M2ParticleEmitter,
12628        ) -> f32;
12629        pub fn whiteout_m2_M2ParticleEmitter_set_drag(
12630            self_: *mut whiteout_M2ParticleEmitter,
12631            value: f32,
12632        );
12633        pub fn whiteout_m2_M2ParticleEmitter_get_baseSpin(
12634            self_: *mut whiteout_M2ParticleEmitter,
12635        ) -> f32;
12636        pub fn whiteout_m2_M2ParticleEmitter_set_baseSpin(
12637            self_: *mut whiteout_M2ParticleEmitter,
12638            value: f32,
12639        );
12640        pub fn whiteout_m2_M2ParticleEmitter_get_baseSpinVariation(
12641            self_: *mut whiteout_M2ParticleEmitter,
12642        ) -> f32;
12643        pub fn whiteout_m2_M2ParticleEmitter_set_baseSpinVariation(
12644            self_: *mut whiteout_M2ParticleEmitter,
12645            value: f32,
12646        );
12647        pub fn whiteout_m2_M2ParticleEmitter_get_spinSpeed(
12648            self_: *mut whiteout_M2ParticleEmitter,
12649        ) -> f32;
12650        pub fn whiteout_m2_M2ParticleEmitter_set_spinSpeed(
12651            self_: *mut whiteout_M2ParticleEmitter,
12652            value: f32,
12653        );
12654        pub fn whiteout_m2_M2ParticleEmitter_get_spinSpeedVariation(
12655            self_: *mut whiteout_M2ParticleEmitter,
12656        ) -> f32;
12657        pub fn whiteout_m2_M2ParticleEmitter_set_spinSpeedVariation(
12658            self_: *mut whiteout_M2ParticleEmitter,
12659            value: f32,
12660        );
12661        pub fn whiteout_m2_M2ParticleEmitter_get_tumble(
12662            self_: *mut whiteout_M2ParticleEmitter,
12663        ) -> *mut whiteout_M2Box;
12664        pub fn whiteout_m2_M2ParticleEmitter_set_tumble(
12665            self_: *mut whiteout_M2ParticleEmitter,
12666            value: *const whiteout_M2Box,
12667        );
12668        pub fn whiteout_m2_M2ParticleEmitter_get_windVector(
12669            self_: *mut whiteout_M2ParticleEmitter,
12670        ) -> *mut core::ffi::c_void;
12671        pub fn whiteout_m2_M2ParticleEmitter_set_windVector(
12672            self_: *mut whiteout_M2ParticleEmitter,
12673            value: *const core::ffi::c_void,
12674        );
12675        pub fn whiteout_m2_M2ParticleEmitter_get_windTime(
12676            self_: *mut whiteout_M2ParticleEmitter,
12677        ) -> f32;
12678        pub fn whiteout_m2_M2ParticleEmitter_set_windTime(
12679            self_: *mut whiteout_M2ParticleEmitter,
12680            value: f32,
12681        );
12682        pub fn whiteout_m2_M2ParticleEmitter_get_followSpeed1(
12683            self_: *mut whiteout_M2ParticleEmitter,
12684        ) -> f32;
12685        pub fn whiteout_m2_M2ParticleEmitter_set_followSpeed1(
12686            self_: *mut whiteout_M2ParticleEmitter,
12687            value: f32,
12688        );
12689        pub fn whiteout_m2_M2ParticleEmitter_get_followScale1(
12690            self_: *mut whiteout_M2ParticleEmitter,
12691        ) -> f32;
12692        pub fn whiteout_m2_M2ParticleEmitter_set_followScale1(
12693            self_: *mut whiteout_M2ParticleEmitter,
12694            value: f32,
12695        );
12696        pub fn whiteout_m2_M2ParticleEmitter_get_followSpeed2(
12697            self_: *mut whiteout_M2ParticleEmitter,
12698        ) -> f32;
12699        pub fn whiteout_m2_M2ParticleEmitter_set_followSpeed2(
12700            self_: *mut whiteout_M2ParticleEmitter,
12701            value: f32,
12702        );
12703        pub fn whiteout_m2_M2ParticleEmitter_get_followScale2(
12704            self_: *mut whiteout_M2ParticleEmitter,
12705        ) -> f32;
12706        pub fn whiteout_m2_M2ParticleEmitter_set_followScale2(
12707            self_: *mut whiteout_M2ParticleEmitter,
12708            value: f32,
12709        );
12710        pub fn whiteout_m2_M2ParticleEmitter_get_splinePoints_count(
12711            self_: *mut whiteout_M2ParticleEmitter,
12712        ) -> usize;
12713        pub fn whiteout_m2_M2ParticleEmitter_resize_splinePoints(
12714            self_: *mut whiteout_M2ParticleEmitter,
12715            count: usize,
12716        );
12717        pub fn whiteout_m2_M2ParticleEmitter_get_splinePoints_data(
12718            self_: *mut whiteout_M2ParticleEmitter,
12719        ) -> *const f32;
12720        pub fn whiteout_m2_M2ParticleEmitter_assign_splinePoints(
12721            self_: *mut whiteout_M2ParticleEmitter,
12722            data: *const f32,
12723            count: usize,
12724        );
12725        pub fn whiteout_m2_M2ParticleEmitter_get_enabledIn(
12726            self_: *mut whiteout_M2ParticleEmitter,
12727        ) -> *mut whiteout_M2AnimationTrackU8;
12728        pub fn whiteout_m2_M2ParticleEmitter_set_enabledIn(
12729            self_: *mut whiteout_M2ParticleEmitter,
12730            value: *const whiteout_M2AnimationTrackU8,
12731        );
12732        // Event
12733        pub fn whiteout_m2_M2Event_new() -> *mut whiteout_M2Event;
12734        pub fn whiteout_m2_M2Event_delete(self_: *mut whiteout_M2Event);
12735        pub fn whiteout_m2_M2Event_get_identifier(self_: *mut whiteout_M2Event) -> u32;
12736        pub fn whiteout_m2_M2Event_set_identifier(self_: *mut whiteout_M2Event, value: u32);
12737        pub fn whiteout_m2_M2Event_get_data(self_: *mut whiteout_M2Event) -> u32;
12738        pub fn whiteout_m2_M2Event_set_data(self_: *mut whiteout_M2Event, value: u32);
12739        pub fn whiteout_m2_M2Event_get_boneId(self_: *mut whiteout_M2Event) -> u32;
12740        pub fn whiteout_m2_M2Event_set_boneId(self_: *mut whiteout_M2Event, value: u32);
12741        pub fn whiteout_m2_M2Event_get_position(
12742            self_: *mut whiteout_M2Event,
12743        ) -> *mut core::ffi::c_void;
12744        pub fn whiteout_m2_M2Event_set_position(
12745            self_: *mut whiteout_M2Event,
12746            value: *const core::ffi::c_void,
12747        );
12748        pub fn whiteout_m2_M2Event_get_enabled(
12749            self_: *mut whiteout_M2Event,
12750        ) -> *mut whiteout_M2AnimationTrackBase;
12751        pub fn whiteout_m2_M2Event_set_enabled(
12752            self_: *mut whiteout_M2Event,
12753            value: *const whiteout_M2AnimationTrackBase,
12754        );
12755        // Model
12756        pub fn whiteout_m2_M2Model_new() -> *mut whiteout_M2Model;
12757        pub fn whiteout_m2_M2Model_delete(self_: *mut whiteout_M2Model);
12758        pub fn whiteout_m2_M2Model_get_modelName(self_: *mut whiteout_M2Model) -> RawCString;
12759        pub fn whiteout_m2_M2Model_set_modelName(
12760            self_: *mut whiteout_M2Model,
12761            value: *const core::ffi::c_char,
12762        );
12763        pub fn whiteout_m2_M2Model_get_globalFlags(
12764            self_: *mut whiteout_M2Model,
12765        ) -> *mut whiteout_M2GlobalFlags;
12766        pub fn whiteout_m2_M2Model_set_globalFlags(
12767            self_: *mut whiteout_M2Model,
12768            value: *const whiteout_M2GlobalFlags,
12769        );
12770        pub fn whiteout_m2_M2Model_get_globalLoops_count(self_: *mut whiteout_M2Model) -> usize;
12771        pub fn whiteout_m2_M2Model_resize_globalLoops(self_: *mut whiteout_M2Model, count: usize);
12772        pub fn whiteout_m2_M2Model_get_globalLoops_at(
12773            self_: *mut whiteout_M2Model,
12774            index: usize,
12775        ) -> *mut whiteout_M2GlobalSequence;
12776        pub fn whiteout_m2_M2Model_get_sequences_count(self_: *mut whiteout_M2Model) -> usize;
12777        pub fn whiteout_m2_M2Model_resize_sequences(self_: *mut whiteout_M2Model, count: usize);
12778        pub fn whiteout_m2_M2Model_get_sequences_at(
12779            self_: *mut whiteout_M2Model,
12780            index: usize,
12781        ) -> *mut whiteout_M2Sequence;
12782        pub fn whiteout_m2_M2Model_get_sequenceIdxHashById_count(
12783            self_: *mut whiteout_M2Model,
12784        ) -> usize;
12785        pub fn whiteout_m2_M2Model_resize_sequenceIdxHashById(
12786            self_: *mut whiteout_M2Model,
12787            count: usize,
12788        );
12789        pub fn whiteout_m2_M2Model_get_sequenceIdxHashById_data(
12790            self_: *mut whiteout_M2Model,
12791        ) -> *const u16;
12792        pub fn whiteout_m2_M2Model_assign_sequenceIdxHashById(
12793            self_: *mut whiteout_M2Model,
12794            data: *const u16,
12795            count: usize,
12796        );
12797        pub fn whiteout_m2_M2Model_get_bones_count(self_: *mut whiteout_M2Model) -> usize;
12798        pub fn whiteout_m2_M2Model_resize_bones(self_: *mut whiteout_M2Model, count: usize);
12799        pub fn whiteout_m2_M2Model_get_bones_at(
12800            self_: *mut whiteout_M2Model,
12801            index: usize,
12802        ) -> *mut whiteout_M2Bone;
12803        pub fn whiteout_m2_M2Model_get_keyBoneIds_count(self_: *mut whiteout_M2Model) -> usize;
12804        pub fn whiteout_m2_M2Model_resize_keyBoneIds(self_: *mut whiteout_M2Model, count: usize);
12805        pub fn whiteout_m2_M2Model_get_keyBoneIds_data(self_: *mut whiteout_M2Model) -> *const u16;
12806        pub fn whiteout_m2_M2Model_assign_keyBoneIds(
12807            self_: *mut whiteout_M2Model,
12808            data: *const u16,
12809            count: usize,
12810        );
12811        pub fn whiteout_m2_M2Model_get_vertices_count(self_: *mut whiteout_M2Model) -> usize;
12812        pub fn whiteout_m2_M2Model_resize_vertices(self_: *mut whiteout_M2Model, count: usize);
12813        pub fn whiteout_m2_M2Model_get_vertices_at(
12814            self_: *mut whiteout_M2Model,
12815            index: usize,
12816        ) -> *mut whiteout_M2Vertex;
12817        pub fn whiteout_m2_M2Model_get_skinProfiles_count(self_: *mut whiteout_M2Model) -> usize;
12818        pub fn whiteout_m2_M2Model_resize_skinProfiles(self_: *mut whiteout_M2Model, count: usize);
12819        pub fn whiteout_m2_M2Model_get_skinProfiles_at(
12820            self_: *mut whiteout_M2Model,
12821            index: usize,
12822        ) -> *mut whiteout_M2SkinProfile;
12823        pub fn whiteout_m2_M2Model_get_lodProfiles_count(self_: *mut whiteout_M2Model) -> usize;
12824        pub fn whiteout_m2_M2Model_resize_lodProfiles(self_: *mut whiteout_M2Model, count: usize);
12825        pub fn whiteout_m2_M2Model_get_lodProfiles_at(
12826            self_: *mut whiteout_M2Model,
12827            index: usize,
12828        ) -> *mut whiteout_M2SkinProfile;
12829        pub fn whiteout_m2_M2Model_get_numSkinProfiles(self_: *mut whiteout_M2Model) -> u32;
12830        pub fn whiteout_m2_M2Model_set_numSkinProfiles(self_: *mut whiteout_M2Model, value: u32);
12831        pub fn whiteout_m2_M2Model_get_colors_count(self_: *mut whiteout_M2Model) -> usize;
12832        pub fn whiteout_m2_M2Model_resize_colors(self_: *mut whiteout_M2Model, count: usize);
12833        pub fn whiteout_m2_M2Model_get_colors_at(
12834            self_: *mut whiteout_M2Model,
12835            index: usize,
12836        ) -> *mut whiteout_M2ColorAnimation;
12837        pub fn whiteout_m2_M2Model_get_textures_count(self_: *mut whiteout_M2Model) -> usize;
12838        pub fn whiteout_m2_M2Model_resize_textures(self_: *mut whiteout_M2Model, count: usize);
12839        pub fn whiteout_m2_M2Model_get_textures_at(
12840            self_: *mut whiteout_M2Model,
12841            index: usize,
12842        ) -> *mut whiteout_M2Texture;
12843        pub fn whiteout_m2_M2Model_get_textureWeights_count(self_: *mut whiteout_M2Model) -> usize;
12844        pub fn whiteout_m2_M2Model_resize_textureWeights(
12845            self_: *mut whiteout_M2Model,
12846            count: usize,
12847        );
12848        pub fn whiteout_m2_M2Model_get_textureWeights_at(
12849            self_: *mut whiteout_M2Model,
12850            index: usize,
12851        ) -> *mut whiteout_M2TextureWeight;
12852        pub fn whiteout_m2_M2Model_get_textureTransforms_count(
12853            self_: *mut whiteout_M2Model,
12854        ) -> usize;
12855        pub fn whiteout_m2_M2Model_resize_textureTransforms(
12856            self_: *mut whiteout_M2Model,
12857            count: usize,
12858        );
12859        pub fn whiteout_m2_M2Model_get_textureTransforms_at(
12860            self_: *mut whiteout_M2Model,
12861            index: usize,
12862        ) -> *mut whiteout_M2TextureTransform;
12863        pub fn whiteout_m2_M2Model_get_textureIndicesById_count(
12864            self_: *mut whiteout_M2Model,
12865        ) -> usize;
12866        pub fn whiteout_m2_M2Model_resize_textureIndicesById(
12867            self_: *mut whiteout_M2Model,
12868            count: usize,
12869        );
12870        pub fn whiteout_m2_M2Model_get_textureIndicesById_data(
12871            self_: *mut whiteout_M2Model,
12872        ) -> *const u16;
12873        pub fn whiteout_m2_M2Model_assign_textureIndicesById(
12874            self_: *mut whiteout_M2Model,
12875            data: *const u16,
12876            count: usize,
12877        );
12878        pub fn whiteout_m2_M2Model_get_materials_count(self_: *mut whiteout_M2Model) -> usize;
12879        pub fn whiteout_m2_M2Model_resize_materials(self_: *mut whiteout_M2Model, count: usize);
12880        pub fn whiteout_m2_M2Model_get_materials_at(
12881            self_: *mut whiteout_M2Model,
12882            index: usize,
12883        ) -> *mut whiteout_M2Material;
12884        pub fn whiteout_m2_M2Model_get_boneCombos_count(self_: *mut whiteout_M2Model) -> usize;
12885        pub fn whiteout_m2_M2Model_resize_boneCombos(self_: *mut whiteout_M2Model, count: usize);
12886        pub fn whiteout_m2_M2Model_get_boneCombos_data(self_: *mut whiteout_M2Model) -> *const u16;
12887        pub fn whiteout_m2_M2Model_assign_boneCombos(
12888            self_: *mut whiteout_M2Model,
12889            data: *const u16,
12890            count: usize,
12891        );
12892        pub fn whiteout_m2_M2Model_get_textureCombos_count(self_: *mut whiteout_M2Model) -> usize;
12893        pub fn whiteout_m2_M2Model_resize_textureCombos(self_: *mut whiteout_M2Model, count: usize);
12894        pub fn whiteout_m2_M2Model_get_textureCombos_data(
12895            self_: *mut whiteout_M2Model,
12896        ) -> *const u16;
12897        pub fn whiteout_m2_M2Model_assign_textureCombos(
12898            self_: *mut whiteout_M2Model,
12899            data: *const u16,
12900            count: usize,
12901        );
12902        pub fn whiteout_m2_M2Model_get_textureCoordCombos_count(
12903            self_: *mut whiteout_M2Model,
12904        ) -> usize;
12905        pub fn whiteout_m2_M2Model_resize_textureCoordCombos(
12906            self_: *mut whiteout_M2Model,
12907            count: usize,
12908        );
12909        pub fn whiteout_m2_M2Model_get_textureCoordCombos_data(
12910            self_: *mut whiteout_M2Model,
12911        ) -> *const u16;
12912        pub fn whiteout_m2_M2Model_assign_textureCoordCombos(
12913            self_: *mut whiteout_M2Model,
12914            data: *const u16,
12915            count: usize,
12916        );
12917        pub fn whiteout_m2_M2Model_get_textureWeightCombos_count(
12918            self_: *mut whiteout_M2Model,
12919        ) -> usize;
12920        pub fn whiteout_m2_M2Model_resize_textureWeightCombos(
12921            self_: *mut whiteout_M2Model,
12922            count: usize,
12923        );
12924        pub fn whiteout_m2_M2Model_get_textureWeightCombos_data(
12925            self_: *mut whiteout_M2Model,
12926        ) -> *const u16;
12927        pub fn whiteout_m2_M2Model_assign_textureWeightCombos(
12928            self_: *mut whiteout_M2Model,
12929            data: *const u16,
12930            count: usize,
12931        );
12932        pub fn whiteout_m2_M2Model_get_textureTransformCombos_count(
12933            self_: *mut whiteout_M2Model,
12934        ) -> usize;
12935        pub fn whiteout_m2_M2Model_resize_textureTransformCombos(
12936            self_: *mut whiteout_M2Model,
12937            count: usize,
12938        );
12939        pub fn whiteout_m2_M2Model_get_textureTransformCombos_data(
12940            self_: *mut whiteout_M2Model,
12941        ) -> *const u16;
12942        pub fn whiteout_m2_M2Model_assign_textureTransformCombos(
12943            self_: *mut whiteout_M2Model,
12944            data: *const u16,
12945            count: usize,
12946        );
12947        pub fn whiteout_m2_M2Model_get_bounding(
12948            self_: *mut whiteout_M2Model,
12949        ) -> *mut whiteout_M2Extent;
12950        pub fn whiteout_m2_M2Model_set_bounding(
12951            self_: *mut whiteout_M2Model,
12952            value: *const whiteout_M2Extent,
12953        );
12954        pub fn whiteout_m2_M2Model_get_collision(
12955            self_: *mut whiteout_M2Model,
12956        ) -> *mut whiteout_M2Extent;
12957        pub fn whiteout_m2_M2Model_set_collision(
12958            self_: *mut whiteout_M2Model,
12959            value: *const whiteout_M2Extent,
12960        );
12961        pub fn whiteout_m2_M2Model_get_collisionTriangleIndices_count(
12962            self_: *mut whiteout_M2Model,
12963        ) -> usize;
12964        pub fn whiteout_m2_M2Model_resize_collisionTriangleIndices(
12965            self_: *mut whiteout_M2Model,
12966            count: usize,
12967        );
12968        pub fn whiteout_m2_M2Model_get_collisionTriangleIndices_data(
12969            self_: *mut whiteout_M2Model,
12970        ) -> *const u16;
12971        pub fn whiteout_m2_M2Model_assign_collisionTriangleIndices(
12972            self_: *mut whiteout_M2Model,
12973            data: *const u16,
12974            count: usize,
12975        );
12976        pub fn whiteout_m2_M2Model_get_collisionVertices_count(
12977            self_: *mut whiteout_M2Model,
12978        ) -> usize;
12979        pub fn whiteout_m2_M2Model_resize_collisionVertices(
12980            self_: *mut whiteout_M2Model,
12981            count: usize,
12982        );
12983        pub fn whiteout_m2_M2Model_get_collisionVertices_data(
12984            self_: *mut whiteout_M2Model,
12985        ) -> *const f32;
12986        pub fn whiteout_m2_M2Model_assign_collisionVertices(
12987            self_: *mut whiteout_M2Model,
12988            data: *const f32,
12989            count: usize,
12990        );
12991        pub fn whiteout_m2_M2Model_get_collisionFaceNormals_count(
12992            self_: *mut whiteout_M2Model,
12993        ) -> usize;
12994        pub fn whiteout_m2_M2Model_resize_collisionFaceNormals(
12995            self_: *mut whiteout_M2Model,
12996            count: usize,
12997        );
12998        pub fn whiteout_m2_M2Model_get_collisionFaceNormals_data(
12999            self_: *mut whiteout_M2Model,
13000        ) -> *const f32;
13001        pub fn whiteout_m2_M2Model_assign_collisionFaceNormals(
13002            self_: *mut whiteout_M2Model,
13003            data: *const f32,
13004            count: usize,
13005        );
13006        pub fn whiteout_m2_M2Model_get_attachments_count(self_: *mut whiteout_M2Model) -> usize;
13007        pub fn whiteout_m2_M2Model_resize_attachments(self_: *mut whiteout_M2Model, count: usize);
13008        pub fn whiteout_m2_M2Model_get_attachments_at(
13009            self_: *mut whiteout_M2Model,
13010            index: usize,
13011        ) -> *mut whiteout_M2Attachment;
13012        pub fn whiteout_m2_M2Model_get_attachmentIndicesById_count(
13013            self_: *mut whiteout_M2Model,
13014        ) -> usize;
13015        pub fn whiteout_m2_M2Model_resize_attachmentIndicesById(
13016            self_: *mut whiteout_M2Model,
13017            count: usize,
13018        );
13019        pub fn whiteout_m2_M2Model_get_attachmentIndicesById_data(
13020            self_: *mut whiteout_M2Model,
13021        ) -> *const u16;
13022        pub fn whiteout_m2_M2Model_assign_attachmentIndicesById(
13023            self_: *mut whiteout_M2Model,
13024            data: *const u16,
13025            count: usize,
13026        );
13027        pub fn whiteout_m2_M2Model_get_events_count(self_: *mut whiteout_M2Model) -> usize;
13028        pub fn whiteout_m2_M2Model_resize_events(self_: *mut whiteout_M2Model, count: usize);
13029        pub fn whiteout_m2_M2Model_get_events_at(
13030            self_: *mut whiteout_M2Model,
13031            index: usize,
13032        ) -> *mut whiteout_M2Event;
13033        pub fn whiteout_m2_M2Model_get_lights_count(self_: *mut whiteout_M2Model) -> usize;
13034        pub fn whiteout_m2_M2Model_resize_lights(self_: *mut whiteout_M2Model, count: usize);
13035        pub fn whiteout_m2_M2Model_get_lights_at(
13036            self_: *mut whiteout_M2Model,
13037            index: usize,
13038        ) -> *mut whiteout_M2Light;
13039        pub fn whiteout_m2_M2Model_get_cameras_count(self_: *mut whiteout_M2Model) -> usize;
13040        pub fn whiteout_m2_M2Model_resize_cameras(self_: *mut whiteout_M2Model, count: usize);
13041        pub fn whiteout_m2_M2Model_get_cameras_at(
13042            self_: *mut whiteout_M2Model,
13043            index: usize,
13044        ) -> *mut whiteout_M2Camera;
13045        pub fn whiteout_m2_M2Model_get_cameraIndicesById_count(
13046            self_: *mut whiteout_M2Model,
13047        ) -> usize;
13048        pub fn whiteout_m2_M2Model_resize_cameraIndicesById(
13049            self_: *mut whiteout_M2Model,
13050            count: usize,
13051        );
13052        pub fn whiteout_m2_M2Model_get_cameraIndicesById_data(
13053            self_: *mut whiteout_M2Model,
13054        ) -> *const u16;
13055        pub fn whiteout_m2_M2Model_assign_cameraIndicesById(
13056            self_: *mut whiteout_M2Model,
13057            data: *const u16,
13058            count: usize,
13059        );
13060        pub fn whiteout_m2_M2Model_get_ribbonEmitters_count(self_: *mut whiteout_M2Model) -> usize;
13061        pub fn whiteout_m2_M2Model_resize_ribbonEmitters(
13062            self_: *mut whiteout_M2Model,
13063            count: usize,
13064        );
13065        pub fn whiteout_m2_M2Model_get_ribbonEmitters_at(
13066            self_: *mut whiteout_M2Model,
13067            index: usize,
13068        ) -> *mut whiteout_M2RibbonEmitter;
13069        pub fn whiteout_m2_M2Model_get_particleEmitters_count(
13070            self_: *mut whiteout_M2Model,
13071        ) -> usize;
13072        pub fn whiteout_m2_M2Model_resize_particleEmitters(
13073            self_: *mut whiteout_M2Model,
13074            count: usize,
13075        );
13076        pub fn whiteout_m2_M2Model_get_particleEmitters_at(
13077            self_: *mut whiteout_M2Model,
13078            index: usize,
13079        ) -> *mut whiteout_M2ParticleEmitter;
13080        pub fn whiteout_m2_M2Model_get_textureCombinerCombos_count(
13081            self_: *mut whiteout_M2Model,
13082        ) -> usize;
13083        pub fn whiteout_m2_M2Model_resize_textureCombinerCombos(
13084            self_: *mut whiteout_M2Model,
13085            count: usize,
13086        );
13087        pub fn whiteout_m2_M2Model_get_textureCombinerCombos_data(
13088            self_: *mut whiteout_M2Model,
13089        ) -> *const u16;
13090        pub fn whiteout_m2_M2Model_assign_textureCombinerCombos(
13091            self_: *mut whiteout_M2Model,
13092            data: *const u16,
13093            count: usize,
13094        );
13095        pub fn whiteout_m2_M2Model_get_texture_ids_count(self_: *mut whiteout_M2Model) -> usize;
13096        pub fn whiteout_m2_M2Model_resize_texture_ids(self_: *mut whiteout_M2Model, count: usize);
13097        pub fn whiteout_m2_M2Model_get_texture_ids_data(self_: *mut whiteout_M2Model)
13098            -> *const u32;
13099        pub fn whiteout_m2_M2Model_assign_texture_ids(
13100            self_: *mut whiteout_M2Model,
13101            data: *const u32,
13102            count: usize,
13103        );
13104        pub fn whiteout_m2_M2Model_get_parentSequenceReplacements_count(
13105            self_: *mut whiteout_M2Model,
13106        ) -> usize;
13107        pub fn whiteout_m2_M2Model_resize_parentSequenceReplacements(
13108            self_: *mut whiteout_M2Model,
13109            count: usize,
13110        );
13111        pub fn whiteout_m2_M2Model_get_parentSequenceReplacements_data(
13112            self_: *mut whiteout_M2Model,
13113        ) -> *const u16;
13114        pub fn whiteout_m2_M2Model_assign_parentSequenceReplacements(
13115            self_: *mut whiteout_M2Model,
13116            data: *const u16,
13117            count: usize,
13118        );
13119        pub fn whiteout_m2_M2Model_get_parentTextureWeights_count(
13120            self_: *mut whiteout_M2Model,
13121        ) -> usize;
13122        pub fn whiteout_m2_M2Model_resize_parentTextureWeights(
13123            self_: *mut whiteout_M2Model,
13124            count: usize,
13125        );
13126        pub fn whiteout_m2_M2Model_get_parentTextureWeights_at(
13127            self_: *mut whiteout_M2Model,
13128            index: usize,
13129        ) -> *mut whiteout_M2TextureWeight;
13130        pub fn whiteout_m2_M2Model_get_parentSequenceBounds_count(
13131            self_: *mut whiteout_M2Model,
13132        ) -> usize;
13133        pub fn whiteout_m2_M2Model_resize_parentSequenceBounds(
13134            self_: *mut whiteout_M2Model,
13135            count: usize,
13136        );
13137        pub fn whiteout_m2_M2Model_get_parentSequenceBounds_at(
13138            self_: *mut whiteout_M2Model,
13139            index: usize,
13140        ) -> *mut whiteout_M2Extent;
13141        pub fn whiteout_m2_M2Model_get_parentEventData_count(self_: *mut whiteout_M2Model)
13142            -> usize;
13143        pub fn whiteout_m2_M2Model_resize_parentEventData(
13144            self_: *mut whiteout_M2Model,
13145            count: usize,
13146        );
13147        pub fn whiteout_m2_M2Model_get_parentEventData_at(
13148            self_: *mut whiteout_M2Model,
13149            index: usize,
13150        ) -> *mut whiteout_M2AnimationTrackBase;
13151        pub fn whiteout_m2_M2Model_get_recursiveParticleModelIds_count(
13152            self_: *mut whiteout_M2Model,
13153        ) -> usize;
13154        pub fn whiteout_m2_M2Model_resize_recursiveParticleModelIds(
13155            self_: *mut whiteout_M2Model,
13156            count: usize,
13157        );
13158        pub fn whiteout_m2_M2Model_get_recursiveParticleModelIds_data(
13159            self_: *mut whiteout_M2Model,
13160        ) -> *const u32;
13161        pub fn whiteout_m2_M2Model_assign_recursiveParticleModelIds(
13162            self_: *mut whiteout_M2Model,
13163            data: *const u32,
13164            count: usize,
13165        );
13166        pub fn whiteout_m2_M2Model_get_geometryParticleModelIds_count(
13167            self_: *mut whiteout_M2Model,
13168        ) -> usize;
13169        pub fn whiteout_m2_M2Model_resize_geometryParticleModelIds(
13170            self_: *mut whiteout_M2Model,
13171            count: usize,
13172        );
13173        pub fn whiteout_m2_M2Model_get_geometryParticleModelIds_data(
13174            self_: *mut whiteout_M2Model,
13175        ) -> *const u32;
13176        pub fn whiteout_m2_M2Model_assign_geometryParticleModelIds(
13177            self_: *mut whiteout_M2Model,
13178            data: *const u32,
13179            count: usize,
13180        );
13181        pub fn whiteout_m2_M2Model_get_particleGeosets_count(self_: *mut whiteout_M2Model)
13182            -> usize;
13183        pub fn whiteout_m2_M2Model_resize_particleGeosets(
13184            self_: *mut whiteout_M2Model,
13185            count: usize,
13186        );
13187        pub fn whiteout_m2_M2Model_get_particleGeosets_at(
13188            self_: *mut whiteout_M2Model,
13189            index: usize,
13190        ) -> *mut whiteout_M2ParticleGeosetData;
13191        pub fn whiteout_m2_M2Model_get_physicsFileData_count(self_: *mut whiteout_M2Model)
13192            -> usize;
13193        pub fn whiteout_m2_M2Model_resize_physicsFileData(
13194            self_: *mut whiteout_M2Model,
13195            count: usize,
13196        );
13197        pub fn whiteout_m2_M2Model_get_physicsFileData_data(
13198            self_: *mut whiteout_M2Model,
13199        ) -> *const u8;
13200        pub fn whiteout_m2_M2Model_assign_physicsFileData(
13201            self_: *mut whiteout_M2Model,
13202            data: *const u8,
13203            count: usize,
13204        );
13205        pub fn whiteout_m2_M2Model_get_edgeFadeEntries_count(self_: *mut whiteout_M2Model)
13206            -> usize;
13207        pub fn whiteout_m2_M2Model_resize_edgeFadeEntries(
13208            self_: *mut whiteout_M2Model,
13209            count: usize,
13210        );
13211        pub fn whiteout_m2_M2Model_get_edgeFadeEntries_at(
13212            self_: *mut whiteout_M2Model,
13213            index: usize,
13214        ) -> *mut whiteout_M2EdgeFadeData;
13215        pub fn whiteout_m2_M2Model_get_nerfEntries_count(self_: *mut whiteout_M2Model) -> usize;
13216        pub fn whiteout_m2_M2Model_resize_nerfEntries(self_: *mut whiteout_M2Model, count: usize);
13217        pub fn whiteout_m2_M2Model_get_nerfEntries_at(
13218            self_: *mut whiteout_M2Model,
13219            index: usize,
13220        ) -> *mut whiteout_M2DistanceFadeData;
13221        pub fn whiteout_m2_M2Model_get_detailedLightEntries_count(
13222            self_: *mut whiteout_M2Model,
13223        ) -> usize;
13224        pub fn whiteout_m2_M2Model_resize_detailedLightEntries(
13225            self_: *mut whiteout_M2Model,
13226            count: usize,
13227        );
13228        pub fn whiteout_m2_M2Model_get_detailedLightEntries_at(
13229            self_: *mut whiteout_M2Model,
13230            index: usize,
13231        ) -> *mut whiteout_M2DetailedLightData;
13232        pub fn whiteout_m2_M2Model_get_debugOcclusionEntries_count(
13233            self_: *mut whiteout_M2Model,
13234        ) -> usize;
13235        pub fn whiteout_m2_M2Model_resize_debugOcclusionEntries(
13236            self_: *mut whiteout_M2Model,
13237            count: usize,
13238        );
13239        pub fn whiteout_m2_M2Model_get_debugOcclusionEntries_at(
13240            self_: *mut whiteout_M2Model,
13241            index: usize,
13242        ) -> *mut whiteout_M2DebugOcclusionData;
13243        pub fn whiteout_m2_M2Model_get_animFrameData_count(self_: *mut whiteout_M2Model) -> usize;
13244        pub fn whiteout_m2_M2Model_resize_animFrameData(self_: *mut whiteout_M2Model, count: usize);
13245        pub fn whiteout_m2_M2Model_get_animFrameData_data(
13246            self_: *mut whiteout_M2Model,
13247        ) -> *const u8;
13248        pub fn whiteout_m2_M2Model_assign_animFrameData(
13249            self_: *mut whiteout_M2Model,
13250            data: *const u8,
13251            count: usize,
13252        );
13253        pub fn whiteout_m2_M2Model_get_texturedLightEntries_count(
13254            self_: *mut whiteout_M2Model,
13255        ) -> usize;
13256        pub fn whiteout_m2_M2Model_resize_texturedLightEntries(
13257            self_: *mut whiteout_M2Model,
13258            count: usize,
13259        );
13260        pub fn whiteout_m2_M2Model_get_texturedLightEntries_at(
13261            self_: *mut whiteout_M2Model,
13262            index: usize,
13263        ) -> *mut whiteout_M2TexturedLightData;
13264        // Parser
13265        pub fn whiteout_m2_M2Parser_new() -> *mut whiteout_M2Parser;
13266        pub fn whiteout_m2_M2Parser_delete(self_: *mut whiteout_M2Parser);
13267        pub fn whiteout_m2_M2Parser_parse(
13268            self_: *mut whiteout_M2Parser,
13269            fs: *mut core::ffi::c_void,
13270            file_path: *const core::ffi::c_char,
13271        ) -> *mut whiteout_M2Model;
13272        pub fn whiteout_m2_M2Parser_parse_cascFs_buffer(
13273            self_: *mut whiteout_M2Parser,
13274            casc_fs: *const u8,
13275            casc_fs_size: usize,
13276            buffer: *const u8,
13277            buffer_size: usize,
13278        ) -> *mut whiteout_M2Model;
13279        pub fn whiteout_m2_M2Parser_hasIssues(self_: *mut whiteout_M2Parser) -> i32;
13280        pub fn whiteout_m2_M2Parser_getIssues_count(self_: *mut whiteout_M2Parser) -> usize;
13281        pub fn whiteout_m2_M2Parser_getIssues_at(
13282            self_: *mut whiteout_M2Parser,
13283            index: usize,
13284        ) -> RawCString;
13285        // WriteOptions
13286        pub fn whiteout_m2_M2WriteOptions_new() -> *mut whiteout_M2WriteOptions;
13287        pub fn whiteout_m2_M2WriteOptions_delete(self_: *mut whiteout_M2WriteOptions);
13288        pub fn whiteout_m2_M2WriteOptions_get_m2Version(self_: *mut whiteout_M2WriteOptions)
13289            -> u32;
13290        pub fn whiteout_m2_M2WriteOptions_set_m2Version(
13291            self_: *mut whiteout_M2WriteOptions,
13292            value: u32,
13293        );
13294        pub fn whiteout_m2_M2WriteOptions_get_emitSkeleton(
13295            self_: *mut whiteout_M2WriteOptions,
13296        ) -> i32;
13297        pub fn whiteout_m2_M2WriteOptions_set_emitSkeleton(
13298            self_: *mut whiteout_M2WriteOptions,
13299            value: i32,
13300        );
13301        pub fn whiteout_m2_M2WriteOptions_get_baseStem(
13302            self_: *mut whiteout_M2WriteOptions,
13303        ) -> RawCString;
13304        pub fn whiteout_m2_M2WriteOptions_set_baseStem(
13305            self_: *mut whiteout_M2WriteOptions,
13306            value: *const core::ffi::c_char,
13307        );
13308        // SerializeResult
13309        pub fn whiteout_m2_M2SerializeResult_new() -> *mut whiteout_M2SerializeResult;
13310        pub fn whiteout_m2_M2SerializeResult_delete(self_: *mut whiteout_M2SerializeResult);
13311        pub fn whiteout_m2_M2SerializeResult_get_m2Data_count(
13312            self_: *mut whiteout_M2SerializeResult,
13313        ) -> usize;
13314        pub fn whiteout_m2_M2SerializeResult_resize_m2Data(
13315            self_: *mut whiteout_M2SerializeResult,
13316            count: usize,
13317        );
13318        pub fn whiteout_m2_M2SerializeResult_get_m2Data_data(
13319            self_: *mut whiteout_M2SerializeResult,
13320        ) -> *const u8;
13321        pub fn whiteout_m2_M2SerializeResult_assign_m2Data(
13322            self_: *mut whiteout_M2SerializeResult,
13323            data: *const u8,
13324            count: usize,
13325        );
13326        // Writer
13327        pub fn whiteout_m2_M2Writer_new() -> *mut whiteout_M2Writer;
13328        pub fn whiteout_m2_M2Writer_new_options(
13329            _0: *mut core::ffi::c_void,
13330        ) -> *mut whiteout_M2Writer;
13331        pub fn whiteout_m2_M2Writer_delete(self_: *mut whiteout_M2Writer);
13332        pub fn whiteout_m2_M2Writer_write(
13333            self_: *mut whiteout_M2Writer,
13334            fs: *mut core::ffi::c_void,
13335            file_path: *const core::ffi::c_char,
13336            model: *mut whiteout_M2Model,
13337        );
13338        pub fn whiteout_m2_M2Writer_write_cascFs_model(
13339            self_: *mut whiteout_M2Writer,
13340            casc_fs: *mut core::ffi::c_void,
13341            model: *mut whiteout_M2Model,
13342        );
13343        pub fn whiteout_m2_M2Writer_write_model(
13344            self_: *mut whiteout_M2Writer,
13345            model: *mut whiteout_M2Model,
13346        ) -> *mut whiteout_M2SerializeResult;
13347        pub fn whiteout_m2_M2Writer_hasIssues(self_: *mut whiteout_M2Writer) -> i32;
13348        pub fn whiteout_m2_M2Writer_getIssues_count(self_: *mut whiteout_M2Writer) -> usize;
13349        pub fn whiteout_m2_M2Writer_getIssues_at(
13350            self_: *mut whiteout_M2Writer,
13351            index: usize,
13352        ) -> RawCString;
13353        // AnimationTrackVector3f
13354        pub fn whiteout_m2_M2AnimationTrackVector3f_new() -> *mut whiteout_M2AnimationTrackVector3f;
13355        pub fn whiteout_m2_M2AnimationTrackVector3f_delete(
13356            self_: *mut whiteout_M2AnimationTrackVector3f,
13357        );
13358        pub fn whiteout_m2_M2AnimationTrackVector3f_get_interpolationType(
13359            self_: *mut whiteout_M2AnimationTrackVector3f,
13360        ) -> i32;
13361        pub fn whiteout_m2_M2AnimationTrackVector3f_set_interpolationType(
13362            self_: *mut whiteout_M2AnimationTrackVector3f,
13363            value: i32,
13364        );
13365        pub fn whiteout_m2_M2AnimationTrackVector3f_get_globalSequenceId(
13366            self_: *mut whiteout_M2AnimationTrackVector3f,
13367        ) -> u16;
13368        pub fn whiteout_m2_M2AnimationTrackVector3f_set_globalSequenceId(
13369            self_: *mut whiteout_M2AnimationTrackVector3f,
13370            value: u16,
13371        );
13372        pub fn whiteout_m2_M2AnimationTrackVector3f_get_timestamps_count(
13373            self_: *mut whiteout_M2AnimationTrackVector3f,
13374        ) -> usize;
13375        pub fn whiteout_m2_M2AnimationTrackVector3f_get_timestamps_inner_count(
13376            self_: *mut whiteout_M2AnimationTrackVector3f,
13377            outer: usize,
13378        ) -> usize;
13379        pub fn whiteout_m2_M2AnimationTrackVector3f_resize_timestamps(
13380            self_: *mut whiteout_M2AnimationTrackVector3f,
13381            count: usize,
13382        );
13383        pub fn whiteout_m2_M2AnimationTrackVector3f_resize_timestamps_inner(
13384            self_: *mut whiteout_M2AnimationTrackVector3f,
13385            outer: usize,
13386            count: usize,
13387        );
13388        pub fn whiteout_m2_M2AnimationTrackVector3f_get_timestamps_inner_data(
13389            self_: *mut whiteout_M2AnimationTrackVector3f,
13390            outer: usize,
13391        ) -> *const u32;
13392        pub fn whiteout_m2_M2AnimationTrackVector3f_assign_timestamps_inner(
13393            self_: *mut whiteout_M2AnimationTrackVector3f,
13394            outer: usize,
13395            data: *const u32,
13396            count: usize,
13397        );
13398        pub fn whiteout_m2_M2AnimationTrackVector3f_get_values_count(
13399            self_: *mut whiteout_M2AnimationTrackVector3f,
13400        ) -> usize;
13401        pub fn whiteout_m2_M2AnimationTrackVector3f_get_values_inner_count(
13402            self_: *mut whiteout_M2AnimationTrackVector3f,
13403            outer: usize,
13404        ) -> usize;
13405        pub fn whiteout_m2_M2AnimationTrackVector3f_resize_values(
13406            self_: *mut whiteout_M2AnimationTrackVector3f,
13407            count: usize,
13408        );
13409        pub fn whiteout_m2_M2AnimationTrackVector3f_resize_values_inner(
13410            self_: *mut whiteout_M2AnimationTrackVector3f,
13411            outer: usize,
13412            count: usize,
13413        );
13414        pub fn whiteout_m2_M2AnimationTrackVector3f_get_values_inner_data(
13415            self_: *mut whiteout_M2AnimationTrackVector3f,
13416            outer: usize,
13417        ) -> *const f32;
13418        pub fn whiteout_m2_M2AnimationTrackVector3f_assign_values_inner(
13419            self_: *mut whiteout_M2AnimationTrackVector3f,
13420            outer: usize,
13421            data: *const f32,
13422            count: usize,
13423        );
13424        // AnimationTrackM2CompatQuaternion
13425        pub fn whiteout_m2_M2AnimationTrackM2CompatQuaternion_new(
13426        ) -> *mut whiteout_M2AnimationTrackM2CompatQuaternion;
13427        pub fn whiteout_m2_M2AnimationTrackM2CompatQuaternion_delete(
13428            self_: *mut whiteout_M2AnimationTrackM2CompatQuaternion,
13429        );
13430        pub fn whiteout_m2_M2AnimationTrackM2CompatQuaternion_get_interpolationType(
13431            self_: *mut whiteout_M2AnimationTrackM2CompatQuaternion,
13432        ) -> i32;
13433        pub fn whiteout_m2_M2AnimationTrackM2CompatQuaternion_set_interpolationType(
13434            self_: *mut whiteout_M2AnimationTrackM2CompatQuaternion,
13435            value: i32,
13436        );
13437        pub fn whiteout_m2_M2AnimationTrackM2CompatQuaternion_get_globalSequenceId(
13438            self_: *mut whiteout_M2AnimationTrackM2CompatQuaternion,
13439        ) -> u16;
13440        pub fn whiteout_m2_M2AnimationTrackM2CompatQuaternion_set_globalSequenceId(
13441            self_: *mut whiteout_M2AnimationTrackM2CompatQuaternion,
13442            value: u16,
13443        );
13444        pub fn whiteout_m2_M2AnimationTrackM2CompatQuaternion_get_timestamps_count(
13445            self_: *mut whiteout_M2AnimationTrackM2CompatQuaternion,
13446        ) -> usize;
13447        pub fn whiteout_m2_M2AnimationTrackM2CompatQuaternion_get_timestamps_inner_count(
13448            self_: *mut whiteout_M2AnimationTrackM2CompatQuaternion,
13449            outer: usize,
13450        ) -> usize;
13451        pub fn whiteout_m2_M2AnimationTrackM2CompatQuaternion_resize_timestamps(
13452            self_: *mut whiteout_M2AnimationTrackM2CompatQuaternion,
13453            count: usize,
13454        );
13455        pub fn whiteout_m2_M2AnimationTrackM2CompatQuaternion_resize_timestamps_inner(
13456            self_: *mut whiteout_M2AnimationTrackM2CompatQuaternion,
13457            outer: usize,
13458            count: usize,
13459        );
13460        pub fn whiteout_m2_M2AnimationTrackM2CompatQuaternion_get_timestamps_inner_data(
13461            self_: *mut whiteout_M2AnimationTrackM2CompatQuaternion,
13462            outer: usize,
13463        ) -> *const u32;
13464        pub fn whiteout_m2_M2AnimationTrackM2CompatQuaternion_assign_timestamps_inner(
13465            self_: *mut whiteout_M2AnimationTrackM2CompatQuaternion,
13466            outer: usize,
13467            data: *const u32,
13468            count: usize,
13469        );
13470        pub fn whiteout_m2_M2AnimationTrackM2CompatQuaternion_get_values_count(
13471            self_: *mut whiteout_M2AnimationTrackM2CompatQuaternion,
13472        ) -> usize;
13473        pub fn whiteout_m2_M2AnimationTrackM2CompatQuaternion_get_values_inner_count(
13474            self_: *mut whiteout_M2AnimationTrackM2CompatQuaternion,
13475            outer: usize,
13476        ) -> usize;
13477        pub fn whiteout_m2_M2AnimationTrackM2CompatQuaternion_resize_values(
13478            self_: *mut whiteout_M2AnimationTrackM2CompatQuaternion,
13479            count: usize,
13480        );
13481        pub fn whiteout_m2_M2AnimationTrackM2CompatQuaternion_resize_values_inner(
13482            self_: *mut whiteout_M2AnimationTrackM2CompatQuaternion,
13483            outer: usize,
13484            count: usize,
13485        );
13486        pub fn whiteout_m2_M2AnimationTrackM2CompatQuaternion_get_values_at(
13487            self_: *mut whiteout_M2AnimationTrackM2CompatQuaternion,
13488            outer: usize,
13489            inner: usize,
13490        ) -> *mut whiteout_M2CompatQuaternion;
13491        // AnimationTrackI16
13492        pub fn whiteout_m2_M2AnimationTrackI16_new() -> *mut whiteout_M2AnimationTrackI16;
13493        pub fn whiteout_m2_M2AnimationTrackI16_delete(self_: *mut whiteout_M2AnimationTrackI16);
13494        pub fn whiteout_m2_M2AnimationTrackI16_get_interpolationType(
13495            self_: *mut whiteout_M2AnimationTrackI16,
13496        ) -> i32;
13497        pub fn whiteout_m2_M2AnimationTrackI16_set_interpolationType(
13498            self_: *mut whiteout_M2AnimationTrackI16,
13499            value: i32,
13500        );
13501        pub fn whiteout_m2_M2AnimationTrackI16_get_globalSequenceId(
13502            self_: *mut whiteout_M2AnimationTrackI16,
13503        ) -> u16;
13504        pub fn whiteout_m2_M2AnimationTrackI16_set_globalSequenceId(
13505            self_: *mut whiteout_M2AnimationTrackI16,
13506            value: u16,
13507        );
13508        pub fn whiteout_m2_M2AnimationTrackI16_get_timestamps_count(
13509            self_: *mut whiteout_M2AnimationTrackI16,
13510        ) -> usize;
13511        pub fn whiteout_m2_M2AnimationTrackI16_get_timestamps_inner_count(
13512            self_: *mut whiteout_M2AnimationTrackI16,
13513            outer: usize,
13514        ) -> usize;
13515        pub fn whiteout_m2_M2AnimationTrackI16_resize_timestamps(
13516            self_: *mut whiteout_M2AnimationTrackI16,
13517            count: usize,
13518        );
13519        pub fn whiteout_m2_M2AnimationTrackI16_resize_timestamps_inner(
13520            self_: *mut whiteout_M2AnimationTrackI16,
13521            outer: usize,
13522            count: usize,
13523        );
13524        pub fn whiteout_m2_M2AnimationTrackI16_get_timestamps_inner_data(
13525            self_: *mut whiteout_M2AnimationTrackI16,
13526            outer: usize,
13527        ) -> *const u32;
13528        pub fn whiteout_m2_M2AnimationTrackI16_assign_timestamps_inner(
13529            self_: *mut whiteout_M2AnimationTrackI16,
13530            outer: usize,
13531            data: *const u32,
13532            count: usize,
13533        );
13534        pub fn whiteout_m2_M2AnimationTrackI16_get_values_count(
13535            self_: *mut whiteout_M2AnimationTrackI16,
13536        ) -> usize;
13537        pub fn whiteout_m2_M2AnimationTrackI16_get_values_inner_count(
13538            self_: *mut whiteout_M2AnimationTrackI16,
13539            outer: usize,
13540        ) -> usize;
13541        pub fn whiteout_m2_M2AnimationTrackI16_resize_values(
13542            self_: *mut whiteout_M2AnimationTrackI16,
13543            count: usize,
13544        );
13545        pub fn whiteout_m2_M2AnimationTrackI16_resize_values_inner(
13546            self_: *mut whiteout_M2AnimationTrackI16,
13547            outer: usize,
13548            count: usize,
13549        );
13550        pub fn whiteout_m2_M2AnimationTrackI16_get_values_inner_data(
13551            self_: *mut whiteout_M2AnimationTrackI16,
13552            outer: usize,
13553        ) -> *const i16;
13554        pub fn whiteout_m2_M2AnimationTrackI16_assign_values_inner(
13555            self_: *mut whiteout_M2AnimationTrackI16,
13556            outer: usize,
13557            data: *const i16,
13558            count: usize,
13559        );
13560        // AnimationTrackF32
13561        pub fn whiteout_m2_M2AnimationTrackF32_new() -> *mut whiteout_M2AnimationTrackF32;
13562        pub fn whiteout_m2_M2AnimationTrackF32_delete(self_: *mut whiteout_M2AnimationTrackF32);
13563        pub fn whiteout_m2_M2AnimationTrackF32_get_interpolationType(
13564            self_: *mut whiteout_M2AnimationTrackF32,
13565        ) -> i32;
13566        pub fn whiteout_m2_M2AnimationTrackF32_set_interpolationType(
13567            self_: *mut whiteout_M2AnimationTrackF32,
13568            value: i32,
13569        );
13570        pub fn whiteout_m2_M2AnimationTrackF32_get_globalSequenceId(
13571            self_: *mut whiteout_M2AnimationTrackF32,
13572        ) -> u16;
13573        pub fn whiteout_m2_M2AnimationTrackF32_set_globalSequenceId(
13574            self_: *mut whiteout_M2AnimationTrackF32,
13575            value: u16,
13576        );
13577        pub fn whiteout_m2_M2AnimationTrackF32_get_timestamps_count(
13578            self_: *mut whiteout_M2AnimationTrackF32,
13579        ) -> usize;
13580        pub fn whiteout_m2_M2AnimationTrackF32_get_timestamps_inner_count(
13581            self_: *mut whiteout_M2AnimationTrackF32,
13582            outer: usize,
13583        ) -> usize;
13584        pub fn whiteout_m2_M2AnimationTrackF32_resize_timestamps(
13585            self_: *mut whiteout_M2AnimationTrackF32,
13586            count: usize,
13587        );
13588        pub fn whiteout_m2_M2AnimationTrackF32_resize_timestamps_inner(
13589            self_: *mut whiteout_M2AnimationTrackF32,
13590            outer: usize,
13591            count: usize,
13592        );
13593        pub fn whiteout_m2_M2AnimationTrackF32_get_timestamps_inner_data(
13594            self_: *mut whiteout_M2AnimationTrackF32,
13595            outer: usize,
13596        ) -> *const u32;
13597        pub fn whiteout_m2_M2AnimationTrackF32_assign_timestamps_inner(
13598            self_: *mut whiteout_M2AnimationTrackF32,
13599            outer: usize,
13600            data: *const u32,
13601            count: usize,
13602        );
13603        pub fn whiteout_m2_M2AnimationTrackF32_get_values_count(
13604            self_: *mut whiteout_M2AnimationTrackF32,
13605        ) -> usize;
13606        pub fn whiteout_m2_M2AnimationTrackF32_get_values_inner_count(
13607            self_: *mut whiteout_M2AnimationTrackF32,
13608            outer: usize,
13609        ) -> usize;
13610        pub fn whiteout_m2_M2AnimationTrackF32_resize_values(
13611            self_: *mut whiteout_M2AnimationTrackF32,
13612            count: usize,
13613        );
13614        pub fn whiteout_m2_M2AnimationTrackF32_resize_values_inner(
13615            self_: *mut whiteout_M2AnimationTrackF32,
13616            outer: usize,
13617            count: usize,
13618        );
13619        pub fn whiteout_m2_M2AnimationTrackF32_get_values_inner_data(
13620            self_: *mut whiteout_M2AnimationTrackF32,
13621            outer: usize,
13622        ) -> *const f32;
13623        pub fn whiteout_m2_M2AnimationTrackF32_assign_values_inner(
13624            self_: *mut whiteout_M2AnimationTrackF32,
13625            outer: usize,
13626            data: *const f32,
13627            count: usize,
13628        );
13629        // AnimationTrackU8
13630        pub fn whiteout_m2_M2AnimationTrackU8_new() -> *mut whiteout_M2AnimationTrackU8;
13631        pub fn whiteout_m2_M2AnimationTrackU8_delete(self_: *mut whiteout_M2AnimationTrackU8);
13632        pub fn whiteout_m2_M2AnimationTrackU8_get_interpolationType(
13633            self_: *mut whiteout_M2AnimationTrackU8,
13634        ) -> i32;
13635        pub fn whiteout_m2_M2AnimationTrackU8_set_interpolationType(
13636            self_: *mut whiteout_M2AnimationTrackU8,
13637            value: i32,
13638        );
13639        pub fn whiteout_m2_M2AnimationTrackU8_get_globalSequenceId(
13640            self_: *mut whiteout_M2AnimationTrackU8,
13641        ) -> u16;
13642        pub fn whiteout_m2_M2AnimationTrackU8_set_globalSequenceId(
13643            self_: *mut whiteout_M2AnimationTrackU8,
13644            value: u16,
13645        );
13646        pub fn whiteout_m2_M2AnimationTrackU8_get_timestamps_count(
13647            self_: *mut whiteout_M2AnimationTrackU8,
13648        ) -> usize;
13649        pub fn whiteout_m2_M2AnimationTrackU8_get_timestamps_inner_count(
13650            self_: *mut whiteout_M2AnimationTrackU8,
13651            outer: usize,
13652        ) -> usize;
13653        pub fn whiteout_m2_M2AnimationTrackU8_resize_timestamps(
13654            self_: *mut whiteout_M2AnimationTrackU8,
13655            count: usize,
13656        );
13657        pub fn whiteout_m2_M2AnimationTrackU8_resize_timestamps_inner(
13658            self_: *mut whiteout_M2AnimationTrackU8,
13659            outer: usize,
13660            count: usize,
13661        );
13662        pub fn whiteout_m2_M2AnimationTrackU8_get_timestamps_inner_data(
13663            self_: *mut whiteout_M2AnimationTrackU8,
13664            outer: usize,
13665        ) -> *const u32;
13666        pub fn whiteout_m2_M2AnimationTrackU8_assign_timestamps_inner(
13667            self_: *mut whiteout_M2AnimationTrackU8,
13668            outer: usize,
13669            data: *const u32,
13670            count: usize,
13671        );
13672        pub fn whiteout_m2_M2AnimationTrackU8_get_values_count(
13673            self_: *mut whiteout_M2AnimationTrackU8,
13674        ) -> usize;
13675        pub fn whiteout_m2_M2AnimationTrackU8_get_values_inner_count(
13676            self_: *mut whiteout_M2AnimationTrackU8,
13677            outer: usize,
13678        ) -> usize;
13679        pub fn whiteout_m2_M2AnimationTrackU8_resize_values(
13680            self_: *mut whiteout_M2AnimationTrackU8,
13681            count: usize,
13682        );
13683        pub fn whiteout_m2_M2AnimationTrackU8_resize_values_inner(
13684            self_: *mut whiteout_M2AnimationTrackU8,
13685            outer: usize,
13686            count: usize,
13687        );
13688        pub fn whiteout_m2_M2AnimationTrackU8_get_values_inner_data(
13689            self_: *mut whiteout_M2AnimationTrackU8,
13690            outer: usize,
13691        ) -> *const u8;
13692        pub fn whiteout_m2_M2AnimationTrackU8_assign_values_inner(
13693            self_: *mut whiteout_M2AnimationTrackU8,
13694            outer: usize,
13695            data: *const u8,
13696            count: usize,
13697        );
13698        // AnimationTrackM2CameraSpline
13699        pub fn whiteout_m2_M2AnimationTrackM2CameraSpline_new(
13700        ) -> *mut whiteout_M2AnimationTrackM2CameraSpline;
13701        pub fn whiteout_m2_M2AnimationTrackM2CameraSpline_delete(
13702            self_: *mut whiteout_M2AnimationTrackM2CameraSpline,
13703        );
13704        pub fn whiteout_m2_M2AnimationTrackM2CameraSpline_get_interpolationType(
13705            self_: *mut whiteout_M2AnimationTrackM2CameraSpline,
13706        ) -> i32;
13707        pub fn whiteout_m2_M2AnimationTrackM2CameraSpline_set_interpolationType(
13708            self_: *mut whiteout_M2AnimationTrackM2CameraSpline,
13709            value: i32,
13710        );
13711        pub fn whiteout_m2_M2AnimationTrackM2CameraSpline_get_globalSequenceId(
13712            self_: *mut whiteout_M2AnimationTrackM2CameraSpline,
13713        ) -> u16;
13714        pub fn whiteout_m2_M2AnimationTrackM2CameraSpline_set_globalSequenceId(
13715            self_: *mut whiteout_M2AnimationTrackM2CameraSpline,
13716            value: u16,
13717        );
13718        pub fn whiteout_m2_M2AnimationTrackM2CameraSpline_get_timestamps_count(
13719            self_: *mut whiteout_M2AnimationTrackM2CameraSpline,
13720        ) -> usize;
13721        pub fn whiteout_m2_M2AnimationTrackM2CameraSpline_get_timestamps_inner_count(
13722            self_: *mut whiteout_M2AnimationTrackM2CameraSpline,
13723            outer: usize,
13724        ) -> usize;
13725        pub fn whiteout_m2_M2AnimationTrackM2CameraSpline_resize_timestamps(
13726            self_: *mut whiteout_M2AnimationTrackM2CameraSpline,
13727            count: usize,
13728        );
13729        pub fn whiteout_m2_M2AnimationTrackM2CameraSpline_resize_timestamps_inner(
13730            self_: *mut whiteout_M2AnimationTrackM2CameraSpline,
13731            outer: usize,
13732            count: usize,
13733        );
13734        pub fn whiteout_m2_M2AnimationTrackM2CameraSpline_get_timestamps_inner_data(
13735            self_: *mut whiteout_M2AnimationTrackM2CameraSpline,
13736            outer: usize,
13737        ) -> *const u32;
13738        pub fn whiteout_m2_M2AnimationTrackM2CameraSpline_assign_timestamps_inner(
13739            self_: *mut whiteout_M2AnimationTrackM2CameraSpline,
13740            outer: usize,
13741            data: *const u32,
13742            count: usize,
13743        );
13744        pub fn whiteout_m2_M2AnimationTrackM2CameraSpline_get_values_count(
13745            self_: *mut whiteout_M2AnimationTrackM2CameraSpline,
13746        ) -> usize;
13747        pub fn whiteout_m2_M2AnimationTrackM2CameraSpline_get_values_inner_count(
13748            self_: *mut whiteout_M2AnimationTrackM2CameraSpline,
13749            outer: usize,
13750        ) -> usize;
13751        pub fn whiteout_m2_M2AnimationTrackM2CameraSpline_resize_values(
13752            self_: *mut whiteout_M2AnimationTrackM2CameraSpline,
13753            count: usize,
13754        );
13755        pub fn whiteout_m2_M2AnimationTrackM2CameraSpline_resize_values_inner(
13756            self_: *mut whiteout_M2AnimationTrackM2CameraSpline,
13757            outer: usize,
13758            count: usize,
13759        );
13760        pub fn whiteout_m2_M2AnimationTrackM2CameraSpline_get_values_at(
13761            self_: *mut whiteout_M2AnimationTrackM2CameraSpline,
13762            outer: usize,
13763            inner: usize,
13764        ) -> *mut whiteout_M2CameraSpline;
13765        // AnimationTrackU16
13766        pub fn whiteout_m2_M2AnimationTrackU16_new() -> *mut whiteout_M2AnimationTrackU16;
13767        pub fn whiteout_m2_M2AnimationTrackU16_delete(self_: *mut whiteout_M2AnimationTrackU16);
13768        pub fn whiteout_m2_M2AnimationTrackU16_get_interpolationType(
13769            self_: *mut whiteout_M2AnimationTrackU16,
13770        ) -> i32;
13771        pub fn whiteout_m2_M2AnimationTrackU16_set_interpolationType(
13772            self_: *mut whiteout_M2AnimationTrackU16,
13773            value: i32,
13774        );
13775        pub fn whiteout_m2_M2AnimationTrackU16_get_globalSequenceId(
13776            self_: *mut whiteout_M2AnimationTrackU16,
13777        ) -> u16;
13778        pub fn whiteout_m2_M2AnimationTrackU16_set_globalSequenceId(
13779            self_: *mut whiteout_M2AnimationTrackU16,
13780            value: u16,
13781        );
13782        pub fn whiteout_m2_M2AnimationTrackU16_get_timestamps_count(
13783            self_: *mut whiteout_M2AnimationTrackU16,
13784        ) -> usize;
13785        pub fn whiteout_m2_M2AnimationTrackU16_get_timestamps_inner_count(
13786            self_: *mut whiteout_M2AnimationTrackU16,
13787            outer: usize,
13788        ) -> usize;
13789        pub fn whiteout_m2_M2AnimationTrackU16_resize_timestamps(
13790            self_: *mut whiteout_M2AnimationTrackU16,
13791            count: usize,
13792        );
13793        pub fn whiteout_m2_M2AnimationTrackU16_resize_timestamps_inner(
13794            self_: *mut whiteout_M2AnimationTrackU16,
13795            outer: usize,
13796            count: usize,
13797        );
13798        pub fn whiteout_m2_M2AnimationTrackU16_get_timestamps_inner_data(
13799            self_: *mut whiteout_M2AnimationTrackU16,
13800            outer: usize,
13801        ) -> *const u32;
13802        pub fn whiteout_m2_M2AnimationTrackU16_assign_timestamps_inner(
13803            self_: *mut whiteout_M2AnimationTrackU16,
13804            outer: usize,
13805            data: *const u32,
13806            count: usize,
13807        );
13808        pub fn whiteout_m2_M2AnimationTrackU16_get_values_count(
13809            self_: *mut whiteout_M2AnimationTrackU16,
13810        ) -> usize;
13811        pub fn whiteout_m2_M2AnimationTrackU16_get_values_inner_count(
13812            self_: *mut whiteout_M2AnimationTrackU16,
13813            outer: usize,
13814        ) -> usize;
13815        pub fn whiteout_m2_M2AnimationTrackU16_resize_values(
13816            self_: *mut whiteout_M2AnimationTrackU16,
13817            count: usize,
13818        );
13819        pub fn whiteout_m2_M2AnimationTrackU16_resize_values_inner(
13820            self_: *mut whiteout_M2AnimationTrackU16,
13821            outer: usize,
13822            count: usize,
13823        );
13824        pub fn whiteout_m2_M2AnimationTrackU16_get_values_inner_data(
13825            self_: *mut whiteout_M2AnimationTrackU16,
13826            outer: usize,
13827        ) -> *const u16;
13828        pub fn whiteout_m2_M2AnimationTrackU16_assign_values_inner(
13829            self_: *mut whiteout_M2AnimationTrackU16,
13830            outer: usize,
13831            data: *const u16,
13832            count: usize,
13833        );
13834        // ParticleAnimationTrackVector3f
13835        pub fn whiteout_m2_M2ParticleAnimationTrackVector3f_new(
13836        ) -> *mut whiteout_M2ParticleAnimationTrackVector3f;
13837        pub fn whiteout_m2_M2ParticleAnimationTrackVector3f_delete(
13838            self_: *mut whiteout_M2ParticleAnimationTrackVector3f,
13839        );
13840        pub fn whiteout_m2_M2ParticleAnimationTrackVector3f_get_values_count(
13841            self_: *mut whiteout_M2ParticleAnimationTrackVector3f,
13842        ) -> usize;
13843        pub fn whiteout_m2_M2ParticleAnimationTrackVector3f_resize_values(
13844            self_: *mut whiteout_M2ParticleAnimationTrackVector3f,
13845            count: usize,
13846        );
13847        pub fn whiteout_m2_M2ParticleAnimationTrackVector3f_get_values_data(
13848            self_: *mut whiteout_M2ParticleAnimationTrackVector3f,
13849        ) -> *const f32;
13850        pub fn whiteout_m2_M2ParticleAnimationTrackVector3f_assign_values(
13851            self_: *mut whiteout_M2ParticleAnimationTrackVector3f,
13852            data: *const f32,
13853            count: usize,
13854        );
13855        // ParticleAnimationTrackVector2f
13856        pub fn whiteout_m2_M2ParticleAnimationTrackVector2f_new(
13857        ) -> *mut whiteout_M2ParticleAnimationTrackVector2f;
13858        pub fn whiteout_m2_M2ParticleAnimationTrackVector2f_delete(
13859            self_: *mut whiteout_M2ParticleAnimationTrackVector2f,
13860        );
13861        pub fn whiteout_m2_M2ParticleAnimationTrackVector2f_get_values_count(
13862            self_: *mut whiteout_M2ParticleAnimationTrackVector2f,
13863        ) -> usize;
13864        pub fn whiteout_m2_M2ParticleAnimationTrackVector2f_resize_values(
13865            self_: *mut whiteout_M2ParticleAnimationTrackVector2f,
13866            count: usize,
13867        );
13868        pub fn whiteout_m2_M2ParticleAnimationTrackVector2f_get_values_data(
13869            self_: *mut whiteout_M2ParticleAnimationTrackVector2f,
13870        ) -> *const f32;
13871        pub fn whiteout_m2_M2ParticleAnimationTrackVector2f_assign_values(
13872            self_: *mut whiteout_M2ParticleAnimationTrackVector2f,
13873            data: *const f32,
13874            count: usize,
13875        );
13876    }
13877}