Skip to main content

whiteout/
m3.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 m3 --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/// Vertex format flags determining vertex buffer layout
14///
15/// These bitmask flags control the per-vertex data layout in the U8__ vertex blob. The vertex stride is: 24 + (hasColor ? 4 : 0) + (numUVs * 4) + 4 bytes.
16/// Bit flags. Combine with `|`, test with [`VertexFormatFlag::contains`].
17#[derive(Clone, Copy, PartialEq, Eq, Hash, Default)]
18pub struct VertexFormatFlag(pub i32);
19
20impl VertexFormatFlag {
21    pub const NONE: Self = Self(0);
22    /// Bit 10 (1-based): Has vertex color (adds 4 bytes)
23    pub const VERTEX_COLOR: Self = Self(512);
24    /// Bit 18 (1-based): Has UV layer 1 (adds 4 bytes)
25    pub const UV_1: Self = Self(131072);
26    /// Bit 19 (1-based): Has UV layer 2 (adds 4 bytes)
27    pub const UV_2: Self = Self(262144);
28    /// Bit 20 (1-based): Has UV layer 3 (adds 4 bytes)
29    pub const UV_3: Self = Self(524288);
30    /// Bit 21 (1-based): Has UV layer 4 (adds 4 bytes)
31    pub const UV_4: Self = Self(1048576);
32    /// Bit 30 (1-based): Has UV layer 5 (adds 4 bytes)
33    pub const UV_5: Self = Self(536870912);
34
35    #[inline]
36    pub const fn contains(self, other: Self) -> bool {
37        (self.0 & other.0) == other.0
38    }
39
40    #[inline]
41    pub const fn is_empty(self) -> bool {
42        self.0 == 0
43    }
44}
45
46impl core::ops::BitOr for VertexFormatFlag {
47    type Output = Self;
48    #[inline]
49    fn bitor(self, rhs: Self) -> Self {
50        Self(self.0 | rhs.0)
51    }
52}
53
54impl core::ops::BitAnd for VertexFormatFlag {
55    type Output = Self;
56    #[inline]
57    fn bitand(self, rhs: Self) -> Self {
58        Self(self.0 & rhs.0)
59    }
60}
61
62impl core::ops::Not for VertexFormatFlag {
63    type Output = Self;
64    #[inline]
65    fn not(self) -> Self {
66        Self(!self.0)
67    }
68}
69
70impl core::fmt::Debug for VertexFormatFlag {
71    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
72        write!(f, "VertexFormatFlag({:#x})", self.0)
73    }
74}
75
76/// Identifies which material array a MATM entry references
77#[repr(i32)]
78#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
79pub enum MaterialType {
80    /// MAT_ — Standard material
81    Standard = 1,
82    /// DIS_ — Displacement material
83    Displacement = 2,
84    /// CMP_ — Composite material
85    Composite = 3,
86    /// TER_ — Terrain material
87    Terrain = 4,
88    /// VOL_ — Volume material
89    Volume = 5,
90    /// VON_ — Volume noise material
91    VolumeNoise = 6,
92    /// CREP — Creep material
93    Creep = 7,
94    /// HAI_ — Hair material (defunct)
95    Hair = 8,
96    /// STBM — Splat terrain bake material
97    SplatTerrainBake = 9,
98    /// REF_ — Reflection material
99    Reflection = 10,
100    /// LFLR — Lens flare material
101    LensFlare = 11,
102    /// MADD — Buffer / additional material data
103    BufferMaterial = 12,
104}
105
106impl TryFrom<i32> for MaterialType {
107    type Error = crate::Error;
108    fn try_from(v: i32) -> Result<Self, crate::Error> {
109        match v {
110            1 => Ok(MaterialType::Standard),
111            2 => Ok(MaterialType::Displacement),
112            3 => Ok(MaterialType::Composite),
113            4 => Ok(MaterialType::Terrain),
114            5 => Ok(MaterialType::Volume),
115            6 => Ok(MaterialType::VolumeNoise),
116            7 => Ok(MaterialType::Creep),
117            8 => Ok(MaterialType::Hair),
118            9 => Ok(MaterialType::SplatTerrainBake),
119            10 => Ok(MaterialType::Reflection),
120            11 => Ok(MaterialType::LensFlare),
121            12 => Ok(MaterialType::BufferMaterial),
122            other => Err(crate::Error::UnknownEnum {
123                name: "MaterialType",
124                value: other,
125            }),
126        }
127    }
128}
129
130/// Light source type (LITE)
131#[repr(i32)]
132#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
133pub enum LightType {
134    /// Point light (omnidirectional)
135    Omni = 0,
136    /// Spot light (cone)
137    Spot = 1,
138    /// Directional light (infinite distance)
139    Directional = 2,
140}
141
142impl TryFrom<i32> for LightType {
143    type Error = crate::Error;
144    fn try_from(v: i32) -> Result<Self, crate::Error> {
145        match v {
146            0 => Ok(LightType::Omni),
147            1 => Ok(LightType::Spot),
148            2 => Ok(LightType::Directional),
149            other => Err(crate::Error::UnknownEnum {
150                name: "LightType",
151                value: other,
152            }),
153        }
154    }
155}
156
157/// Physics collision shape type (PHSH)
158#[repr(i32)]
159#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
160pub enum PhysicsShapeType {
161    /// Box (half-extents in shapeDimensions)
162    Box = 0,
163    /// Sphere (radius in shapeDimensions.x)
164    Sphere = 1,
165    /// Capsule (radius + height)
166    Capsule = 2,
167    /// Cylinder (radius + height)
168    Cylinder = 3,
169    /// Convex hull (vertex/half-edge data)
170    ConvexHull = 4,
171    /// Triangle mesh (face/edge/normal data)
172    Mesh = 5,
173}
174
175impl TryFrom<i32> for PhysicsShapeType {
176    type Error = crate::Error;
177    fn try_from(v: i32) -> Result<Self, crate::Error> {
178        match v {
179            0 => Ok(PhysicsShapeType::Box),
180            1 => Ok(PhysicsShapeType::Sphere),
181            2 => Ok(PhysicsShapeType::Capsule),
182            3 => Ok(PhysicsShapeType::Cylinder),
183            4 => Ok(PhysicsShapeType::ConvexHull),
184            5 => Ok(PhysicsShapeType::Mesh),
185            other => Err(crate::Error::UnknownEnum {
186                name: "PhysicsShapeType",
187                value: other,
188            }),
189        }
190    }
191}
192
193/// Hit-test shape type (SSGS / ATVL), same semantics as PhysicsShapeType but u32
194#[repr(i32)]
195#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
196pub enum HitTestShapeType {
197    Box = 0,
198    Sphere = 1,
199    Capsule = 2,
200    Cylinder = 3,
201    Mesh = 4,
202}
203
204impl TryFrom<i32> for HitTestShapeType {
205    type Error = crate::Error;
206    fn try_from(v: i32) -> Result<Self, crate::Error> {
207        match v {
208            0 => Ok(HitTestShapeType::Box),
209            1 => Ok(HitTestShapeType::Sphere),
210            2 => Ok(HitTestShapeType::Capsule),
211            3 => Ok(HitTestShapeType::Cylinder),
212            4 => Ok(HitTestShapeType::Mesh),
213            other => Err(crate::Error::UnknownEnum {
214                name: "HitTestShapeType",
215                value: other,
216            }),
217        }
218    }
219}
220
221/// Particle / ribbon emitter shape (PAR_ / RIB_)
222#[repr(i32)]
223#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
224pub enum EmitterShape {
225    /// Emit from a single point
226    Point = 0,
227    /// Emit from a rectangular plane
228    Plane = 1,
229    /// Emit from a sphere surface/volume
230    Sphere = 2,
231    /// Emit from a box volume
232    Box = 3,
233    /// Emit from a cylinder
234    Cylinder = 4,
235    /// Emit from a disc
236    Disc = 5,
237    /// Emit from a spline path, splineLineData
238    Spline = 6,
239    /// Emit from mesh surface, mesh region indices in shapeRegions
240    Mesh = 7,
241}
242
243impl TryFrom<i32> for EmitterShape {
244    type Error = crate::Error;
245    fn try_from(v: i32) -> Result<Self, crate::Error> {
246        match v {
247            0 => Ok(EmitterShape::Point),
248            1 => Ok(EmitterShape::Plane),
249            2 => Ok(EmitterShape::Sphere),
250            3 => Ok(EmitterShape::Box),
251            4 => Ok(EmitterShape::Cylinder),
252            5 => Ok(EmitterShape::Disc),
253            6 => Ok(EmitterShape::Spline),
254            7 => Ok(EmitterShape::Mesh),
255            other => Err(crate::Error::UnknownEnum {
256                name: "EmitterShape",
257                value: other,
258            }),
259        }
260    }
261}
262
263/// Particle visual / billboard type (maps to b_iInstanceType in Particle.fx)
264#[repr(i32)]
265#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
266pub enum ParticleInstanceType {
267    /// Camera-facing billboard quad
268    Billboard = 0,
269    /// Velocity-stretched quad
270    Tail = 1,
271    /// Quad oriented along instantaneous velocity
272    FaceTravelDir = 2,
273    /// Quad oriented along a fixed world direction
274    FaceWorldDir = 3,
275    /// Billboard locked to a single rotation axis
276    SingleAxis = 4,
277    /// Quad projected onto terrain normal
278    TerrainOriented = 5,
279    /// Terrain-oriented + velocity-stretched
280    TerrainDirOriented = 6,
281    /// Quad uses the emitter bone's orientation
282    EmitterOriented = 7,
283    /// Quad oriented by physics simulation
284    PhysicsOriented = 8,
285    /// Stretch between spawn origin and current position
286    Pinned = 9,
287    /// Like Tail but offset by one tail-length
288    Trail = 10,
289}
290
291impl TryFrom<i32> for ParticleInstanceType {
292    type Error = crate::Error;
293    fn try_from(v: i32) -> Result<Self, crate::Error> {
294        match v {
295            0 => Ok(ParticleInstanceType::Billboard),
296            1 => Ok(ParticleInstanceType::Tail),
297            2 => Ok(ParticleInstanceType::FaceTravelDir),
298            3 => Ok(ParticleInstanceType::FaceWorldDir),
299            4 => Ok(ParticleInstanceType::SingleAxis),
300            5 => Ok(ParticleInstanceType::TerrainOriented),
301            6 => Ok(ParticleInstanceType::TerrainDirOriented),
302            7 => Ok(ParticleInstanceType::EmitterOriented),
303            8 => Ok(ParticleInstanceType::PhysicsOriented),
304            9 => Ok(ParticleInstanceType::Pinned),
305            10 => Ok(ParticleInstanceType::Trail),
306            other => Err(crate::Error::UnknownEnum {
307                name: "ParticleInstanceType",
308                value: other,
309            }),
310        }
311    }
312}
313
314/// Force influence type (FOR_)
315#[repr(i32)]
316#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
317pub enum ForceType {
318    /// Radial force (outward from center)
319    Radial = 0,
320    /// Wind force (directional)
321    Wind = 1,
322    /// Explosion force (impulse)
323    Explosion = 2,
324}
325
326impl TryFrom<i32> for ForceType {
327    type Error = crate::Error;
328    fn try_from(v: i32) -> Result<Self, crate::Error> {
329        match v {
330            0 => Ok(ForceType::Radial),
331            1 => Ok(ForceType::Wind),
332            2 => Ok(ForceType::Explosion),
333            other => Err(crate::Error::UnknownEnum {
334                name: "ForceType",
335                value: other,
336            }),
337        }
338    }
339}
340
341/// Influence volume shape for a force (FOR_)
342#[repr(i32)]
343#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
344pub enum ForceShape {
345    /// Spherical influence volume
346    Sphere = 0,
347    /// Cylindrical influence volume
348    Cylinder = 1,
349    /// Box influence volume
350    Box = 2,
351    /// Hemispherical influence volume
352    Hemisphere = 3,
353}
354
355impl TryFrom<i32> for ForceShape {
356    type Error = crate::Error;
357    fn try_from(v: i32) -> Result<Self, crate::Error> {
358        match v {
359            0 => Ok(ForceShape::Sphere),
360            1 => Ok(ForceShape::Cylinder),
361            2 => Ok(ForceShape::Box),
362            3 => Ok(ForceShape::Hemisphere),
363            other => Err(crate::Error::UnknownEnum {
364                name: "ForceShape",
365                value: other,
366            }),
367        }
368    }
369}
370
371/// Ribbon cross-section type (maps to b_iRibbonType in Ribbon.fx)
372#[repr(i32)]
373#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
374pub enum RibbonType {
375    /// Camera-facing ribbon strip
376    Billboard = 0,
377    /// Flat/planar ribbon strip
378    Planar = 1,
379    /// Cylindrical cross-section
380    Cylinder = 2,
381    /// Star-shaped cross-section
382    Star = 3,
383}
384
385impl TryFrom<i32> for RibbonType {
386    type Error = crate::Error;
387    fn try_from(v: i32) -> Result<Self, crate::Error> {
388        match v {
389            0 => Ok(RibbonType::Billboard),
390            1 => Ok(RibbonType::Planar),
391            2 => Ok(RibbonType::Cylinder),
392            3 => Ok(RibbonType::Star),
393            other => Err(crate::Error::UnknownEnum {
394                name: "RibbonType",
395                value: other,
396            }),
397        }
398    }
399}
400
401/// Projector / decal projection type (PROJ)
402#[repr(i32)]
403#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
404pub enum ProjectionType {
405    /// Orthographic projection
406    Orthographic = 0,
407    /// Perspective projection
408    Perspective = 1,
409}
410
411impl TryFrom<i32> for ProjectionType {
412    type Error = crate::Error;
413    fn try_from(v: i32) -> Result<Self, crate::Error> {
414        match v {
415            0 => Ok(ProjectionType::Orthographic),
416            1 => Ok(ProjectionType::Perspective),
417            other => Err(crate::Error::UnknownEnum {
418                name: "ProjectionType",
419                value: other,
420            }),
421        }
422    }
423}
424
425/// Volume shape type (VOL_ / VON_)
426#[repr(i32)]
427#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
428pub enum VolumeType {
429    Box = 0,
430    Sphere = 1,
431    Capsule = 2,
432}
433
434impl TryFrom<i32> for VolumeType {
435    type Error = crate::Error;
436    fn try_from(v: i32) -> Result<Self, crate::Error> {
437        match v {
438            0 => Ok(VolumeType::Box),
439            1 => Ok(VolumeType::Sphere),
440            2 => Ok(VolumeType::Capsule),
441            other => Err(crate::Error::UnknownEnum {
442                name: "VolumeType",
443                value: other,
444            }),
445        }
446    }
447}
448
449/// Interpolation mode for particle/ribbon smoothing curves
450///
451/// Maps to RibbonParticleCommon.fx constants. Used by PAR_ colorSmoothing / sizeSmoothing / rotationSmoothing and RIB_ sizeSmoothing / colorSmoothing.
452#[repr(i32)]
453#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
454pub enum InterpolationMode {
455    /// ITERPOLATION_LINEAR
456    Linear = 0,
457    /// ITERPOLATION_LINEAR_SMOOTH
458    LinearSmooth = 1,
459    /// ITERPOLATION_BEZIER
460    Bezier = 2,
461    /// ITERPOLATION_LINEAR_WITH_HOLD
462    LinearWithHold = 3,
463    /// ITERPOLATION_BEZIER_WITH_HOLD
464    BezierWithHold = 4,
465}
466
467impl TryFrom<i32> for InterpolationMode {
468    type Error = crate::Error;
469    fn try_from(v: i32) -> Result<Self, crate::Error> {
470        match v {
471            0 => Ok(InterpolationMode::Linear),
472            1 => Ok(InterpolationMode::LinearSmooth),
473            2 => Ok(InterpolationMode::Bezier),
474            3 => Ok(InterpolationMode::LinearWithHold),
475            4 => Ok(InterpolationMode::BezierWithHold),
476            other => Err(crate::Error::UnknownEnum {
477                name: "InterpolationMode",
478                value: other,
479            }),
480        }
481    }
482}
483
484/// Model-wide flags (MODL.flags) — tangents, FOW, instancing, etc.
485/// Bit flags. Combine with `|`, test with [`ModelFlag::contains`].
486#[derive(Clone, Copy, PartialEq, Eq, Hash, Default)]
487pub struct ModelFlag(pub i32);
488
489impl ModelFlag {
490    pub const NONE: Self = Self(0);
491    /// Tangents computed
492    pub const TANGENTS: Self = Self(1);
493    /// Bone transforms fixed
494    pub const BONES_FIXED: Self = Self(2);
495    /// UV densities computed
496    pub const UV_DENSITIES_COMPUTED: Self = Self(4);
497    /// Uses relative bounds
498    pub const RELATIVE_BOUNDS: Self = Self(8);
499    /// Section bounds fixed
500    pub const SECTION_BOUNDS_FIXED: Self = Self(16);
501    /// Track sets computed
502    pub const TRACK_SETS_COMPUTED: Self = Self(32);
503    /// Track collection sorted
504    pub const TRACK_COLLECTION_SORTED: Self = Self(64);
505    /// Model accepts splats
506    pub const ACCEPTS_SPLATS: Self = Self(128);
507    /// Animated base flag valid
508    pub const TRACK_ANIMATED_BASE_FLAG_VALID: Self = Self(2048);
509    /// File marked dirty
510    pub const FILE_DIRTY: Self = Self(4096);
511    /// FOW: do not tint
512    pub const FOW_DO_NOT_USE_TINT: Self = Self(16384);
513    /// Uses instanced vertex buffer
514    pub const INSTANCED_VB: Self = Self(32768);
515    /// Force sampled FOW
516    pub const FORCE_SAMPLED_FOW: Self = Self(65536);
517    /// Instanced model
518    pub const INSTANCED_MODEL: Self = Self(131072);
519    /// Never use FOW
520    pub const NEVER_USE_FOW: Self = Self(262144);
521    /// Bone animated flags solved
522    pub const BONE_ANIMATED_FLAG_SOLVED: Self = Self(524288);
523    /// Allow local light shadows
524    pub const ALLOW_LOCAL_LIGHT_SHADOWS: Self = Self(1048576);
525    /// Avoid sampled FOW
526    pub const AVOID_SAMPLED_FOW: Self = Self(2097152);
527
528    #[inline]
529    pub const fn contains(self, other: Self) -> bool {
530        (self.0 & other.0) == other.0
531    }
532
533    #[inline]
534    pub const fn is_empty(self) -> bool {
535        self.0 == 0
536    }
537}
538
539impl core::ops::BitOr for ModelFlag {
540    type Output = Self;
541    #[inline]
542    fn bitor(self, rhs: Self) -> Self {
543        Self(self.0 | rhs.0)
544    }
545}
546
547impl core::ops::BitAnd for ModelFlag {
548    type Output = Self;
549    #[inline]
550    fn bitand(self, rhs: Self) -> Self {
551        Self(self.0 & rhs.0)
552    }
553}
554
555impl core::ops::Not for ModelFlag {
556    type Output = Self;
557    #[inline]
558    fn not(self) -> Self {
559        Self(!self.0)
560    }
561}
562
563impl core::fmt::Debug for ModelFlag {
564    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
565        write!(f, "ModelFlag({:#x})", self.0)
566    }
567}
568
569/// Sequence playback flags (SEQS.flags)
570/// Bit flags. Combine with `|`, test with [`SequenceFlag::contains`].
571#[derive(Clone, Copy, PartialEq, Eq, Hash, Default)]
572pub struct SequenceFlag(pub i32);
573
574impl SequenceFlag {
575    pub const NONE: Self = Self(0);
576    /// Sequence does not loop
577    pub const NOT_LOOPING: Self = Self(1);
578    /// Always plays globally
579    pub const ALWAYS_GLOBAL: Self = Self(2);
580    /// Unknown
581    pub const UNKNOWN_0X_4: Self = Self(4);
582    /// Global playback in editor
583    pub const GLOBAL_IN_PREVIEWER: Self = Self(8);
584
585    #[inline]
586    pub const fn contains(self, other: Self) -> bool {
587        (self.0 & other.0) == other.0
588    }
589
590    #[inline]
591    pub const fn is_empty(self) -> bool {
592        self.0 == 0
593    }
594}
595
596impl core::ops::BitOr for SequenceFlag {
597    type Output = Self;
598    #[inline]
599    fn bitor(self, rhs: Self) -> Self {
600        Self(self.0 | rhs.0)
601    }
602}
603
604impl core::ops::BitAnd for SequenceFlag {
605    type Output = Self;
606    #[inline]
607    fn bitand(self, rhs: Self) -> Self {
608        Self(self.0 & rhs.0)
609    }
610}
611
612impl core::ops::Not for SequenceFlag {
613    type Output = Self;
614    #[inline]
615    fn not(self) -> Self {
616        Self(!self.0)
617    }
618}
619
620impl core::fmt::Debug for SequenceFlag {
621    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
622        write!(f, "SequenceFlag({:#x})", self.0)
623    }
624}
625
626/// Bone flags (BONE.flags) — inheritance, billboard, IK, skin
627/// Bit flags. Combine with `|`, test with [`BoneFlag::contains`].
628#[derive(Clone, Copy, PartialEq, Eq, Hash, Default)]
629pub struct BoneFlag(pub i32);
630
631impl BoneFlag {
632    pub const NONE: Self = Self(0);
633    /// Inherit parent translation
634    pub const INHERIT_TRANSLATION: Self = Self(1);
635    /// Inherit parent scale
636    pub const INHERIT_SCALE: Self = Self(2);
637    /// Inherit parent rotation
638    pub const INHERIT_ROTATION: Self = Self(4);
639    /// Billboard mode 1
640    pub const BILLBOARD_1: Self = Self(16);
641    /// Billboard mode 2
642    pub const BILLBOARD_2: Self = Self(64);
643    /// 2D projection mode
644    pub const PROJECT_2D: Self = Self(256);
645    /// Has animation data
646    pub const ANIMATED: Self = Self(512);
647    /// IK bone
648    pub const INVERSE_KINEMATICS: Self = Self(1024);
649    /// Affects mesh skin
650    pub const SKINNED: Self = Self(2048);
651    /// Real bone (not helper)
652    pub const REAL: Self = Self(8192);
653    /// Primary batch bone
654    pub const BATCH_1: Self = Self(16384);
655    /// Descendant of batch1 bone
656    pub const BATCH_2: Self = Self(32768);
657
658    #[inline]
659    pub const fn contains(self, other: Self) -> bool {
660        (self.0 & other.0) == other.0
661    }
662
663    #[inline]
664    pub const fn is_empty(self) -> bool {
665        self.0 == 0
666    }
667}
668
669impl core::ops::BitOr for BoneFlag {
670    type Output = Self;
671    #[inline]
672    fn bitor(self, rhs: Self) -> Self {
673        Self(self.0 | rhs.0)
674    }
675}
676
677impl core::ops::BitAnd for BoneFlag {
678    type Output = Self;
679    #[inline]
680    fn bitand(self, rhs: Self) -> Self {
681        Self(self.0 & rhs.0)
682    }
683}
684
685impl core::ops::Not for BoneFlag {
686    type Output = Self;
687    #[inline]
688    fn not(self) -> Self {
689        Self(!self.0)
690    }
691}
692
693impl core::fmt::Debug for BoneFlag {
694    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
695        write!(f, "BoneFlag({:#x})", self.0)
696    }
697}
698
699/// Region flags (REGN.flags, v4+)
700/// Bit flags. Combine with `|`, test with [`RegionFlag::contains`].
701#[derive(Clone, Copy, PartialEq, Eq, Hash, Default)]
702pub struct RegionFlag(pub i32);
703
704impl RegionFlag {
705    pub const NONE: Self = Self(0);
706    /// Region is hidden
707    pub const HIDDEN: Self = Self(1);
708    /// Placeholder region
709    pub const PLACEHOLDER: Self = Self(2);
710    /// Cloth-simulated
711    pub const CLOTH_SIMULATED: Self = Self(4);
712    /// Cloth-influenced
713    pub const CLOTH_INFLUENCED: Self = Self(8);
714
715    #[inline]
716    pub const fn contains(self, other: Self) -> bool {
717        (self.0 & other.0) == other.0
718    }
719
720    #[inline]
721    pub const fn is_empty(self) -> bool {
722        self.0 == 0
723    }
724}
725
726impl core::ops::BitOr for RegionFlag {
727    type Output = Self;
728    #[inline]
729    fn bitor(self, rhs: Self) -> Self {
730        Self(self.0 | rhs.0)
731    }
732}
733
734impl core::ops::BitAnd for RegionFlag {
735    type Output = Self;
736    #[inline]
737    fn bitand(self, rhs: Self) -> Self {
738        Self(self.0 & rhs.0)
739    }
740}
741
742impl core::ops::Not for RegionFlag {
743    type Output = Self;
744    #[inline]
745    fn not(self) -> Self {
746        Self(!self.0)
747    }
748}
749
750impl core::fmt::Debug for RegionFlag {
751    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
752        write!(f, "RegionFlag({:#x})", self.0)
753    }
754}
755
756/// Additional standard-material flags (MAT_.additionalFlags)
757/// Bit flags. Combine with `|`, test with [`MaterialAdditionalFlag::contains`].
758#[derive(Clone, Copy, PartialEq, Eq, Hash, Default)]
759pub struct MaterialAdditionalFlag(pub i32);
760
761impl MaterialAdditionalFlag {
762    pub const NONE: Self = Self(0);
763    /// Enable depth blend falloff
764    pub const DEPTH_BLEND_FALLOFF: Self = Self(1);
765    /// Uses vertex color
766    pub const VERTEX_COLOR: Self = Self(4);
767    /// Uses vertex alpha
768    pub const VERTEX_ALPHA: Self = Self(8);
769
770    #[inline]
771    pub const fn contains(self, other: Self) -> bool {
772        (self.0 & other.0) == other.0
773    }
774
775    #[inline]
776    pub const fn is_empty(self) -> bool {
777        self.0 == 0
778    }
779}
780
781impl core::ops::BitOr for MaterialAdditionalFlag {
782    type Output = Self;
783    #[inline]
784    fn bitor(self, rhs: Self) -> Self {
785        Self(self.0 | rhs.0)
786    }
787}
788
789impl core::ops::BitAnd for MaterialAdditionalFlag {
790    type Output = Self;
791    #[inline]
792    fn bitand(self, rhs: Self) -> Self {
793        Self(self.0 & rhs.0)
794    }
795}
796
797impl core::ops::Not for MaterialAdditionalFlag {
798    type Output = Self;
799    #[inline]
800    fn not(self) -> Self {
801        Self(!self.0)
802    }
803}
804
805impl core::fmt::Debug for MaterialAdditionalFlag {
806    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
807        write!(f, "MaterialAdditionalFlag({:#x})", self.0)
808    }
809}
810
811/// Standard material rendering flags (MAT_.flags)
812/// Bit flags. Combine with `|`, test with [`MaterialFlag::contains`].
813#[derive(Clone, Copy, PartialEq, Eq, Hash, Default)]
814pub struct MaterialFlag(pub i32);
815
816impl MaterialFlag {
817    pub const NONE: Self = Self(0);
818    /// Enable vertex color
819    pub const VERTEX_COLOR: Self = Self(1);
820    /// Enable vertex alpha
821    pub const VERTEX_ALPHA: Self = Self(2);
822    /// Not affected by fog
823    pub const UNFOGGED: Self = Self(4);
824    /// Two-sided rendering
825    pub const TWO_SIDED: Self = Self(8);
826    /// Unlit / unshaded
827    pub const UNSHADED: Self = Self(16);
828    /// Does not cast shadows
829    pub const NO_SHADOWS_CAST: Self = Self(32);
830    /// Excluded from hit testing
831    pub const NO_HIT_TEST: Self = Self(64);
832    /// Does not receive shadows
833    pub const NO_SHADOWS_RECEIVE: Self = Self(128);
834    /// Z-fill pre-pass
835    pub const DEPTH_PREPASS: Self = Self(256);
836    /// Terrain HDR mode
837    pub const TERRAIN_HDR: Self = Self(512);
838    /// Simulate roughness
839    pub const SIMULATE_ROUGHNESS: Self = Self(2048);
840    /// Pixel forward lighting
841    pub const PIXEL_FORWARD_LIGHTING: Self = Self(4096);
842    /// Depth-based fog
843    pub const DEPTH_FOG: Self = Self(8192);
844    /// Transparent shadows
845    pub const TRANSPARENT_SHADOWS: Self = Self(16384);
846    /// Decal lighting mode
847    pub const DECAL_LIGHTING: Self = Self(32768);
848    /// Transparent depth effects
849    pub const TRANSPARENT_DEPTH_EFFECTS: Self = Self(65536);
850    /// Transparent local lights
851    pub const TRANSPARENT_LOCAL_LIGHTS: Self = Self(131072);
852    /// Disable soft blending
853    pub const DISABLE_SOFT: Self = Self(262144);
854    /// Double Lambert shading
855    pub const DOUBLE_LAMBERT: Self = Self(524288);
856    /// Hair layer sorting
857    pub const HAIR_LAYER_SORTING: Self = Self(1048576);
858    /// Accept splat projections
859    pub const ACCEPT_SPLATS: Self = Self(2097152);
860    /// Decal low LOD required
861    pub const DECAL_LOW_REQUIRED: Self = Self(4194304);
862    /// Emissive low LOD required
863    pub const EMIS_LOW_REQUIRED: Self = Self(8388608);
864    /// Specular low LOD required
865    pub const SPEC_LOW_REQUIRED: Self = Self(16777216);
866    /// Accept splats only
867    pub const ACCEPT_SPLATS_ONLY: Self = Self(33554432);
868    /// Background object
869    pub const BACKGROUND_OBJECT: Self = Self(67108864);
870    /// Depth prepass low LOD
871    pub const DEPTH_PREPASS_LOW_REQUIRED: Self = Self(268435456);
872    /// Disable highlighting
873    pub const NO_HIGHLIGHTING: Self = Self(536870912);
874    /// Clamp output
875    pub const CLAMP_OUTPUT: Self = Self(1073741824);
876    /// Geometry visible (v17+)
877    pub const GEOMETRY_VISIBLE: Self = Self(-2147483648);
878
879    #[inline]
880    pub const fn contains(self, other: Self) -> bool {
881        (self.0 & other.0) == other.0
882    }
883
884    #[inline]
885    pub const fn is_empty(self) -> bool {
886        self.0 == 0
887    }
888}
889
890impl core::ops::BitOr for MaterialFlag {
891    type Output = Self;
892    #[inline]
893    fn bitor(self, rhs: Self) -> Self {
894        Self(self.0 | rhs.0)
895    }
896}
897
898impl core::ops::BitAnd for MaterialFlag {
899    type Output = Self;
900    #[inline]
901    fn bitand(self, rhs: Self) -> Self {
902        Self(self.0 & rhs.0)
903    }
904}
905
906impl core::ops::Not for MaterialFlag {
907    type Output = Self;
908    #[inline]
909    fn not(self) -> Self {
910        Self(!self.0)
911    }
912}
913
914impl core::fmt::Debug for MaterialFlag {
915    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
916        write!(f, "MaterialFlag({:#x})", self.0)
917    }
918}
919
920/// Texture layer flags (LAYR.flags)
921/// Bit flags. Combine with `|`, test with [`TextureLayerFlag::contains`].
922#[derive(Clone, Copy, PartialEq, Eq, Hash, Default)]
923pub struct TextureLayerFlag(pub i32);
924
925impl TextureLayerFlag {
926    pub const NONE: Self = Self(0);
927    /// Wrap texture in U
928    pub const UV_WRAP_X: Self = Self(4);
929    /// Wrap texture in V
930    pub const UV_WRAP_Y: Self = Self(8);
931    /// Invert color
932    pub const COLOR_INVERT: Self = Self(16);
933    /// Clamp to `[0,1]`
934    pub const COLOR_CLAMP: Self = Self(32);
935    /// Additive blending
936    pub const COLOR_ADD: Self = Self(64);
937    /// Multiplicative blending
938    pub const COLOR_MULTIPLY: Self = Self(128);
939    /// Flipbook UVs for particles
940    pub const PARTICLE_UV_FLIPBOOK: Self = Self(256);
941    /// Video texture
942    pub const VIDEO: Self = Self(512);
943    /// Solid color (no texture)
944    pub const COLOR: Self = Self(1024);
945    /// Override texture source
946    pub const REPLACE_TEXTURE_SOURCE: Self = Self(2048);
947    /// Fresnel-based UV transform
948    pub const FRESNEL_TRANSFORM: Self = Self(16384);
949    /// Normalize fresnel values
950    pub const FRESNEL_NORMALIZE: Self = Self(32768);
951
952    #[inline]
953    pub const fn contains(self, other: Self) -> bool {
954        (self.0 & other.0) == other.0
955    }
956
957    #[inline]
958    pub const fn is_empty(self) -> bool {
959        self.0 == 0
960    }
961}
962
963impl core::ops::BitOr for TextureLayerFlag {
964    type Output = Self;
965    #[inline]
966    fn bitor(self, rhs: Self) -> Self {
967        Self(self.0 | rhs.0)
968    }
969}
970
971impl core::ops::BitAnd for TextureLayerFlag {
972    type Output = Self;
973    #[inline]
974    fn bitand(self, rhs: Self) -> Self {
975        Self(self.0 & rhs.0)
976    }
977}
978
979impl core::ops::Not for TextureLayerFlag {
980    type Output = Self;
981    #[inline]
982    fn not(self) -> Self {
983        Self(!self.0)
984    }
985}
986
987impl core::fmt::Debug for TextureLayerFlag {
988    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
989        write!(f, "TextureLayerFlag({:#x})", self.0)
990    }
991}
992
993/// Blend mode for materials (MAT_.blendMode, VOL_.blendMode)
994#[repr(i32)]
995#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
996pub enum BlendMode {
997    /// Fully opaque
998    Opaque = 0,
999    /// Standard alpha blending
1000    AlphaBlend = 1,
1001    /// Additive blending
1002    Add = 2,
1003    /// Alpha-modulated additive
1004    AlphaAdd = 3,
1005    /// Multiplicative blending
1006    Mod = 4,
1007    /// Double multiplicative
1008    Mod2x = 5,
1009}
1010
1011impl TryFrom<i32> for BlendMode {
1012    type Error = crate::Error;
1013    fn try_from(v: i32) -> Result<Self, crate::Error> {
1014        match v {
1015            0 => Ok(BlendMode::Opaque),
1016            1 => Ok(BlendMode::AlphaBlend),
1017            2 => Ok(BlendMode::Add),
1018            3 => Ok(BlendMode::AlphaAdd),
1019            4 => Ok(BlendMode::Mod),
1020            5 => Ok(BlendMode::Mod2x),
1021            other => Err(crate::Error::UnknownEnum {
1022                name: "BlendMode",
1023                value: other,
1024            }),
1025        }
1026    }
1027}
1028
1029/// Material rendering class (MAT_.materialClass)
1030#[repr(i32)]
1031#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1032pub enum MaterialClass {
1033    /// Unit/character material
1034    Unit = 0,
1035    /// Building/structure material
1036    Building = 1,
1037    /// Doodad/prop material
1038    Doodad = 2,
1039    /// Special effect material
1040    SpecialFX = 3,
1041}
1042
1043impl TryFrom<i32> for MaterialClass {
1044    type Error = crate::Error;
1045    fn try_from(v: i32) -> Result<Self, crate::Error> {
1046        match v {
1047            0 => Ok(MaterialClass::Unit),
1048            1 => Ok(MaterialClass::Building),
1049            2 => Ok(MaterialClass::Doodad),
1050            3 => Ok(MaterialClass::SpecialFX),
1051            other => Err(crate::Error::UnknownEnum {
1052                name: "MaterialClass",
1053                value: other,
1054            }),
1055        }
1056    }
1057}
1058
1059/// Layer blend operation (MAT_.layerBlendMode, emissiveBlendMode)
1060#[repr(i32)]
1061#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1062pub enum LayerBlendOp {
1063    /// Multiply: base * layer
1064    Mod = 0,
1065    /// Double multiply: base * layer * 2
1066    Mod2x = 1,
1067    /// Add: base + layer
1068    Add = 2,
1069    /// Linear interpolate by layer alpha
1070    Lerp = 3,
1071    /// Team color emissive add
1072    TeamColorEmissiveAdd = 4,
1073    /// Team color diffuse add
1074    TeamColorDiffuseAdd = 5,
1075    /// Add ignoring alpha channel
1076    AddNoAlpha = 6,
1077}
1078
1079impl TryFrom<i32> for LayerBlendOp {
1080    type Error = crate::Error;
1081    fn try_from(v: i32) -> Result<Self, crate::Error> {
1082        match v {
1083            0 => Ok(LayerBlendOp::Mod),
1084            1 => Ok(LayerBlendOp::Mod2x),
1085            2 => Ok(LayerBlendOp::Add),
1086            3 => Ok(LayerBlendOp::Lerp),
1087            4 => Ok(LayerBlendOp::TeamColorEmissiveAdd),
1088            5 => Ok(LayerBlendOp::TeamColorDiffuseAdd),
1089            6 => Ok(LayerBlendOp::AddNoAlpha),
1090            other => Err(crate::Error::UnknownEnum {
1091                name: "LayerBlendOp",
1092                value: other,
1093            }),
1094        }
1095    }
1096}
1097
1098/// UV mapping source / projection mode (LAYR.uvMapping)
1099#[repr(i32)]
1100#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1101pub enum UVMappingMode {
1102    /// UV coordinate set 0
1103    ExplicitUV0 = 0,
1104    /// UV coordinate set 1
1105    ExplicitUV1 = 1,
1106    /// Cubic environment reflection
1107    ReflectCubicEnvio = 2,
1108    /// Spherical environment reflection
1109    ReflectSphericalEnvio = 3,
1110    /// Planar local UVs (Z plane)
1111    PlanarLocalZ = 4,
1112    /// Planar world UVs (Z plane)
1113    PlanarWorldZ = 5,
1114    /// Particle flipbook UVs
1115    ParticleFlipbook = 6,
1116    /// Cubic environment mapping
1117    CubicEnvio = 7,
1118    /// Spherical environment mapping
1119    SphericalEnvio = 8,
1120    /// UV coordinate set 2
1121    ExplicitUV2 = 9,
1122    /// UV coordinate set 3
1123    ExplicitUV3 = 10,
1124    /// Planar local UVs (X plane)
1125    PlanarLocalX = 11,
1126    /// Planar local UVs (Y plane)
1127    PlanarLocalY = 12,
1128    /// Planar world UVs (X plane)
1129    PlanarWorldX = 13,
1130    /// Planar world UVs (Y plane)
1131    PlanarWorldY = 14,
1132    /// Screen-space UVs
1133    ScreenSpace = 15,
1134    /// Tri-planar blending (local space)
1135    TriPlanarLocal = 16,
1136    /// Tri-planar blending (world space)
1137    TriPlanarWorld = 17,
1138    /// Tri-planar world with local Z
1139    TriPlanarWorldLocalZ = 18,
1140}
1141
1142impl TryFrom<i32> for UVMappingMode {
1143    type Error = crate::Error;
1144    fn try_from(v: i32) -> Result<Self, crate::Error> {
1145        match v {
1146            0 => Ok(UVMappingMode::ExplicitUV0),
1147            1 => Ok(UVMappingMode::ExplicitUV1),
1148            2 => Ok(UVMappingMode::ReflectCubicEnvio),
1149            3 => Ok(UVMappingMode::ReflectSphericalEnvio),
1150            4 => Ok(UVMappingMode::PlanarLocalZ),
1151            5 => Ok(UVMappingMode::PlanarWorldZ),
1152            6 => Ok(UVMappingMode::ParticleFlipbook),
1153            7 => Ok(UVMappingMode::CubicEnvio),
1154            8 => Ok(UVMappingMode::SphericalEnvio),
1155            9 => Ok(UVMappingMode::ExplicitUV2),
1156            10 => Ok(UVMappingMode::ExplicitUV3),
1157            11 => Ok(UVMappingMode::PlanarLocalX),
1158            12 => Ok(UVMappingMode::PlanarLocalY),
1159            13 => Ok(UVMappingMode::PlanarWorldX),
1160            14 => Ok(UVMappingMode::PlanarWorldY),
1161            15 => Ok(UVMappingMode::ScreenSpace),
1162            16 => Ok(UVMappingMode::TriPlanarLocal),
1163            17 => Ok(UVMappingMode::TriPlanarWorld),
1164            18 => Ok(UVMappingMode::TriPlanarWorldLocalZ),
1165            other => Err(crate::Error::UnknownEnum {
1166                name: "UVMappingMode",
1167                value: other,
1168            }),
1169        }
1170    }
1171}
1172
1173/// Color channel selection (LAYR.colorType)
1174#[repr(i32)]
1175#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1176pub enum ColorChannelSelect {
1177    /// Use RGB channels (alpha forced to 1)
1178    RGB = 0,
1179    /// Use all RGBA channels
1180    RGBA = 1,
1181    /// Use alpha channel only (splat to all)
1182    Alpha = 2,
1183    /// Use red channel only (splat to all)
1184    Red = 3,
1185    /// Use green channel only (splat to all)
1186    Green = 4,
1187    /// Use blue channel only (splat to all)
1188    Blue = 5,
1189}
1190
1191impl TryFrom<i32> for ColorChannelSelect {
1192    type Error = crate::Error;
1193    fn try_from(v: i32) -> Result<Self, crate::Error> {
1194        match v {
1195            0 => Ok(ColorChannelSelect::RGB),
1196            1 => Ok(ColorChannelSelect::RGBA),
1197            2 => Ok(ColorChannelSelect::Alpha),
1198            3 => Ok(ColorChannelSelect::Red),
1199            4 => Ok(ColorChannelSelect::Green),
1200            5 => Ok(ColorChannelSelect::Blue),
1201            other => Err(crate::Error::UnknownEnum {
1202                name: "ColorChannelSelect",
1203                value: other,
1204            }),
1205        }
1206    }
1207}
1208
1209/// Specular mode (MAT_.specularMode)
1210#[repr(i32)]
1211#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1212pub enum SpecularMode {
1213    /// Use RGB channels for specularity
1214    RGB = 0,
1215    /// Use alpha channel only
1216    AlphaOnly = 1,
1217}
1218
1219impl TryFrom<i32> for SpecularMode {
1220    type Error = crate::Error;
1221    fn try_from(v: i32) -> Result<Self, crate::Error> {
1222        match v {
1223            0 => Ok(SpecularMode::RGB),
1224            1 => Ok(SpecularMode::AlphaOnly),
1225            other => Err(crate::Error::UnknownEnum {
1226                name: "SpecularMode",
1227                value: other,
1228            }),
1229        }
1230    }
1231}
1232
1233/// Fresnel effect mode (LAYR.fresnelMode)
1234#[repr(i32)]
1235#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1236pub enum FresnelMode {
1237    /// No fresnel effect
1238    None = 0,
1239    /// Standard fresnel (edge glow)
1240    Standard = 1,
1241    /// Inverted fresnel (center glow)
1242    Inverted = 2,
1243}
1244
1245impl TryFrom<i32> for FresnelMode {
1246    type Error = crate::Error;
1247    fn try_from(v: i32) -> Result<Self, crate::Error> {
1248        match v {
1249            0 => Ok(FresnelMode::None),
1250            1 => Ok(FresnelMode::Standard),
1251            2 => Ok(FresnelMode::Inverted),
1252            other => Err(crate::Error::UnknownEnum {
1253                name: "FresnelMode",
1254                value: other,
1255            }),
1256        }
1257    }
1258}
1259
1260/// Reflection material flags (REF_.flags, v2+)
1261/// Bit flags. Combine with `|`, test with [`ReflectionMaterialFlag::contains`].
1262#[derive(Clone, Copy, PartialEq, Eq, Hash, Default)]
1263pub struct ReflectionMaterialFlag(pub i32);
1264
1265impl ReflectionMaterialFlag {
1266    pub const NONE: Self = Self(0);
1267    /// Use reflection map
1268    pub const USE_REFLECTION_MAP: Self = Self(1);
1269    /// Use displacement map
1270    pub const USE_DISPLACEMENT_MAP: Self = Self(2);
1271    /// Render in transparent pass
1272    pub const RENDER_IN_TRANSPARENT_PASS: Self = Self(4);
1273    /// Enable blurring
1274    pub const BLURRING: Self = Self(8);
1275    /// Use blur map
1276    pub const USE_BLUR_MAP: Self = Self(16);
1277
1278    #[inline]
1279    pub const fn contains(self, other: Self) -> bool {
1280        (self.0 & other.0) == other.0
1281    }
1282
1283    #[inline]
1284    pub const fn is_empty(self) -> bool {
1285        self.0 == 0
1286    }
1287}
1288
1289impl core::ops::BitOr for ReflectionMaterialFlag {
1290    type Output = Self;
1291    #[inline]
1292    fn bitor(self, rhs: Self) -> Self {
1293        Self(self.0 | rhs.0)
1294    }
1295}
1296
1297impl core::ops::BitAnd for ReflectionMaterialFlag {
1298    type Output = Self;
1299    #[inline]
1300    fn bitand(self, rhs: Self) -> Self {
1301        Self(self.0 & rhs.0)
1302    }
1303}
1304
1305impl core::ops::Not for ReflectionMaterialFlag {
1306    type Output = Self;
1307    #[inline]
1308    fn not(self) -> Self {
1309        Self(!self.0)
1310    }
1311}
1312
1313impl core::fmt::Debug for ReflectionMaterialFlag {
1314    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1315        write!(f, "ReflectionMaterialFlag({:#x})", self.0)
1316    }
1317}
1318
1319/// Volume noise material flags (VON_.flags)
1320#[repr(i32)]
1321#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1322pub enum VolumeNoiseMaterialFlag {
1323    None = 0,
1324    /// Draw in separate pass after transparency
1325    DrawAfterTransparency = 1,
1326}
1327
1328impl TryFrom<i32> for VolumeNoiseMaterialFlag {
1329    type Error = crate::Error;
1330    fn try_from(v: i32) -> Result<Self, crate::Error> {
1331        match v {
1332            0 => Ok(VolumeNoiseMaterialFlag::None),
1333            1 => Ok(VolumeNoiseMaterialFlag::DrawAfterTransparency),
1334            other => Err(crate::Error::UnknownEnum {
1335                name: "VolumeNoiseMaterialFlag",
1336                value: other,
1337            }),
1338        }
1339    }
1340}
1341
1342/// Volume density falloff type (VOL_.falloffType, VON_.falloffType)
1343#[repr(i32)]
1344#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1345pub enum VolumeFalloffType {
1346    /// Linear density falloff
1347    Linear = 0,
1348    /// Exponential density falloff
1349    Exponential = 1,
1350}
1351
1352impl TryFrom<i32> for VolumeFalloffType {
1353    type Error = crate::Error;
1354    fn try_from(v: i32) -> Result<Self, crate::Error> {
1355        match v {
1356            0 => Ok(VolumeFalloffType::Linear),
1357            1 => Ok(VolumeFalloffType::Exponential),
1358            other => Err(crate::Error::UnknownEnum {
1359                name: "VolumeFalloffType",
1360                value: other,
1361            }),
1362        }
1363    }
1364}
1365
1366/// Volume noise camera position mode (VON_.drawTransparency)
1367#[repr(i32)]
1368#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1369pub enum VolumeNoiseCameraMode {
1370    /// Camera is outside the volume
1371    Outside = 0,
1372    /// Camera is inside the volume
1373    Inside = 1,
1374}
1375
1376impl TryFrom<i32> for VolumeNoiseCameraMode {
1377    type Error = crate::Error;
1378    fn try_from(v: i32) -> Result<Self, crate::Error> {
1379        match v {
1380            0 => Ok(VolumeNoiseCameraMode::Outside),
1381            1 => Ok(VolumeNoiseCameraMode::Inside),
1382            other => Err(crate::Error::UnknownEnum {
1383                name: "VolumeNoiseCameraMode",
1384                value: other,
1385            }),
1386        }
1387    }
1388}
1389
1390/// Light flags (LITE.flags)
1391/// Bit flags. Combine with `|`, test with [`LightFlag::contains`].
1392#[derive(Clone, Copy, PartialEq, Eq, Hash, Default)]
1393pub struct LightFlag(pub i32);
1394
1395impl LightFlag {
1396    pub const NONE: Self = Self(0);
1397    /// Casts shadows
1398    pub const SHADOWS: Self = Self(1);
1399    /// Specular component
1400    pub const SPECULAR: Self = Self(2);
1401    /// AO influence
1402    pub const AMBIENT_OCCLUSION: Self = Self(4);
1403    /// Lights opaque objects
1404    pub const LIGHT_OPAQUE: Self = Self(8);
1405    /// Lights transparent objects
1406    pub const LIGHT_TRANSPARENT: Self = Self(16);
1407    /// Uses team color
1408    pub const TEAM_COLOR: Self = Self(32);
1409
1410    #[inline]
1411    pub const fn contains(self, other: Self) -> bool {
1412        (self.0 & other.0) == other.0
1413    }
1414
1415    #[inline]
1416    pub const fn is_empty(self) -> bool {
1417        self.0 == 0
1418    }
1419}
1420
1421impl core::ops::BitOr for LightFlag {
1422    type Output = Self;
1423    #[inline]
1424    fn bitor(self, rhs: Self) -> Self {
1425        Self(self.0 | rhs.0)
1426    }
1427}
1428
1429impl core::ops::BitAnd for LightFlag {
1430    type Output = Self;
1431    #[inline]
1432    fn bitand(self, rhs: Self) -> Self {
1433        Self(self.0 & rhs.0)
1434    }
1435}
1436
1437impl core::ops::Not for LightFlag {
1438    type Output = Self;
1439    #[inline]
1440    fn not(self) -> Self {
1441        Self(!self.0)
1442    }
1443}
1444
1445impl core::fmt::Debug for LightFlag {
1446    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1447        write!(f, "LightFlag({:#x})", self.0)
1448    }
1449}
1450
1451/// Particle emitter main flags (PAR_.flags)
1452/// Bit flags. Combine with `|`, test with [`ParticleFlag::contains`].
1453#[derive(Clone, Copy, PartialEq, Eq, Hash, Default)]
1454pub struct ParticleFlag(pub i32);
1455
1456impl ParticleFlag {
1457    pub const NONE: Self = Self(0);
1458    /// Sort by distance
1459    pub const SORT: Self = Self(1);
1460    /// Collide with terrain
1461    pub const COLLIDE_TERRAIN: Self = Self(2);
1462    /// Collide with objects
1463    pub const COLLIDE_OBJECTS: Self = Self(4);
1464    /// Emit on collision
1465    pub const COLLIDE_EMIT: Self = Self(8);
1466    /// Emit from shape cutout
1467    pub const EMIT_SHAPE_CUTOUT: Self = Self(16);
1468    /// Inherit emission parameters
1469    pub const INHERIT_EMIT_PARAMS: Self = Self(32);
1470    /// Inherit parent velocity
1471    pub const INHERIT_PARENT_VELOCITY: Self = Self(64);
1472    /// Sort by height
1473    pub const SORT_HEIGHT: Self = Self(128);
1474    /// Reverse sort order
1475    pub const SORT_REVERSE: Self = Self(256);
1476    /// Legacy rotation smoothing
1477    pub const OLD_ROTATION_SMOOTH: Self = Self(512);
1478    /// Legacy rotation bezier
1479    pub const OLD_ROTATION_BEZIER: Self = Self(1024);
1480    /// Legacy size smoothing
1481    pub const OLD_SIZE_SMOOTH: Self = Self(2048);
1482    /// Legacy size bezier
1483    pub const OLD_SIZE_BEZIER: Self = Self(4096);
1484    /// Legacy color smoothing
1485    pub const OLD_COLOR_SMOOTH: Self = Self(8192);
1486    /// Legacy color bezier
1487    pub const OLD_COLOR_BEZIER: Self = Self(16384);
1488    /// Lit particles → lit pixel-shader variant
1489    pub const LIT_PARTS: Self = Self(32768);
1490    /// Random flipbook start → shader b_randomFlipBookStart
1491    pub const RANDOM_FLIPBOOK_START: Self = Self(65536);
1492    /// Multiply gravity by mass
1493    pub const MULTIPLY_GRAVITY_BY_MASS: Self = Self(131072);
1494    /// Clamp tail length → shader b_clampedTailLength (Tail/Trail, not Pinned)
1495    pub const CLAMP_TAIL_LENGTH: Self = Self(262144);
1496    /// Spawn trailing particles (also forces b_useProceduralPosition)
1497    pub const SPAWN_TRAILING_PARTICLES: Self = Self(524288);
1498    /// Fix tail length on creation → shader b_fixedTailLength
1499    pub const FIX_TAIL_LENGTH_ON_CREATION: Self = Self(1048576);
1500    /// Use vertex alpha
1501    pub const USE_VERTEX_ALPHA: Self = Self(2097152);
1502    /// Use model particles (also forces b_useProceduralPosition)
1503    pub const MODEL_PARTICLES: Self = Self(4194304);
1504    /// Swap Y/Z on model particles
1505    pub const SWAP_YZ_ON_MODEL_PARTICLES: Self = Self(8388608);
1506    /// Scale time by parent
1507    pub const SCALE_TIME_BY_PARENT: Self = Self(16777216);
1508    /// Use local time
1509    pub const USE_LOCAL_TIME: Self = Self(33554432);
1510    /// Simulate on initialization
1511    pub const SIMULATE_INIT: Self = Self(67108864);
1512    /// Copy emitter
1513    pub const COPY: Self = Self(134217728);
1514    /// Part of the b_useProceduralPosition trigger mask (0x10480003)
1515    pub const REQUIRES_GPU_SIM: Self = Self(268435456);
1516    /// Toggles a particle shader permutation (role TBD)
1517    pub const SHADER_PERM_30: Self = Self(1073741824);
1518    /// Forces GPU procedural-position path (b_useProceduralPosition)
1519    pub const FORCE_PROCEDURAL_POSITION: Self = Self(-2147483648);
1520
1521    #[inline]
1522    pub const fn contains(self, other: Self) -> bool {
1523        (self.0 & other.0) == other.0
1524    }
1525
1526    #[inline]
1527    pub const fn is_empty(self) -> bool {
1528        self.0 == 0
1529    }
1530}
1531
1532impl core::ops::BitOr for ParticleFlag {
1533    type Output = Self;
1534    #[inline]
1535    fn bitor(self, rhs: Self) -> Self {
1536        Self(self.0 | rhs.0)
1537    }
1538}
1539
1540impl core::ops::BitAnd for ParticleFlag {
1541    type Output = Self;
1542    #[inline]
1543    fn bitand(self, rhs: Self) -> Self {
1544        Self(self.0 & rhs.0)
1545    }
1546}
1547
1548impl core::ops::Not for ParticleFlag {
1549    type Output = Self;
1550    #[inline]
1551    fn not(self) -> Self {
1552        Self(!self.0)
1553    }
1554}
1555
1556impl core::fmt::Debug for ParticleFlag {
1557    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1558        write!(f, "ParticleFlag({:#x})", self.0)
1559    }
1560}
1561
1562/// Particle emitter additional flags (PAR_.additionalFlags, v17+)
1563/// Bit flags. Combine with `|`, test with [`ParticleAdditionalFlag::contains`].
1564#[derive(Clone, Copy, PartialEq, Eq, Hash, Default)]
1565pub struct ParticleAdditionalFlag(pub i32);
1566
1567impl ParticleAdditionalFlag {
1568    pub const NONE: Self = Self(0);
1569    /// Randomize emission speed
1570    pub const EMIT_SPEED_RANDOMIZE: Self = Self(1);
1571    /// Randomize lifespan
1572    pub const LIFESPAN_RANDOMIZE: Self = Self(2);
1573    /// Randomize mass
1574    pub const MASS_RANDOMIZE: Self = Self(4);
1575    /// World-space coordinates
1576    pub const WORLD_SPACE: Self = Self(8);
1577
1578    #[inline]
1579    pub const fn contains(self, other: Self) -> bool {
1580        (self.0 & other.0) == other.0
1581    }
1582
1583    #[inline]
1584    pub const fn is_empty(self) -> bool {
1585        self.0 == 0
1586    }
1587}
1588
1589impl core::ops::BitOr for ParticleAdditionalFlag {
1590    type Output = Self;
1591    #[inline]
1592    fn bitor(self, rhs: Self) -> Self {
1593        Self(self.0 | rhs.0)
1594    }
1595}
1596
1597impl core::ops::BitAnd for ParticleAdditionalFlag {
1598    type Output = Self;
1599    #[inline]
1600    fn bitand(self, rhs: Self) -> Self {
1601        Self(self.0 & rhs.0)
1602    }
1603}
1604
1605impl core::ops::Not for ParticleAdditionalFlag {
1606    type Output = Self;
1607    #[inline]
1608    fn not(self) -> Self {
1609        Self(!self.0)
1610    }
1611}
1612
1613impl core::fmt::Debug for ParticleAdditionalFlag {
1614    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1615        write!(f, "ParticleAdditionalFlag({:#x})", self.0)
1616    }
1617}
1618
1619/// Particle rotation flags (PAR_.rotationFlags, v18+)
1620#[repr(i32)]
1621#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1622pub enum ParticleRotationFlag {
1623    None = 0,
1624    /// Relative rotation
1625    Relative = 2,
1626    /// Always set
1627    AlwaysSet = 4,
1628}
1629
1630impl TryFrom<i32> for ParticleRotationFlag {
1631    type Error = crate::Error;
1632    fn try_from(v: i32) -> Result<Self, crate::Error> {
1633        match v {
1634            0 => Ok(ParticleRotationFlag::None),
1635            2 => Ok(ParticleRotationFlag::Relative),
1636            4 => Ok(ParticleRotationFlag::AlwaysSet),
1637            other => Err(crate::Error::UnknownEnum {
1638                name: "ParticleRotationFlag",
1639                value: other,
1640            }),
1641        }
1642    }
1643}
1644
1645/// Ribbon emitter main flags (RIB_.flags)
1646/// Bit flags. Combine with `|`, test with [`RibbonFlag::contains`].
1647#[derive(Clone, Copy, PartialEq, Eq, Hash, Default)]
1648pub struct RibbonFlag(pub i32);
1649
1650impl RibbonFlag {
1651    pub const NONE: Self = Self(0);
1652    /// Collide with terrain
1653    pub const COLLIDE_TERRAIN: Self = Self(2);
1654    /// Collide with objects
1655    pub const COLLIDE_OBJECTS: Self = Self(4);
1656    /// Fade edges
1657    pub const EDGE_FALLOFF: Self = Self(8);
1658    /// Inherit parent velocity
1659    pub const INHERIT_PARENT_VELOCITY: Self = Self(16);
1660    /// Smooth size
1661    pub const SMOOTH_SIZE: Self = Self(32);
1662    /// Bezier smooth size
1663    pub const BEZIER_SMOOTH_SIZE: Self = Self(64);
1664    /// Use vertex alpha
1665    pub const USE_VERTEX_ALPHA: Self = Self(128);
1666    /// Scale time by parent
1667    pub const SCALE_TIME_BY_PARENT: Self = Self(256);
1668    /// Force CPU simulation
1669    pub const FORCE_CPU_SIM: Self = Self(512);
1670    /// Use local time
1671    pub const LOCAL_TIME: Self = Self(1024);
1672    /// Simulate on init
1673    pub const SIMULATE_INIT: Self = Self(2048);
1674    /// Use length and time
1675    pub const USE_LENGTH_AND_TIME: Self = Self(4096);
1676    /// Accurate GPU tangents
1677    pub const ACCURATE_GPU_TANGENTS: Self = Self(8192);
1678    /// Derive yaw from speed
1679    pub const YAW_FROM_SPEED: Self = Self(16384);
1680    /// Use locator node
1681    pub const USE_LOCATOR: Self = Self(32768);
1682
1683    #[inline]
1684    pub const fn contains(self, other: Self) -> bool {
1685        (self.0 & other.0) == other.0
1686    }
1687
1688    #[inline]
1689    pub const fn is_empty(self) -> bool {
1690        self.0 == 0
1691    }
1692}
1693
1694impl core::ops::BitOr for RibbonFlag {
1695    type Output = Self;
1696    #[inline]
1697    fn bitor(self, rhs: Self) -> Self {
1698        Self(self.0 | rhs.0)
1699    }
1700}
1701
1702impl core::ops::BitAnd for RibbonFlag {
1703    type Output = Self;
1704    #[inline]
1705    fn bitand(self, rhs: Self) -> Self {
1706        Self(self.0 & rhs.0)
1707    }
1708}
1709
1710impl core::ops::Not for RibbonFlag {
1711    type Output = Self;
1712    #[inline]
1713    fn not(self) -> Self {
1714        Self(!self.0)
1715    }
1716}
1717
1718impl core::fmt::Debug for RibbonFlag {
1719    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1720        write!(f, "RibbonFlag({:#x})", self.0)
1721    }
1722}
1723
1724/// Ribbon emitter additional flags (RIB_.flags2, v8+)
1725/// Bit flags. Combine with `|`, test with [`RibbonAdditionalFlag::contains`].
1726#[derive(Clone, Copy, PartialEq, Eq, Hash, Default)]
1727pub struct RibbonAdditionalFlag(pub i32);
1728
1729impl RibbonAdditionalFlag {
1730    pub const NONE: Self = Self(0);
1731    /// Randomize emission speed
1732    pub const SPEED_RANDOMIZE: Self = Self(1);
1733    /// Randomize lifespan
1734    pub const LIFESPAN_RANDOMIZE: Self = Self(2);
1735    /// Randomize mass
1736    pub const MASS_RANDOMIZE: Self = Self(4);
1737    /// World-space coordinates
1738    pub const WORLD_SPACE: Self = Self(8);
1739
1740    #[inline]
1741    pub const fn contains(self, other: Self) -> bool {
1742        (self.0 & other.0) == other.0
1743    }
1744
1745    #[inline]
1746    pub const fn is_empty(self) -> bool {
1747        self.0 == 0
1748    }
1749}
1750
1751impl core::ops::BitOr for RibbonAdditionalFlag {
1752    type Output = Self;
1753    #[inline]
1754    fn bitor(self, rhs: Self) -> Self {
1755        Self(self.0 | rhs.0)
1756    }
1757}
1758
1759impl core::ops::BitAnd for RibbonAdditionalFlag {
1760    type Output = Self;
1761    #[inline]
1762    fn bitand(self, rhs: Self) -> Self {
1763        Self(self.0 & rhs.0)
1764    }
1765}
1766
1767impl core::ops::Not for RibbonAdditionalFlag {
1768    type Output = Self;
1769    #[inline]
1770    fn not(self) -> Self {
1771        Self(!self.0)
1772    }
1773}
1774
1775impl core::fmt::Debug for RibbonAdditionalFlag {
1776    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1777        write!(f, "RibbonAdditionalFlag({:#x})", self.0)
1778    }
1779}
1780
1781/// Projector flags (PROJ.flags)
1782/// Bit flags. Combine with `|`, test with [`ProjectorFlag::contains`].
1783#[derive(Clone, Copy, PartialEq, Eq, Hash, Default)]
1784pub struct ProjectorFlag(pub i32);
1785
1786impl ProjectorFlag {
1787    pub const NONE: Self = Self(0);
1788    /// Static position
1789    pub const STATIC: Self = Self(1);
1790    /// Unknown
1791    pub const UNKNOWN_FLAG_0X_2: Self = Self(2);
1792    /// Unknown
1793    pub const UNKNOWN_FLAG_0X_4: Self = Self(4);
1794    /// Unknown
1795    pub const UNKNOWN_FLAG_0X_8: Self = Self(8);
1796
1797    #[inline]
1798    pub const fn contains(self, other: Self) -> bool {
1799        (self.0 & other.0) == other.0
1800    }
1801
1802    #[inline]
1803    pub const fn is_empty(self) -> bool {
1804        self.0 == 0
1805    }
1806}
1807
1808impl core::ops::BitOr for ProjectorFlag {
1809    type Output = Self;
1810    #[inline]
1811    fn bitor(self, rhs: Self) -> Self {
1812        Self(self.0 | rhs.0)
1813    }
1814}
1815
1816impl core::ops::BitAnd for ProjectorFlag {
1817    type Output = Self;
1818    #[inline]
1819    fn bitand(self, rhs: Self) -> Self {
1820        Self(self.0 & rhs.0)
1821    }
1822}
1823
1824impl core::ops::Not for ProjectorFlag {
1825    type Output = Self;
1826    #[inline]
1827    fn not(self) -> Self {
1828        Self(!self.0)
1829    }
1830}
1831
1832impl core::fmt::Debug for ProjectorFlag {
1833    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1834        write!(f, "ProjectorFlag({:#x})", self.0)
1835    }
1836}
1837
1838/// Force flags (FOR_.flags)
1839/// Bit flags. Combine with `|`, test with [`ForceFlag::contains`].
1840#[derive(Clone, Copy, PartialEq, Eq, Hash, Default)]
1841pub struct ForceFlag(pub i32);
1842
1843impl ForceFlag {
1844    pub const NONE: Self = Self(0);
1845    /// Distance falloff
1846    pub const FALLOFF: Self = Self(1);
1847    /// Height gradient
1848    pub const HEIGHT_GRADIENT: Self = Self(2);
1849    /// Unbounded range
1850    pub const UNBOUNDED: Self = Self(4);
1851
1852    #[inline]
1853    pub const fn contains(self, other: Self) -> bool {
1854        (self.0 & other.0) == other.0
1855    }
1856
1857    #[inline]
1858    pub const fn is_empty(self) -> bool {
1859        self.0 == 0
1860    }
1861}
1862
1863impl core::ops::BitOr for ForceFlag {
1864    type Output = Self;
1865    #[inline]
1866    fn bitor(self, rhs: Self) -> Self {
1867        Self(self.0 | rhs.0)
1868    }
1869}
1870
1871impl core::ops::BitAnd for ForceFlag {
1872    type Output = Self;
1873    #[inline]
1874    fn bitand(self, rhs: Self) -> Self {
1875        Self(self.0 & rhs.0)
1876    }
1877}
1878
1879impl core::ops::Not for ForceFlag {
1880    type Output = Self;
1881    #[inline]
1882    fn not(self) -> Self {
1883        Self(!self.0)
1884    }
1885}
1886
1887impl core::fmt::Debug for ForceFlag {
1888    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1889        write!(f, "ForceFlag({:#x})", self.0)
1890    }
1891}
1892
1893/// Rigid body flags (PHRB.flags)
1894/// Bit flags. Combine with `|`, test with [`RigidBodyFlag::contains`].
1895#[derive(Clone, Copy, PartialEq, Eq, Hash, Default)]
1896pub struct RigidBodyFlag(pub i32);
1897
1898impl RigidBodyFlag {
1899    pub const NONE: Self = Self(0);
1900    /// Can collide
1901    pub const COLLIDABLE: Self = Self(1);
1902    /// Walkable surface
1903    pub const WALKABLE: Self = Self(2);
1904    /// Can be stacked
1905    pub const STACKABLE: Self = Self(4);
1906    /// Simulate collisions
1907    pub const SIMULATE_COLLISION: Self = Self(8);
1908    /// Ignore local bodies
1909    pub const IGNORE_LOCAL_BODIES: Self = Self(16);
1910    /// Always present
1911    pub const ALWAYS_EXISTS: Self = Self(32);
1912    /// Unknown
1913    pub const UNKNOWN_6: Self = Self(64);
1914    /// Disable simulation
1915    pub const NO_SIMULATION: Self = Self(128);
1916    /// Unknown
1917    pub const UNKNOWN_9: Self = Self(512);
1918
1919    #[inline]
1920    pub const fn contains(self, other: Self) -> bool {
1921        (self.0 & other.0) == other.0
1922    }
1923
1924    #[inline]
1925    pub const fn is_empty(self) -> bool {
1926        self.0 == 0
1927    }
1928}
1929
1930impl core::ops::BitOr for RigidBodyFlag {
1931    type Output = Self;
1932    #[inline]
1933    fn bitor(self, rhs: Self) -> Self {
1934        Self(self.0 | rhs.0)
1935    }
1936}
1937
1938impl core::ops::BitAnd for RigidBodyFlag {
1939    type Output = Self;
1940    #[inline]
1941    fn bitand(self, rhs: Self) -> Self {
1942        Self(self.0 & rhs.0)
1943    }
1944}
1945
1946impl core::ops::Not for RigidBodyFlag {
1947    type Output = Self;
1948    #[inline]
1949    fn not(self) -> Self {
1950        Self(!self.0)
1951    }
1952}
1953
1954impl core::fmt::Debug for RigidBodyFlag {
1955    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1956        write!(f, "RigidBodyFlag({:#x})", self.0)
1957    }
1958}
1959
1960/// Color stored as BGRA (4 bytes)
1961///
1962/// Blue-green-red-alpha byte order, matching the M3 on-disk format.
1963pub struct ColorBGRA {
1964    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3ColorBGRA>,
1965}
1966
1967impl Drop for ColorBGRA {
1968    fn drop(&mut self) {
1969        // SAFETY: `raw` came from a native constructor and Drop runs once.
1970        unsafe { ffi::whiteout_m3_M3ColorBGRA_delete(self.raw.as_ptr()) }
1971    }
1972}
1973
1974impl ColorBGRA {
1975    /// # Safety
1976    /// `raw` must be a live handle this value takes ownership of.
1977    #[allow(dead_code)] // used by whichever methods return this type
1978    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3ColorBGRA) -> Option<Self> {
1979        core::ptr::NonNull::new(raw).map(|raw| ColorBGRA { raw })
1980    }
1981}
1982
1983// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
1984// is deliberately NOT implemented — the C++ types make no documented
1985// guarantee about concurrent use, and claiming one we haven't verified
1986// would be unsound. See `@bind thread_safe` in the plan.
1987unsafe impl Send for ColorBGRA {}
1988
1989impl core::fmt::Debug for ColorBGRA {
1990    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1991        f.debug_struct("ColorBGRA").finish_non_exhaustive()
1992    }
1993}
1994
1995impl ColorBGRA {
1996    /// # Panics
1997    /// Panics if the native allocation fails.
1998    pub fn new() -> Self {
1999        // SAFETY: the native constructor returns a live handle; a null here
2000        // means the library is unusable.
2001        unsafe {
2002            let raw = ffi::whiteout_m3_M3ColorBGRA_new();
2003            Self::from_raw(raw).expect("native ColorBGRA allocation failed")
2004        }
2005    }
2006
2007    /// Blue channel
2008    pub fn b(&self) -> u8 {
2009        // SAFETY: plain scalar read through a live handle.
2010        unsafe { ffi::whiteout_m3_M3ColorBGRA_get_b(self.raw.as_ptr()) }
2011    }
2012
2013    pub fn set_b(&mut self, value: u8) {
2014        // SAFETY: plain scalar write through a live handle.
2015        unsafe { ffi::whiteout_m3_M3ColorBGRA_set_b(self.raw.as_ptr(), value) }
2016    }
2017
2018    /// Green channel
2019    pub fn g(&self) -> u8 {
2020        // SAFETY: plain scalar read through a live handle.
2021        unsafe { ffi::whiteout_m3_M3ColorBGRA_get_g(self.raw.as_ptr()) }
2022    }
2023
2024    pub fn set_g(&mut self, value: u8) {
2025        // SAFETY: plain scalar write through a live handle.
2026        unsafe { ffi::whiteout_m3_M3ColorBGRA_set_g(self.raw.as_ptr(), value) }
2027    }
2028
2029    /// Red channel
2030    pub fn r(&self) -> u8 {
2031        // SAFETY: plain scalar read through a live handle.
2032        unsafe { ffi::whiteout_m3_M3ColorBGRA_get_r(self.raw.as_ptr()) }
2033    }
2034
2035    pub fn set_r(&mut self, value: u8) {
2036        // SAFETY: plain scalar write through a live handle.
2037        unsafe { ffi::whiteout_m3_M3ColorBGRA_set_r(self.raw.as_ptr(), value) }
2038    }
2039
2040    /// Alpha channel
2041    pub fn a(&self) -> u8 {
2042        // SAFETY: plain scalar read through a live handle.
2043        unsafe { ffi::whiteout_m3_M3ColorBGRA_get_a(self.raw.as_ptr()) }
2044    }
2045
2046    pub fn set_a(&mut self, value: u8) {
2047        // SAFETY: plain scalar write through a live handle.
2048        unsafe { ffi::whiteout_m3_M3ColorBGRA_set_a(self.raw.as_ptr(), value) }
2049    }
2050}
2051
2052impl Default for ColorBGRA {
2053    fn default() -> Self {
2054        Self::new()
2055    }
2056}
2057
2058pub struct ColorBGR {
2059    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3ColorBGR>,
2060}
2061
2062impl Drop for ColorBGR {
2063    fn drop(&mut self) {
2064        // SAFETY: `raw` came from a native constructor and Drop runs once.
2065        unsafe { ffi::whiteout_m3_M3ColorBGR_delete(self.raw.as_ptr()) }
2066    }
2067}
2068
2069impl ColorBGR {
2070    /// # Safety
2071    /// `raw` must be a live handle this value takes ownership of.
2072    #[allow(dead_code)] // used by whichever methods return this type
2073    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3ColorBGR) -> Option<Self> {
2074        core::ptr::NonNull::new(raw).map(|raw| ColorBGR { raw })
2075    }
2076}
2077
2078// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
2079// is deliberately NOT implemented — the C++ types make no documented
2080// guarantee about concurrent use, and claiming one we haven't verified
2081// would be unsound. See `@bind thread_safe` in the plan.
2082unsafe impl Send for ColorBGR {}
2083
2084impl core::fmt::Debug for ColorBGR {
2085    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2086        f.debug_struct("ColorBGR").finish_non_exhaustive()
2087    }
2088}
2089
2090impl ColorBGR {
2091    /// # Panics
2092    /// Panics if the native allocation fails.
2093    pub fn new() -> Self {
2094        // SAFETY: the native constructor returns a live handle; a null here
2095        // means the library is unusable.
2096        unsafe {
2097            let raw = ffi::whiteout_m3_M3ColorBGR_new();
2098            Self::from_raw(raw).expect("native ColorBGR allocation failed")
2099        }
2100    }
2101
2102    /// Blue channel
2103    pub fn b(&self) -> u8 {
2104        // SAFETY: plain scalar read through a live handle.
2105        unsafe { ffi::whiteout_m3_M3ColorBGR_get_b(self.raw.as_ptr()) }
2106    }
2107
2108    pub fn set_b(&mut self, value: u8) {
2109        // SAFETY: plain scalar write through a live handle.
2110        unsafe { ffi::whiteout_m3_M3ColorBGR_set_b(self.raw.as_ptr(), value) }
2111    }
2112
2113    /// Green channel
2114    pub fn g(&self) -> u8 {
2115        // SAFETY: plain scalar read through a live handle.
2116        unsafe { ffi::whiteout_m3_M3ColorBGR_get_g(self.raw.as_ptr()) }
2117    }
2118
2119    pub fn set_g(&mut self, value: u8) {
2120        // SAFETY: plain scalar write through a live handle.
2121        unsafe { ffi::whiteout_m3_M3ColorBGR_set_g(self.raw.as_ptr(), value) }
2122    }
2123
2124    /// Red channel
2125    pub fn r(&self) -> u8 {
2126        // SAFETY: plain scalar read through a live handle.
2127        unsafe { ffi::whiteout_m3_M3ColorBGR_get_r(self.raw.as_ptr()) }
2128    }
2129
2130    pub fn set_r(&mut self, value: u8) {
2131        // SAFETY: plain scalar write through a live handle.
2132        unsafe { ffi::whiteout_m3_M3ColorBGR_set_r(self.raw.as_ptr(), value) }
2133    }
2134}
2135
2136impl Default for ColorBGR {
2137    fn default() -> Self {
2138        Self::new()
2139    }
2140}
2141
2142/// Axis-aligned bounding box with bounding sphere radius (28 bytes)
2143///
2144/// Used throughout M3 for model bounds, collision bounds, and per-region extents.
2145pub struct Extent {
2146    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3Extent>,
2147}
2148
2149impl Drop for Extent {
2150    fn drop(&mut self) {
2151        // SAFETY: `raw` came from a native constructor and Drop runs once.
2152        unsafe { ffi::whiteout_m3_M3Extent_delete(self.raw.as_ptr()) }
2153    }
2154}
2155
2156impl Extent {
2157    /// # Safety
2158    /// `raw` must be a live handle this value takes ownership of.
2159    #[allow(dead_code)] // used by whichever methods return this type
2160    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3Extent) -> Option<Self> {
2161        core::ptr::NonNull::new(raw).map(|raw| Extent { raw })
2162    }
2163}
2164
2165// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
2166// is deliberately NOT implemented — the C++ types make no documented
2167// guarantee about concurrent use, and claiming one we haven't verified
2168// would be unsound. See `@bind thread_safe` in the plan.
2169unsafe impl Send for Extent {}
2170
2171impl core::fmt::Debug for Extent {
2172    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2173        f.debug_struct("Extent").finish_non_exhaustive()
2174    }
2175}
2176
2177impl Extent {
2178    /// # Panics
2179    /// Panics if the native allocation fails.
2180    pub fn new() -> Self {
2181        // SAFETY: the native constructor returns a live handle; a null here
2182        // means the library is unusable.
2183        unsafe {
2184            let raw = ffi::whiteout_m3_M3Extent_new();
2185            Self::from_raw(raw).expect("native Extent allocation failed")
2186        }
2187    }
2188
2189    /// AABB minimum corner
2190    pub fn min(&self) -> crate::math::Vector3f {
2191        // SAFETY: the getter returns an interior pointer to a
2192        // layout-identical POD; we copy it out immediately.
2193        unsafe {
2194            *(ffi::whiteout_m3_M3Extent_get_min(self.raw.as_ptr()) as *const crate::math::Vector3f)
2195        }
2196    }
2197
2198    pub fn set_min(&mut self, value: crate::math::Vector3f) {
2199        // SAFETY: as above, in the other direction.
2200        unsafe {
2201            ffi::whiteout_m3_M3Extent_set_min(
2202                self.raw.as_ptr(),
2203                &value as *const crate::math::Vector3f as *const _,
2204            )
2205        }
2206    }
2207
2208    /// AABB maximum corner
2209    pub fn max(&self) -> crate::math::Vector3f {
2210        // SAFETY: the getter returns an interior pointer to a
2211        // layout-identical POD; we copy it out immediately.
2212        unsafe {
2213            *(ffi::whiteout_m3_M3Extent_get_max(self.raw.as_ptr()) as *const crate::math::Vector3f)
2214        }
2215    }
2216
2217    pub fn set_max(&mut self, value: crate::math::Vector3f) {
2218        // SAFETY: as above, in the other direction.
2219        unsafe {
2220            ffi::whiteout_m3_M3Extent_set_max(
2221                self.raw.as_ptr(),
2222                &value as *const crate::math::Vector3f as *const _,
2223            )
2224        }
2225    }
2226
2227    /// Bounding sphere radius
2228    pub fn radius(&self) -> f32 {
2229        // SAFETY: plain scalar read through a live handle.
2230        unsafe { ffi::whiteout_m3_M3Extent_get_radius(self.raw.as_ptr()) }
2231    }
2232
2233    pub fn set_radius(&mut self, value: f32) {
2234        // SAFETY: plain scalar write through a live handle.
2235        unsafe { ffi::whiteout_m3_M3Extent_set_radius(self.raw.as_ptr(), value) }
2236    }
2237}
2238
2239impl Default for Extent {
2240    fn default() -> Self {
2241        Self::new()
2242    }
2243}
2244
2245/// EVNT — Animation event (v0–v2, 104–108 bytes)
2246///
2247/// Named event triggered at a specific bone with an optional type code and parameter string. Used for sound cues, spawn effects, etc.
2248pub struct Event {
2249    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3Event>,
2250}
2251
2252impl Drop for Event {
2253    fn drop(&mut self) {
2254        // SAFETY: `raw` came from a native constructor and Drop runs once.
2255        unsafe { ffi::whiteout_m3_M3Event_delete(self.raw.as_ptr()) }
2256    }
2257}
2258
2259impl Event {
2260    /// # Safety
2261    /// `raw` must be a live handle this value takes ownership of.
2262    #[allow(dead_code)] // used by whichever methods return this type
2263    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3Event) -> Option<Self> {
2264        core::ptr::NonNull::new(raw).map(|raw| Event { raw })
2265    }
2266}
2267
2268// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
2269// is deliberately NOT implemented — the C++ types make no documented
2270// guarantee about concurrent use, and claiming one we haven't verified
2271// would be unsound. See `@bind thread_safe` in the plan.
2272unsafe impl Send for Event {}
2273
2274impl core::fmt::Debug for Event {
2275    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2276        f.debug_struct("Event").finish_non_exhaustive()
2277    }
2278}
2279
2280impl Event {
2281    /// # Panics
2282    /// Panics if the native allocation fails.
2283    pub fn new() -> Self {
2284        // SAFETY: the native constructor returns a live handle; a null here
2285        // means the library is unusable.
2286        unsafe {
2287            let raw = ffi::whiteout_m3_M3Event_new();
2288            Self::from_raw(raw).expect("native Event allocation failed")
2289        }
2290    }
2291
2292    /// Event name (`Ref<CHAR>`)
2293    pub fn name(&self) -> String {
2294        // SAFETY: the native side hands over an owned CString.
2295        unsafe { crate::support::take_string(ffi::whiteout_m3_M3Event_get_name(self.raw.as_ptr())) }
2296    }
2297
2298    pub fn set_name(&mut self, value: &str) {
2299        let value = std::ffi::CString::new(value).unwrap_or_default();
2300        // SAFETY: the pointer outlives the call.
2301        unsafe { ffi::whiteout_m3_M3Event_set_name(self.raw.as_ptr(), value.as_ptr()) }
2302    }
2303
2304    /// Unknown field
2305    pub fn unknown(&self) -> u32 {
2306        // SAFETY: plain scalar read through a live handle.
2307        unsafe { ffi::whiteout_m3_M3Event_get_unknown(self.raw.as_ptr()) }
2308    }
2309
2310    pub fn set_unknown(&mut self, value: u32) {
2311        // SAFETY: plain scalar write through a live handle.
2312        unsafe { ffi::whiteout_m3_M3Event_set_unknown(self.raw.as_ptr(), value) }
2313    }
2314
2315    /// Index into BONE array
2316    pub fn bone_index(&self) -> u16 {
2317        // SAFETY: plain scalar read through a live handle.
2318        unsafe { ffi::whiteout_m3_M3Event_get_boneIndex(self.raw.as_ptr()) }
2319    }
2320
2321    pub fn set_bone_index(&mut self, value: u16) {
2322        // SAFETY: plain scalar write through a live handle.
2323        unsafe { ffi::whiteout_m3_M3Event_set_boneIndex(self.raw.as_ptr(), value) }
2324    }
2325
2326    /// Alignment padding
2327    pub fn padding(&self) -> u16 {
2328        // SAFETY: plain scalar read through a live handle.
2329        unsafe { ffi::whiteout_m3_M3Event_get_padding(self.raw.as_ptr()) }
2330    }
2331
2332    pub fn set_padding(&mut self, value: u16) {
2333        // SAFETY: plain scalar write through a live handle.
2334        unsafe { ffi::whiteout_m3_M3Event_set_padding(self.raw.as_ptr(), value) }
2335    }
2336
2337    /// Engine-specific event type code
2338    pub fn event_type(&self) -> u32 {
2339        // SAFETY: plain scalar read through a live handle.
2340        unsafe { ffi::whiteout_m3_M3Event_get_eventType(self.raw.as_ptr()) }
2341    }
2342
2343    pub fn set_event_type(&mut self, value: u32) {
2344        // SAFETY: plain scalar write through a live handle.
2345        unsafe { ffi::whiteout_m3_M3Event_set_eventType(self.raw.as_ptr(), value) }
2346    }
2347
2348    /// Optional parameter string (`Ref<CHAR>`)
2349    pub fn option_string(&self) -> String {
2350        // SAFETY: the native side hands over an owned CString.
2351        unsafe {
2352            crate::support::take_string(ffi::whiteout_m3_M3Event_get_optionString(
2353                self.raw.as_ptr(),
2354            ))
2355        }
2356    }
2357
2358    pub fn set_option_string(&mut self, value: &str) {
2359        let value = std::ffi::CString::new(value).unwrap_or_default();
2360        // SAFETY: the pointer outlives the call.
2361        unsafe { ffi::whiteout_m3_M3Event_set_optionString(self.raw.as_ptr(), value.as_ptr()) }
2362    }
2363
2364    /// RTT channel index
2365    pub fn rtt_channel_index(&self) -> u32 {
2366        // SAFETY: plain scalar read through a live handle.
2367        unsafe { ffi::whiteout_m3_M3Event_get_rttChannelIndex(self.raw.as_ptr()) }
2368    }
2369
2370    pub fn set_rtt_channel_index(&mut self, value: u32) {
2371        // SAFETY: plain scalar write through a live handle.
2372        unsafe { ffi::whiteout_m3_M3Event_set_rttChannelIndex(self.raw.as_ptr(), value) }
2373    }
2374
2375    /// Extra parameter (v2+)
2376    pub fn extra_parameter(&self) -> u32 {
2377        // SAFETY: plain scalar read through a live handle.
2378        unsafe { ffi::whiteout_m3_M3Event_get_extraParameter(self.raw.as_ptr()) }
2379    }
2380
2381    pub fn set_extra_parameter(&mut self, value: u32) {
2382        // SAFETY: plain scalar write through a live handle.
2383        unsafe { ffi::whiteout_m3_M3Event_set_extraParameter(self.raw.as_ptr(), value) }
2384    }
2385}
2386
2387impl Default for Event {
2388    fn default() -> Self {
2389        Self::new()
2390    }
2391}
2392
2393/// SEQS — Animation sequence (v0–v2, up to 92 bytes)
2394///
2395/// Defines a named animation clip with frame range, playback speed, looping flags, blend time, and bounding volume.
2396pub struct Sequence {
2397    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3Sequence>,
2398}
2399
2400impl Drop for Sequence {
2401    fn drop(&mut self) {
2402        // SAFETY: `raw` came from a native constructor and Drop runs once.
2403        unsafe { ffi::whiteout_m3_M3Sequence_delete(self.raw.as_ptr()) }
2404    }
2405}
2406
2407impl Sequence {
2408    /// # Safety
2409    /// `raw` must be a live handle this value takes ownership of.
2410    #[allow(dead_code)] // used by whichever methods return this type
2411    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3Sequence) -> Option<Self> {
2412        core::ptr::NonNull::new(raw).map(|raw| Sequence { raw })
2413    }
2414}
2415
2416// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
2417// is deliberately NOT implemented — the C++ types make no documented
2418// guarantee about concurrent use, and claiming one we haven't verified
2419// would be unsound. See `@bind thread_safe` in the plan.
2420unsafe impl Send for Sequence {}
2421
2422impl core::fmt::Debug for Sequence {
2423    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2424        f.debug_struct("Sequence").finish_non_exhaustive()
2425    }
2426}
2427
2428impl Sequence {
2429    /// # Panics
2430    /// Panics if the native allocation fails.
2431    pub fn new() -> Self {
2432        // SAFETY: the native constructor returns a live handle; a null here
2433        // means the library is unusable.
2434        unsafe {
2435            let raw = ffi::whiteout_m3_M3Sequence_new();
2436            Self::from_raw(raw).expect("native Sequence allocation failed")
2437        }
2438    }
2439
2440    /// Unique sequence identifier
2441    pub fn id(&self) -> i32 {
2442        // SAFETY: plain scalar read through a live handle.
2443        unsafe { ffi::whiteout_m3_M3Sequence_get_id(self.raw.as_ptr()) }
2444    }
2445
2446    pub fn set_id(&mut self, value: i32) {
2447        // SAFETY: plain scalar write through a live handle.
2448        unsafe { ffi::whiteout_m3_M3Sequence_set_id(self.raw.as_ptr(), value) }
2449    }
2450
2451    /// Sequence index
2452    pub fn index(&self) -> i32 {
2453        // SAFETY: plain scalar read through a live handle.
2454        unsafe { ffi::whiteout_m3_M3Sequence_get_index(self.raw.as_ptr()) }
2455    }
2456
2457    pub fn set_index(&mut self, value: i32) {
2458        // SAFETY: plain scalar write through a live handle.
2459        unsafe { ffi::whiteout_m3_M3Sequence_set_index(self.raw.as_ptr(), value) }
2460    }
2461
2462    /// Sequence name (`Ref<CHAR>`)
2463    pub fn name(&self) -> String {
2464        // SAFETY: the native side hands over an owned CString.
2465        unsafe {
2466            crate::support::take_string(ffi::whiteout_m3_M3Sequence_get_name(self.raw.as_ptr()))
2467        }
2468    }
2469
2470    pub fn set_name(&mut self, value: &str) {
2471        let value = std::ffi::CString::new(value).unwrap_or_default();
2472        // SAFETY: the pointer outlives the call.
2473        unsafe { ffi::whiteout_m3_M3Sequence_set_name(self.raw.as_ptr(), value.as_ptr()) }
2474    }
2475
2476    /// First frame (inclusive)
2477    pub fn start_frame(&self) -> u32 {
2478        // SAFETY: plain scalar read through a live handle.
2479        unsafe { ffi::whiteout_m3_M3Sequence_get_startFrame(self.raw.as_ptr()) }
2480    }
2481
2482    pub fn set_start_frame(&mut self, value: u32) {
2483        // SAFETY: plain scalar write through a live handle.
2484        unsafe { ffi::whiteout_m3_M3Sequence_set_startFrame(self.raw.as_ptr(), value) }
2485    }
2486
2487    /// Last frame (inclusive)
2488    pub fn end_frame(&self) -> u32 {
2489        // SAFETY: plain scalar read through a live handle.
2490        unsafe { ffi::whiteout_m3_M3Sequence_get_endFrame(self.raw.as_ptr()) }
2491    }
2492
2493    pub fn set_end_frame(&mut self, value: u32) {
2494        // SAFETY: plain scalar write through a live handle.
2495        unsafe { ffi::whiteout_m3_M3Sequence_set_endFrame(self.raw.as_ptr(), value) }
2496    }
2497
2498    /// Movement speed multiplier
2499    pub fn move_speed(&self) -> f32 {
2500        // SAFETY: plain scalar read through a live handle.
2501        unsafe { ffi::whiteout_m3_M3Sequence_get_moveSpeed(self.raw.as_ptr()) }
2502    }
2503
2504    pub fn set_move_speed(&mut self, value: f32) {
2505        // SAFETY: plain scalar write through a live handle.
2506        unsafe { ffi::whiteout_m3_M3Sequence_set_moveSpeed(self.raw.as_ptr(), value) }
2507    }
2508
2509    /// Playback flags (loop, global, etc.)
2510    pub fn flags(&self) -> SequenceFlag {
2511        // SAFETY: scalar read; a flag set accepts any bits.
2512        SequenceFlag(unsafe { ffi::whiteout_m3_M3Sequence_get_flags(self.raw.as_ptr()) })
2513    }
2514
2515    pub fn set_flags(&mut self, value: SequenceFlag) {
2516        // SAFETY: scalar write through a live handle.
2517        unsafe { ffi::whiteout_m3_M3Sequence_set_flags(self.raw.as_ptr(), value.0) }
2518    }
2519
2520    /// Selection frequency / priority weight
2521    pub fn frequency(&self) -> u32 {
2522        // SAFETY: plain scalar read through a live handle.
2523        unsafe { ffi::whiteout_m3_M3Sequence_get_frequency(self.raw.as_ptr()) }
2524    }
2525
2526    pub fn set_frequency(&mut self, value: u32) {
2527        // SAFETY: plain scalar write through a live handle.
2528        unsafe { ffi::whiteout_m3_M3Sequence_set_frequency(self.raw.as_ptr(), value) }
2529    }
2530
2531    /// Replay region start frame
2532    pub fn replay_start(&self) -> u32 {
2533        // SAFETY: plain scalar read through a live handle.
2534        unsafe { ffi::whiteout_m3_M3Sequence_get_replayStart(self.raw.as_ptr()) }
2535    }
2536
2537    pub fn set_replay_start(&mut self, value: u32) {
2538        // SAFETY: plain scalar write through a live handle.
2539        unsafe { ffi::whiteout_m3_M3Sequence_set_replayStart(self.raw.as_ptr(), value) }
2540    }
2541
2542    /// Replay region end frame
2543    pub fn replay_end(&self) -> u32 {
2544        // SAFETY: plain scalar read through a live handle.
2545        unsafe { ffi::whiteout_m3_M3Sequence_get_replayEnd(self.raw.as_ptr()) }
2546    }
2547
2548    pub fn set_replay_end(&mut self, value: u32) {
2549        // SAFETY: plain scalar write through a live handle.
2550        unsafe { ffi::whiteout_m3_M3Sequence_set_replayEnd(self.raw.as_ptr(), value) }
2551    }
2552
2553    /// Blend-in time (ms)
2554    pub fn blend_time(&self) -> u32 {
2555        // SAFETY: plain scalar read through a live handle.
2556        unsafe { ffi::whiteout_m3_M3Sequence_get_blendTime(self.raw.as_ptr()) }
2557    }
2558
2559    pub fn set_blend_time(&mut self, value: u32) {
2560        // SAFETY: plain scalar write through a live handle.
2561        unsafe { ffi::whiteout_m3_M3Sequence_set_blendTime(self.raw.as_ptr(), value) }
2562    }
2563
2564    /// Animated bounding volume
2565    /// Borrows the field in place — no copy, no allocation.
2566    pub fn bounds(&self) -> crate::support::Ref<'_, Extent> {
2567        // SAFETY: an interior pointer into `self`, valid for this
2568        // borrow and never freed by the `Ref`.
2569        unsafe {
2570            crate::support::Ref::new(Extent {
2571                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Sequence_get_bounds(
2572                    self.raw.as_ptr(),
2573                )),
2574            })
2575        }
2576    }
2577
2578    pub fn bounds_mut(&mut self) -> crate::support::RefMut<'_, Extent> {
2579        // SAFETY: as above; `&mut self` guarantees exclusivity.
2580        unsafe {
2581            crate::support::RefMut::new(Extent {
2582                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Sequence_get_bounds(
2583                    self.raw.as_ptr(),
2584                )),
2585            })
2586        }
2587    }
2588
2589    /// Animation set indices (U8__)
2590    /// Zero-copy view of the underlying `std::vector`.
2591    pub fn animation_sets(&self) -> &[u8] {
2592        // SAFETY: `_data`/`_count` describe one contiguous C++
2593        // allocation, borrowed for as long as `self` is.
2594        unsafe {
2595            let n = ffi::whiteout_m3_M3Sequence_get_animationSets_count(self.raw.as_ptr());
2596            let p = ffi::whiteout_m3_M3Sequence_get_animationSets_data(self.raw.as_ptr());
2597            if p.is_null() || n == 0 {
2598                &[]
2599            } else {
2600                core::slice::from_raw_parts(p, n)
2601            }
2602        }
2603    }
2604
2605    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
2606    pub fn animation_sets_mut(&mut self) -> &mut [u8] {
2607        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
2608        unsafe {
2609            let n = ffi::whiteout_m3_M3Sequence_get_animationSets_count(self.raw.as_ptr());
2610            let p =
2611                ffi::whiteout_m3_M3Sequence_get_animationSets_data(self.raw.as_ptr()) as *mut u8;
2612            if p.is_null() || n == 0 {
2613                &mut []
2614            } else {
2615                core::slice::from_raw_parts_mut(p, n)
2616            }
2617        }
2618    }
2619
2620    pub fn set_animation_sets(&mut self, values: &[u8]) {
2621        // SAFETY: the native side copies `values` before returning.
2622        unsafe {
2623            ffi::whiteout_m3_M3Sequence_assign_animationSets(
2624                self.raw.as_ptr(),
2625                values.as_ptr() as *const _,
2626                values.len(),
2627            )
2628        }
2629    }
2630
2631    pub fn resize_animation_sets(&mut self, count: usize) {
2632        // SAFETY: reallocation is safe here precisely because
2633        // `&mut self` means no slice borrow is outstanding.
2634        unsafe { ffi::whiteout_m3_M3Sequence_resize_animationSets(self.raw.as_ptr(), count) }
2635    }
2636}
2637
2638impl Default for Sequence {
2639    fn default() -> Self {
2640        Self::new()
2641    }
2642}
2643
2644/// STC_ — Sub-track container (v0–v4, 204 bytes)
2645///
2646/// Binds animation IDs to concrete keyframe data stored in 13 typed AnimBlock arrays (slots 0–12). Each slot handles a different value type: events, vectors, quaternions, colors, scalars, flags, and bounding extents.
2647pub struct SubTrackContainer {
2648    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3SubTrackContainer>,
2649}
2650
2651impl Drop for SubTrackContainer {
2652    fn drop(&mut self) {
2653        // SAFETY: `raw` came from a native constructor and Drop runs once.
2654        unsafe { ffi::whiteout_m3_M3SubTrackContainer_delete(self.raw.as_ptr()) }
2655    }
2656}
2657
2658impl SubTrackContainer {
2659    /// # Safety
2660    /// `raw` must be a live handle this value takes ownership of.
2661    #[allow(dead_code)] // used by whichever methods return this type
2662    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3SubTrackContainer) -> Option<Self> {
2663        core::ptr::NonNull::new(raw).map(|raw| SubTrackContainer { raw })
2664    }
2665}
2666
2667// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
2668// is deliberately NOT implemented — the C++ types make no documented
2669// guarantee about concurrent use, and claiming one we haven't verified
2670// would be unsound. See `@bind thread_safe` in the plan.
2671unsafe impl Send for SubTrackContainer {}
2672
2673impl core::fmt::Debug for SubTrackContainer {
2674    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2675        f.debug_struct("SubTrackContainer").finish_non_exhaustive()
2676    }
2677}
2678
2679impl SubTrackContainer {
2680    /// # Panics
2681    /// Panics if the native allocation fails.
2682    pub fn new() -> Self {
2683        // SAFETY: the native constructor returns a live handle; a null here
2684        // means the library is unusable.
2685        unsafe {
2686            let raw = ffi::whiteout_m3_M3SubTrackContainer_new();
2687            Self::from_raw(raw).expect("native SubTrackContainer allocation failed")
2688        }
2689    }
2690
2691    /// Container name (`Ref<CHAR>`)
2692    pub fn name(&self) -> String {
2693        // SAFETY: the native side hands over an owned CString.
2694        unsafe {
2695            crate::support::take_string(ffi::whiteout_m3_M3SubTrackContainer_get_name(
2696                self.raw.as_ptr(),
2697            ))
2698        }
2699    }
2700
2701    pub fn set_name(&mut self, value: &str) {
2702        let value = std::ffi::CString::new(value).unwrap_or_default();
2703        // SAFETY: the pointer outlives the call.
2704        unsafe { ffi::whiteout_m3_M3SubTrackContainer_set_name(self.raw.as_ptr(), value.as_ptr()) }
2705    }
2706
2707    /// Non-zero if runs concurrently
2708    pub fn runs_concurrent(&self) -> u16 {
2709        // SAFETY: plain scalar read through a live handle.
2710        unsafe { ffi::whiteout_m3_M3SubTrackContainer_get_runsConcurrent(self.raw.as_ptr()) }
2711    }
2712
2713    pub fn set_runs_concurrent(&mut self, value: u16) {
2714        // SAFETY: plain scalar write through a live handle.
2715        unsafe { ffi::whiteout_m3_M3SubTrackContainer_set_runsConcurrent(self.raw.as_ptr(), value) }
2716    }
2717
2718    /// Animation priority level
2719    pub fn anim_priority(&self) -> u16 {
2720        // SAFETY: plain scalar read through a live handle.
2721        unsafe { ffi::whiteout_m3_M3SubTrackContainer_get_animPriority(self.raw.as_ptr()) }
2722    }
2723
2724    pub fn set_anim_priority(&mut self, value: u16) {
2725        // SAFETY: plain scalar write through a live handle.
2726        unsafe { ffi::whiteout_m3_M3SubTrackContainer_set_animPriority(self.raw.as_ptr(), value) }
2727    }
2728
2729    /// Parent STS_ index
2730    pub fn animation_state_index(&self) -> u16 {
2731        // SAFETY: plain scalar read through a live handle.
2732        unsafe { ffi::whiteout_m3_M3SubTrackContainer_get_animationStateIndex(self.raw.as_ptr()) }
2733    }
2734
2735    pub fn set_animation_state_index(&mut self, value: u16) {
2736        // SAFETY: plain scalar write through a live handle.
2737        unsafe {
2738            ffi::whiteout_m3_M3SubTrackContainer_set_animationStateIndex(self.raw.as_ptr(), value)
2739        }
2740    }
2741
2742    /// Alignment padding
2743    pub fn padding(&self) -> u16 {
2744        // SAFETY: plain scalar read through a live handle.
2745        unsafe { ffi::whiteout_m3_M3SubTrackContainer_get_padding(self.raw.as_ptr()) }
2746    }
2747
2748    pub fn set_padding(&mut self, value: u16) {
2749        // SAFETY: plain scalar write through a live handle.
2750        unsafe { ffi::whiteout_m3_M3SubTrackContainer_set_padding(self.raw.as_ptr(), value) }
2751    }
2752
2753    /// Animation IDs (U32_)
2754    /// Zero-copy view of the underlying `std::vector`.
2755    pub fn anim_ids(&self) -> &[u32] {
2756        // SAFETY: `_data`/`_count` describe one contiguous C++
2757        // allocation, borrowed for as long as `self` is.
2758        unsafe {
2759            let n = ffi::whiteout_m3_M3SubTrackContainer_get_animIds_count(self.raw.as_ptr());
2760            let p = ffi::whiteout_m3_M3SubTrackContainer_get_animIds_data(self.raw.as_ptr());
2761            if p.is_null() || n == 0 {
2762                &[]
2763            } else {
2764                core::slice::from_raw_parts(p, n)
2765            }
2766        }
2767    }
2768
2769    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
2770    pub fn anim_ids_mut(&mut self) -> &mut [u32] {
2771        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
2772        unsafe {
2773            let n = ffi::whiteout_m3_M3SubTrackContainer_get_animIds_count(self.raw.as_ptr());
2774            let p = ffi::whiteout_m3_M3SubTrackContainer_get_animIds_data(self.raw.as_ptr())
2775                as *mut u32;
2776            if p.is_null() || n == 0 {
2777                &mut []
2778            } else {
2779                core::slice::from_raw_parts_mut(p, n)
2780            }
2781        }
2782    }
2783
2784    pub fn set_anim_ids(&mut self, values: &[u32]) {
2785        // SAFETY: the native side copies `values` before returning.
2786        unsafe {
2787            ffi::whiteout_m3_M3SubTrackContainer_assign_animIds(
2788                self.raw.as_ptr(),
2789                values.as_ptr() as *const _,
2790                values.len(),
2791            )
2792        }
2793    }
2794
2795    pub fn resize_anim_ids(&mut self, count: usize) {
2796        // SAFETY: reallocation is safe here precisely because
2797        // `&mut self` means no slice borrow is outstanding.
2798        unsafe { ffi::whiteout_m3_M3SubTrackContainer_resize_animIds(self.raw.as_ptr(), count) }
2799    }
2800
2801    /// Animation reference indices (U32_)
2802    /// Zero-copy view of the underlying `std::vector`.
2803    pub fn anim_refs(&self) -> &[u32] {
2804        // SAFETY: `_data`/`_count` describe one contiguous C++
2805        // allocation, borrowed for as long as `self` is.
2806        unsafe {
2807            let n = ffi::whiteout_m3_M3SubTrackContainer_get_animRefs_count(self.raw.as_ptr());
2808            let p = ffi::whiteout_m3_M3SubTrackContainer_get_animRefs_data(self.raw.as_ptr());
2809            if p.is_null() || n == 0 {
2810                &[]
2811            } else {
2812                core::slice::from_raw_parts(p, n)
2813            }
2814        }
2815    }
2816
2817    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
2818    pub fn anim_refs_mut(&mut self) -> &mut [u32] {
2819        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
2820        unsafe {
2821            let n = ffi::whiteout_m3_M3SubTrackContainer_get_animRefs_count(self.raw.as_ptr());
2822            let p = ffi::whiteout_m3_M3SubTrackContainer_get_animRefs_data(self.raw.as_ptr())
2823                as *mut u32;
2824            if p.is_null() || n == 0 {
2825                &mut []
2826            } else {
2827                core::slice::from_raw_parts_mut(p, n)
2828            }
2829        }
2830    }
2831
2832    pub fn set_anim_refs(&mut self, values: &[u32]) {
2833        // SAFETY: the native side copies `values` before returning.
2834        unsafe {
2835            ffi::whiteout_m3_M3SubTrackContainer_assign_animRefs(
2836                self.raw.as_ptr(),
2837                values.as_ptr() as *const _,
2838                values.len(),
2839            )
2840        }
2841    }
2842
2843    pub fn resize_anim_refs(&mut self, count: usize) {
2844        // SAFETY: reallocation is safe here precisely because
2845        // `&mut self` means no slice borrow is outstanding.
2846        unsafe { ffi::whiteout_m3_M3SubTrackContainer_resize_animRefs(self.raw.as_ptr(), count) }
2847    }
2848
2849    /// Unknown field
2850    pub fn unknown(&self) -> u32 {
2851        // SAFETY: plain scalar read through a live handle.
2852        unsafe { ffi::whiteout_m3_M3SubTrackContainer_get_unknown(self.raw.as_ptr()) }
2853    }
2854
2855    pub fn set_unknown(&mut self, value: u32) {
2856        // SAFETY: plain scalar write through a live handle.
2857        unsafe { ffi::whiteout_m3_M3SubTrackContainer_set_unknown(self.raw.as_ptr(), value) }
2858    }
2859}
2860
2861impl Default for SubTrackContainer {
2862    fn default() -> Self {
2863        Self::new()
2864    }
2865}
2866
2867/// STG_ — Animation group (v0, 24 bytes)
2868///
2869/// Groups sub-track containers by name for organizational purposes.
2870pub struct AnimationGroup {
2871    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3AnimationGroup>,
2872}
2873
2874impl Drop for AnimationGroup {
2875    fn drop(&mut self) {
2876        // SAFETY: `raw` came from a native constructor and Drop runs once.
2877        unsafe { ffi::whiteout_m3_M3AnimationGroup_delete(self.raw.as_ptr()) }
2878    }
2879}
2880
2881impl AnimationGroup {
2882    /// # Safety
2883    /// `raw` must be a live handle this value takes ownership of.
2884    #[allow(dead_code)] // used by whichever methods return this type
2885    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3AnimationGroup) -> Option<Self> {
2886        core::ptr::NonNull::new(raw).map(|raw| AnimationGroup { raw })
2887    }
2888}
2889
2890// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
2891// is deliberately NOT implemented — the C++ types make no documented
2892// guarantee about concurrent use, and claiming one we haven't verified
2893// would be unsound. See `@bind thread_safe` in the plan.
2894unsafe impl Send for AnimationGroup {}
2895
2896impl core::fmt::Debug for AnimationGroup {
2897    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2898        f.debug_struct("AnimationGroup").finish_non_exhaustive()
2899    }
2900}
2901
2902impl AnimationGroup {
2903    /// # Panics
2904    /// Panics if the native allocation fails.
2905    pub fn new() -> Self {
2906        // SAFETY: the native constructor returns a live handle; a null here
2907        // means the library is unusable.
2908        unsafe {
2909            let raw = ffi::whiteout_m3_M3AnimationGroup_new();
2910            Self::from_raw(raw).expect("native AnimationGroup allocation failed")
2911        }
2912    }
2913
2914    /// Group name (`Ref<CHAR>`)
2915    pub fn name(&self) -> String {
2916        // SAFETY: the native side hands over an owned CString.
2917        unsafe {
2918            crate::support::take_string(ffi::whiteout_m3_M3AnimationGroup_get_name(
2919                self.raw.as_ptr(),
2920            ))
2921        }
2922    }
2923
2924    pub fn set_name(&mut self, value: &str) {
2925        let value = std::ffi::CString::new(value).unwrap_or_default();
2926        // SAFETY: the pointer outlives the call.
2927        unsafe { ffi::whiteout_m3_M3AnimationGroup_set_name(self.raw.as_ptr(), value.as_ptr()) }
2928    }
2929
2930    /// Indices into STC_ array (U32_)
2931    /// Zero-copy view of the underlying `std::vector`.
2932    pub fn subtrack_indices(&self) -> &[u32] {
2933        // SAFETY: `_data`/`_count` describe one contiguous C++
2934        // allocation, borrowed for as long as `self` is.
2935        unsafe {
2936            let n = ffi::whiteout_m3_M3AnimationGroup_get_subtrackIndices_count(self.raw.as_ptr());
2937            let p = ffi::whiteout_m3_M3AnimationGroup_get_subtrackIndices_data(self.raw.as_ptr());
2938            if p.is_null() || n == 0 {
2939                &[]
2940            } else {
2941                core::slice::from_raw_parts(p, n)
2942            }
2943        }
2944    }
2945
2946    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
2947    pub fn subtrack_indices_mut(&mut self) -> &mut [u32] {
2948        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
2949        unsafe {
2950            let n = ffi::whiteout_m3_M3AnimationGroup_get_subtrackIndices_count(self.raw.as_ptr());
2951            let p = ffi::whiteout_m3_M3AnimationGroup_get_subtrackIndices_data(self.raw.as_ptr())
2952                as *mut u32;
2953            if p.is_null() || n == 0 {
2954                &mut []
2955            } else {
2956                core::slice::from_raw_parts_mut(p, n)
2957            }
2958        }
2959    }
2960
2961    pub fn set_subtrack_indices(&mut self, values: &[u32]) {
2962        // SAFETY: the native side copies `values` before returning.
2963        unsafe {
2964            ffi::whiteout_m3_M3AnimationGroup_assign_subtrackIndices(
2965                self.raw.as_ptr(),
2966                values.as_ptr() as *const _,
2967                values.len(),
2968            )
2969        }
2970    }
2971
2972    pub fn resize_subtrack_indices(&mut self, count: usize) {
2973        // SAFETY: reallocation is safe here precisely because
2974        // `&mut self` means no slice borrow is outstanding.
2975        unsafe {
2976            ffi::whiteout_m3_M3AnimationGroup_resize_subtrackIndices(self.raw.as_ptr(), count)
2977        }
2978    }
2979}
2980
2981impl Default for AnimationGroup {
2982    fn default() -> Self {
2983        Self::new()
2984    }
2985}
2986
2987/// STS_ — Animation state (v0, 28 bytes)
2988///
2989/// Top-level animation state containing a set of animation IDs and 16 bytes of unknown state data.
2990pub struct AnimationState {
2991    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3AnimationState>,
2992}
2993
2994impl Drop for AnimationState {
2995    fn drop(&mut self) {
2996        // SAFETY: `raw` came from a native constructor and Drop runs once.
2997        unsafe { ffi::whiteout_m3_M3AnimationState_delete(self.raw.as_ptr()) }
2998    }
2999}
3000
3001impl AnimationState {
3002    /// # Safety
3003    /// `raw` must be a live handle this value takes ownership of.
3004    #[allow(dead_code)] // used by whichever methods return this type
3005    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3AnimationState) -> Option<Self> {
3006        core::ptr::NonNull::new(raw).map(|raw| AnimationState { raw })
3007    }
3008}
3009
3010// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
3011// is deliberately NOT implemented — the C++ types make no documented
3012// guarantee about concurrent use, and claiming one we haven't verified
3013// would be unsound. See `@bind thread_safe` in the plan.
3014unsafe impl Send for AnimationState {}
3015
3016impl core::fmt::Debug for AnimationState {
3017    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3018        f.debug_struct("AnimationState").finish_non_exhaustive()
3019    }
3020}
3021
3022impl AnimationState {
3023    /// # Panics
3024    /// Panics if the native allocation fails.
3025    pub fn new() -> Self {
3026        // SAFETY: the native constructor returns a live handle; a null here
3027        // means the library is unusable.
3028        unsafe {
3029            let raw = ffi::whiteout_m3_M3AnimationState_new();
3030            Self::from_raw(raw).expect("native AnimationState allocation failed")
3031        }
3032    }
3033
3034    /// Animation IDs (U32_)
3035    /// Zero-copy view of the underlying `std::vector`.
3036    pub fn anim_ids(&self) -> &[u32] {
3037        // SAFETY: `_data`/`_count` describe one contiguous C++
3038        // allocation, borrowed for as long as `self` is.
3039        unsafe {
3040            let n = ffi::whiteout_m3_M3AnimationState_get_animIds_count(self.raw.as_ptr());
3041            let p = ffi::whiteout_m3_M3AnimationState_get_animIds_data(self.raw.as_ptr());
3042            if p.is_null() || n == 0 {
3043                &[]
3044            } else {
3045                core::slice::from_raw_parts(p, n)
3046            }
3047        }
3048    }
3049
3050    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
3051    pub fn anim_ids_mut(&mut self) -> &mut [u32] {
3052        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
3053        unsafe {
3054            let n = ffi::whiteout_m3_M3AnimationState_get_animIds_count(self.raw.as_ptr());
3055            let p =
3056                ffi::whiteout_m3_M3AnimationState_get_animIds_data(self.raw.as_ptr()) as *mut u32;
3057            if p.is_null() || n == 0 {
3058                &mut []
3059            } else {
3060                core::slice::from_raw_parts_mut(p, n)
3061            }
3062        }
3063    }
3064
3065    pub fn set_anim_ids(&mut self, values: &[u32]) {
3066        // SAFETY: the native side copies `values` before returning.
3067        unsafe {
3068            ffi::whiteout_m3_M3AnimationState_assign_animIds(
3069                self.raw.as_ptr(),
3070                values.as_ptr() as *const _,
3071                values.len(),
3072            )
3073        }
3074    }
3075
3076    pub fn resize_anim_ids(&mut self, count: usize) {
3077        // SAFETY: reallocation is safe here precisely because
3078        // `&mut self` means no slice borrow is outstanding.
3079        unsafe { ffi::whiteout_m3_M3AnimationState_resize_animIds(self.raw.as_ptr(), count) }
3080    }
3081
3082    /// Unknown state data (16 bytes)
3083    /// Number of elements — a fixed-size C++ array.
3084    pub const fn unknown_len() -> usize {
3085        16
3086    }
3087
3088    /// # Panics
3089    /// If `index >= 16`, matching Rust slice indexing.
3090    pub fn unknown(&self, index: usize) -> u8 {
3091        assert!(index < 16, "unknown index {index} out of range (len 16)");
3092        // SAFETY: index checked above; plain scalar read.
3093        unsafe { ffi::whiteout_m3_M3AnimationState_get_unknown_at(self.raw.as_ptr(), index) }
3094    }
3095
3096    /// # Panics
3097    /// If `index >= 16`.
3098    pub fn set_unknown(&mut self, index: usize, value: u8) {
3099        assert!(index < 16, "unknown index {index} out of range (len 16)");
3100        // SAFETY: index checked above.
3101        unsafe { ffi::whiteout_m3_M3AnimationState_set_unknown_at(self.raw.as_ptr(), index, value) }
3102    }
3103}
3104
3105impl Default for AnimationState {
3106    fn default() -> Self {
3107        Self::new()
3108    }
3109}
3110
3111/// BSET — Bone animation set (v0, 32 bytes)
3112///
3113/// Maps a bone to specific animation sequences with fallback support. In practice, always null in observed corpus data.
3114pub struct BoneAnimationSet {
3115    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3BoneAnimationSet>,
3116}
3117
3118impl Drop for BoneAnimationSet {
3119    fn drop(&mut self) {
3120        // SAFETY: `raw` came from a native constructor and Drop runs once.
3121        unsafe { ffi::whiteout_m3_M3BoneAnimationSet_delete(self.raw.as_ptr()) }
3122    }
3123}
3124
3125impl BoneAnimationSet {
3126    /// # Safety
3127    /// `raw` must be a live handle this value takes ownership of.
3128    #[allow(dead_code)] // used by whichever methods return this type
3129    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3BoneAnimationSet) -> Option<Self> {
3130        core::ptr::NonNull::new(raw).map(|raw| BoneAnimationSet { raw })
3131    }
3132}
3133
3134// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
3135// is deliberately NOT implemented — the C++ types make no documented
3136// guarantee about concurrent use, and claiming one we haven't verified
3137// would be unsound. See `@bind thread_safe` in the plan.
3138unsafe impl Send for BoneAnimationSet {}
3139
3140impl core::fmt::Debug for BoneAnimationSet {
3141    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3142        f.debug_struct("BoneAnimationSet").finish_non_exhaustive()
3143    }
3144}
3145
3146impl BoneAnimationSet {
3147    /// # Panics
3148    /// Panics if the native allocation fails.
3149    pub fn new() -> Self {
3150        // SAFETY: the native constructor returns a live handle; a null here
3151        // means the library is unusable.
3152        unsafe {
3153            let raw = ffi::whiteout_m3_M3BoneAnimationSet_new();
3154            Self::from_raw(raw).expect("native BoneAnimationSet allocation failed")
3155        }
3156    }
3157
3158    /// Primary sequence index
3159    pub fn animation_sequence_index(&self) -> u16 {
3160        // SAFETY: plain scalar read through a live handle.
3161        unsafe { ffi::whiteout_m3_M3BoneAnimationSet_get_animationSequenceIndex(self.raw.as_ptr()) }
3162    }
3163
3164    pub fn set_animation_sequence_index(&mut self, value: u16) {
3165        // SAFETY: plain scalar write through a live handle.
3166        unsafe {
3167            ffi::whiteout_m3_M3BoneAnimationSet_set_animationSequenceIndex(self.raw.as_ptr(), value)
3168        }
3169    }
3170
3171    /// Fallback sequence index
3172    pub fn fallback_sequence_index(&self) -> u16 {
3173        // SAFETY: plain scalar read through a live handle.
3174        unsafe { ffi::whiteout_m3_M3BoneAnimationSet_get_fallbackSequenceIndex(self.raw.as_ptr()) }
3175    }
3176
3177    pub fn set_fallback_sequence_index(&mut self, value: u16) {
3178        // SAFETY: plain scalar write through a live handle.
3179        unsafe {
3180            ffi::whiteout_m3_M3BoneAnimationSet_set_fallbackSequenceIndex(self.raw.as_ptr(), value)
3181        }
3182    }
3183
3184    /// Set name (`Ref<CHAR>`)
3185    pub fn name(&self) -> String {
3186        // SAFETY: the native side hands over an owned CString.
3187        unsafe {
3188            crate::support::take_string(ffi::whiteout_m3_M3BoneAnimationSet_get_name(
3189                self.raw.as_ptr(),
3190            ))
3191        }
3192    }
3193
3194    pub fn set_name(&mut self, value: &str) {
3195        let value = std::ffi::CString::new(value).unwrap_or_default();
3196        // SAFETY: the pointer outlives the call.
3197        unsafe { ffi::whiteout_m3_M3BoneAnimationSet_set_name(self.raw.as_ptr(), value.as_ptr()) }
3198    }
3199
3200    /// Split item indices (U16_)
3201    /// Zero-copy view of the underlying `std::vector`.
3202    pub fn split_items(&self) -> &[u16] {
3203        // SAFETY: `_data`/`_count` describe one contiguous C++
3204        // allocation, borrowed for as long as `self` is.
3205        unsafe {
3206            let n = ffi::whiteout_m3_M3BoneAnimationSet_get_splitItems_count(self.raw.as_ptr());
3207            let p = ffi::whiteout_m3_M3BoneAnimationSet_get_splitItems_data(self.raw.as_ptr());
3208            if p.is_null() || n == 0 {
3209                &[]
3210            } else {
3211                core::slice::from_raw_parts(p, n)
3212            }
3213        }
3214    }
3215
3216    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
3217    pub fn split_items_mut(&mut self) -> &mut [u16] {
3218        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
3219        unsafe {
3220            let n = ffi::whiteout_m3_M3BoneAnimationSet_get_splitItems_count(self.raw.as_ptr());
3221            let p = ffi::whiteout_m3_M3BoneAnimationSet_get_splitItems_data(self.raw.as_ptr())
3222                as *mut u16;
3223            if p.is_null() || n == 0 {
3224                &mut []
3225            } else {
3226                core::slice::from_raw_parts_mut(p, n)
3227            }
3228        }
3229    }
3230
3231    pub fn set_split_items(&mut self, values: &[u16]) {
3232        // SAFETY: the native side copies `values` before returning.
3233        unsafe {
3234            ffi::whiteout_m3_M3BoneAnimationSet_assign_splitItems(
3235                self.raw.as_ptr(),
3236                values.as_ptr() as *const _,
3237                values.len(),
3238            )
3239        }
3240    }
3241
3242    pub fn resize_split_items(&mut self, count: usize) {
3243        // SAFETY: reallocation is safe here precisely because
3244        // `&mut self` means no slice borrow is outstanding.
3245        unsafe { ffi::whiteout_m3_M3BoneAnimationSet_resize_splitItems(self.raw.as_ptr(), count) }
3246    }
3247}
3248
3249impl Default for BoneAnimationSet {
3250    fn default() -> Self {
3251        Self::new()
3252    }
3253}
3254
3255/// PAR_ — Particle emitter (v10–v24, 1300–1496 bytes)
3256///
3257/// The most complex M3 chunk type. Contains bone/material binding, emission shape/rate, per-particle lifetime/velocity/color/size/rotation curves, physics (drag, mass, forces), noise, collision, flipbook, variation channels, spline data, LOD, trails, and splat references. Version extensions add additional flags, force multipliers, UV transforms, phase shift, and ribbon-on-bounce parameters.
3258pub struct ParticleEmitter {
3259    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3ParticleEmitter>,
3260}
3261
3262impl Drop for ParticleEmitter {
3263    fn drop(&mut self) {
3264        // SAFETY: `raw` came from a native constructor and Drop runs once.
3265        unsafe { ffi::whiteout_m3_M3ParticleEmitter_delete(self.raw.as_ptr()) }
3266    }
3267}
3268
3269impl ParticleEmitter {
3270    /// # Safety
3271    /// `raw` must be a live handle this value takes ownership of.
3272    #[allow(dead_code)] // used by whichever methods return this type
3273    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3ParticleEmitter) -> Option<Self> {
3274        core::ptr::NonNull::new(raw).map(|raw| ParticleEmitter { raw })
3275    }
3276}
3277
3278// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
3279// is deliberately NOT implemented — the C++ types make no documented
3280// guarantee about concurrent use, and claiming one we haven't verified
3281// would be unsound. See `@bind thread_safe` in the plan.
3282unsafe impl Send for ParticleEmitter {}
3283
3284impl core::fmt::Debug for ParticleEmitter {
3285    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3286        f.debug_struct("ParticleEmitter").finish_non_exhaustive()
3287    }
3288}
3289
3290impl ParticleEmitter {
3291    /// # Panics
3292    /// Panics if the native allocation fails.
3293    pub fn new() -> Self {
3294        // SAFETY: the native constructor returns a live handle; a null here
3295        // means the library is unusable.
3296        unsafe {
3297            let raw = ffi::whiteout_m3_M3ParticleEmitter_new();
3298            Self::from_raw(raw).expect("native ParticleEmitter allocation failed")
3299        }
3300    }
3301
3302    /// Index into BONE array
3303    pub fn bone_index(&self) -> u32 {
3304        // SAFETY: plain scalar read through a live handle.
3305        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_boneIndex(self.raw.as_ptr()) }
3306    }
3307
3308    pub fn set_bone_index(&mut self, value: u32) {
3309        // SAFETY: plain scalar write through a live handle.
3310        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_boneIndex(self.raw.as_ptr(), value) }
3311    }
3312
3313    /// Index into MATM material map array
3314    pub fn material_index(&self) -> u32 {
3315        // SAFETY: plain scalar read through a live handle.
3316        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_materialIndex(self.raw.as_ptr()) }
3317    }
3318
3319    pub fn set_material_index(&mut self, value: u32) {
3320        // SAFETY: plain scalar write through a live handle.
3321        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_materialIndex(self.raw.as_ptr(), value) }
3322    }
3323
3324    pub fn additional_flags(&self) -> ParticleAdditionalFlag {
3325        // SAFETY: scalar read; a flag set accepts any bits.
3326        ParticleAdditionalFlag(unsafe {
3327            ffi::whiteout_m3_M3ParticleEmitter_get_additionalFlags(self.raw.as_ptr())
3328        })
3329    }
3330
3331    pub fn set_additional_flags(&mut self, value: ParticleAdditionalFlag) {
3332        // SAFETY: scalar write through a live handle.
3333        unsafe {
3334            ffi::whiteout_m3_M3ParticleEmitter_set_additionalFlags(self.raw.as_ptr(), value.0)
3335        }
3336    }
3337
3338    /// Initial particle speed
3339    /// Borrows the field in place — no copy, no allocation.
3340    pub fn initial_speed(&self) -> crate::support::Ref<'_, AnimRefF32> {
3341        // SAFETY: an interior pointer into `self`, valid for this
3342        // borrow and never freed by the `Ref`.
3343        unsafe {
3344            crate::support::Ref::new(AnimRefF32 {
3345                raw: core::ptr::NonNull::new_unchecked(
3346                    ffi::whiteout_m3_M3ParticleEmitter_get_initialSpeed(self.raw.as_ptr()),
3347                ),
3348            })
3349        }
3350    }
3351
3352    pub fn initial_speed_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
3353        // SAFETY: as above; `&mut self` guarantees exclusivity.
3354        unsafe {
3355            crate::support::RefMut::new(AnimRefF32 {
3356                raw: core::ptr::NonNull::new_unchecked(
3357                    ffi::whiteout_m3_M3ParticleEmitter_get_initialSpeed(self.raw.as_ptr()),
3358                ),
3359            })
3360        }
3361    }
3362
3363    /// Random speed variation
3364    /// Borrows the field in place — no copy, no allocation.
3365    pub fn initial_speed_random(&self) -> crate::support::Ref<'_, AnimRefF32> {
3366        // SAFETY: an interior pointer into `self`, valid for this
3367        // borrow and never freed by the `Ref`.
3368        unsafe {
3369            crate::support::Ref::new(AnimRefF32 {
3370                raw: core::ptr::NonNull::new_unchecked(
3371                    ffi::whiteout_m3_M3ParticleEmitter_get_initialSpeedRandom(self.raw.as_ptr()),
3372                ),
3373            })
3374        }
3375    }
3376
3377    pub fn initial_speed_random_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
3378        // SAFETY: as above; `&mut self` guarantees exclusivity.
3379        unsafe {
3380            crate::support::RefMut::new(AnimRefF32 {
3381                raw: core::ptr::NonNull::new_unchecked(
3382                    ffi::whiteout_m3_M3ParticleEmitter_get_initialSpeedRandom(self.raw.as_ptr()),
3383                ),
3384            })
3385        }
3386    }
3387
3388    /// Initial yaw angle
3389    /// Borrows the field in place — no copy, no allocation.
3390    pub fn initial_yaw(&self) -> crate::support::Ref<'_, AnimRefF32> {
3391        // SAFETY: an interior pointer into `self`, valid for this
3392        // borrow and never freed by the `Ref`.
3393        unsafe {
3394            crate::support::Ref::new(AnimRefF32 {
3395                raw: core::ptr::NonNull::new_unchecked(
3396                    ffi::whiteout_m3_M3ParticleEmitter_get_initialYaw(self.raw.as_ptr()),
3397                ),
3398            })
3399        }
3400    }
3401
3402    pub fn initial_yaw_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
3403        // SAFETY: as above; `&mut self` guarantees exclusivity.
3404        unsafe {
3405            crate::support::RefMut::new(AnimRefF32 {
3406                raw: core::ptr::NonNull::new_unchecked(
3407                    ffi::whiteout_m3_M3ParticleEmitter_get_initialYaw(self.raw.as_ptr()),
3408                ),
3409            })
3410        }
3411    }
3412
3413    /// Initial pitch angle
3414    /// Borrows the field in place — no copy, no allocation.
3415    pub fn initial_pitch(&self) -> crate::support::Ref<'_, AnimRefF32> {
3416        // SAFETY: an interior pointer into `self`, valid for this
3417        // borrow and never freed by the `Ref`.
3418        unsafe {
3419            crate::support::Ref::new(AnimRefF32 {
3420                raw: core::ptr::NonNull::new_unchecked(
3421                    ffi::whiteout_m3_M3ParticleEmitter_get_initialPitch(self.raw.as_ptr()),
3422                ),
3423            })
3424        }
3425    }
3426
3427    pub fn initial_pitch_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
3428        // SAFETY: as above; `&mut self` guarantees exclusivity.
3429        unsafe {
3430            crate::support::RefMut::new(AnimRefF32 {
3431                raw: core::ptr::NonNull::new_unchecked(
3432                    ffi::whiteout_m3_M3ParticleEmitter_get_initialPitch(self.raw.as_ptr()),
3433                ),
3434            })
3435        }
3436    }
3437
3438    /// Initial horizontal spread
3439    /// Borrows the field in place — no copy, no allocation.
3440    pub fn initial_horizontal(&self) -> crate::support::Ref<'_, AnimRefF32> {
3441        // SAFETY: an interior pointer into `self`, valid for this
3442        // borrow and never freed by the `Ref`.
3443        unsafe {
3444            crate::support::Ref::new(AnimRefF32 {
3445                raw: core::ptr::NonNull::new_unchecked(
3446                    ffi::whiteout_m3_M3ParticleEmitter_get_initialHorizontal(self.raw.as_ptr()),
3447                ),
3448            })
3449        }
3450    }
3451
3452    pub fn initial_horizontal_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
3453        // SAFETY: as above; `&mut self` guarantees exclusivity.
3454        unsafe {
3455            crate::support::RefMut::new(AnimRefF32 {
3456                raw: core::ptr::NonNull::new_unchecked(
3457                    ffi::whiteout_m3_M3ParticleEmitter_get_initialHorizontal(self.raw.as_ptr()),
3458                ),
3459            })
3460        }
3461    }
3462
3463    /// Initial vertical spread
3464    /// Borrows the field in place — no copy, no allocation.
3465    pub fn initial_vertical(&self) -> crate::support::Ref<'_, AnimRefF32> {
3466        // SAFETY: an interior pointer into `self`, valid for this
3467        // borrow and never freed by the `Ref`.
3468        unsafe {
3469            crate::support::Ref::new(AnimRefF32 {
3470                raw: core::ptr::NonNull::new_unchecked(
3471                    ffi::whiteout_m3_M3ParticleEmitter_get_initialVertical(self.raw.as_ptr()),
3472                ),
3473            })
3474        }
3475    }
3476
3477    pub fn initial_vertical_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
3478        // SAFETY: as above; `&mut self` guarantees exclusivity.
3479        unsafe {
3480            crate::support::RefMut::new(AnimRefF32 {
3481                raw: core::ptr::NonNull::new_unchecked(
3482                    ffi::whiteout_m3_M3ParticleEmitter_get_initialVertical(self.raw.as_ptr()),
3483                ),
3484            })
3485        }
3486    }
3487
3488    /// Base particle lifetime
3489    /// Borrows the field in place — no copy, no allocation.
3490    pub fn lifetime(&self) -> crate::support::Ref<'_, AnimRefF32> {
3491        // SAFETY: an interior pointer into `self`, valid for this
3492        // borrow and never freed by the `Ref`.
3493        unsafe {
3494            crate::support::Ref::new(AnimRefF32 {
3495                raw: core::ptr::NonNull::new_unchecked(
3496                    ffi::whiteout_m3_M3ParticleEmitter_get_lifetime(self.raw.as_ptr()),
3497                ),
3498            })
3499        }
3500    }
3501
3502    pub fn lifetime_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
3503        // SAFETY: as above; `&mut self` guarantees exclusivity.
3504        unsafe {
3505            crate::support::RefMut::new(AnimRefF32 {
3506                raw: core::ptr::NonNull::new_unchecked(
3507                    ffi::whiteout_m3_M3ParticleEmitter_get_lifetime(self.raw.as_ptr()),
3508                ),
3509            })
3510        }
3511    }
3512
3513    /// Random lifetime variation
3514    /// Borrows the field in place — no copy, no allocation.
3515    pub fn lifetime_random(&self) -> crate::support::Ref<'_, AnimRefF32> {
3516        // SAFETY: an interior pointer into `self`, valid for this
3517        // borrow and never freed by the `Ref`.
3518        unsafe {
3519            crate::support::Ref::new(AnimRefF32 {
3520                raw: core::ptr::NonNull::new_unchecked(
3521                    ffi::whiteout_m3_M3ParticleEmitter_get_lifetimeRandom(self.raw.as_ptr()),
3522                ),
3523            })
3524        }
3525    }
3526
3527    pub fn lifetime_random_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
3528        // SAFETY: as above; `&mut self` guarantees exclusivity.
3529        unsafe {
3530            crate::support::RefMut::new(AnimRefF32 {
3531                raw: core::ptr::NonNull::new_unchecked(
3532                    ffi::whiteout_m3_M3ParticleEmitter_get_lifetimeRandom(self.raw.as_ptr()),
3533                ),
3534            })
3535        }
3536    }
3537
3538    /// Kill radius (particles beyond this are destroyed)
3539    pub fn kill_radius(&self) -> f32 {
3540        // SAFETY: plain scalar read through a live handle.
3541        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_killRadius(self.raw.as_ptr()) }
3542    }
3543
3544    pub fn set_kill_radius(&mut self, value: f32) {
3545        // SAFETY: plain scalar write through a live handle.
3546        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_killRadius(self.raw.as_ptr(), value) }
3547    }
3548
3549    /// Gravity X component (expected 0)
3550    pub fn gravity_x(&self) -> u32 {
3551        // SAFETY: plain scalar read through a live handle.
3552        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_gravityX(self.raw.as_ptr()) }
3553    }
3554
3555    pub fn set_gravity_x(&mut self, value: u32) {
3556        // SAFETY: plain scalar write through a live handle.
3557        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_gravityX(self.raw.as_ptr(), value) }
3558    }
3559
3560    /// Gravity Y component (expected 0)
3561    pub fn gravity_y(&self) -> u32 {
3562        // SAFETY: plain scalar read through a live handle.
3563        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_gravityY(self.raw.as_ptr()) }
3564    }
3565
3566    pub fn set_gravity_y(&mut self, value: u32) {
3567        // SAFETY: plain scalar write through a live handle.
3568        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_gravityY(self.raw.as_ptr(), value) }
3569    }
3570
3571    /// Gravity Z component
3572    pub fn gravity(&self) -> f32 {
3573        // SAFETY: plain scalar read through a live handle.
3574        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_gravity(self.raw.as_ptr()) }
3575    }
3576
3577    pub fn set_gravity(&mut self, value: f32) {
3578        // SAFETY: plain scalar write through a live handle.
3579        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_gravity(self.raw.as_ptr(), value) }
3580    }
3581
3582    /// Size midpoint time (0–1, v12+)
3583    pub fn size_mid_time(&self) -> f32 {
3584        // SAFETY: plain scalar read through a live handle.
3585        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_sizeMidTime(self.raw.as_ptr()) }
3586    }
3587
3588    pub fn set_size_mid_time(&mut self, value: f32) {
3589        // SAFETY: plain scalar write through a live handle.
3590        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_sizeMidTime(self.raw.as_ptr(), value) }
3591    }
3592
3593    /// Color midpoint time (0–1, v12+)
3594    pub fn color_mid_time(&self) -> f32 {
3595        // SAFETY: plain scalar read through a live handle.
3596        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_colorMidTime(self.raw.as_ptr()) }
3597    }
3598
3599    pub fn set_color_mid_time(&mut self, value: f32) {
3600        // SAFETY: plain scalar write through a live handle.
3601        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_colorMidTime(self.raw.as_ptr(), value) }
3602    }
3603
3604    /// Alpha midpoint time (0–1, v12+)
3605    pub fn alpha_mid_time(&self) -> f32 {
3606        // SAFETY: plain scalar read through a live handle.
3607        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_alphaMidTime(self.raw.as_ptr()) }
3608    }
3609
3610    pub fn set_alpha_mid_time(&mut self, value: f32) {
3611        // SAFETY: plain scalar write through a live handle.
3612        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_alphaMidTime(self.raw.as_ptr(), value) }
3613    }
3614
3615    /// Rotation midpoint time (0–1, v12+)
3616    pub fn rotation_mid_time(&self) -> f32 {
3617        // SAFETY: plain scalar read through a live handle.
3618        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_rotationMidTime(self.raw.as_ptr()) }
3619    }
3620
3621    pub fn set_rotation_mid_time(&mut self, value: f32) {
3622        // SAFETY: plain scalar write through a live handle.
3623        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_rotationMidTime(self.raw.as_ptr(), value) }
3624    }
3625
3626    /// Size hold time at midpoint (v14+)
3627    pub fn size_mid_hold_time(&self) -> f32 {
3628        // SAFETY: plain scalar read through a live handle.
3629        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_sizeMidHoldTime(self.raw.as_ptr()) }
3630    }
3631
3632    pub fn set_size_mid_hold_time(&mut self, value: f32) {
3633        // SAFETY: plain scalar write through a live handle.
3634        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_sizeMidHoldTime(self.raw.as_ptr(), value) }
3635    }
3636
3637    /// Color hold time at midpoint (v14+)
3638    pub fn color_mid_hold_time(&self) -> f32 {
3639        // SAFETY: plain scalar read through a live handle.
3640        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_colorMidHoldTime(self.raw.as_ptr()) }
3641    }
3642
3643    pub fn set_color_mid_hold_time(&mut self, value: f32) {
3644        // SAFETY: plain scalar write through a live handle.
3645        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_colorMidHoldTime(self.raw.as_ptr(), value) }
3646    }
3647
3648    /// Alpha hold time at midpoint (v14+)
3649    pub fn alpha_mid_hold_time(&self) -> f32 {
3650        // SAFETY: plain scalar read through a live handle.
3651        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_alphaMidHoldTime(self.raw.as_ptr()) }
3652    }
3653
3654    pub fn set_alpha_mid_hold_time(&mut self, value: f32) {
3655        // SAFETY: plain scalar write through a live handle.
3656        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_alphaMidHoldTime(self.raw.as_ptr(), value) }
3657    }
3658
3659    /// Rotation hold time at midpoint (v14+)
3660    pub fn rotation_mid_hold_time(&self) -> f32 {
3661        // SAFETY: plain scalar read through a live handle.
3662        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_rotationMidHoldTime(self.raw.as_ptr()) }
3663    }
3664
3665    pub fn set_rotation_mid_hold_time(&mut self, value: f32) {
3666        // SAFETY: plain scalar write through a live handle.
3667        unsafe {
3668            ffi::whiteout_m3_M3ParticleEmitter_set_rotationMidHoldTime(self.raw.as_ptr(), value)
3669        }
3670    }
3671
3672    /// Size curve (start, mid, end)
3673    /// Borrows the field in place — no copy, no allocation.
3674    pub fn size_animation(&self) -> crate::support::Ref<'_, AnimRefVector3f> {
3675        // SAFETY: an interior pointer into `self`, valid for this
3676        // borrow and never freed by the `Ref`.
3677        unsafe {
3678            crate::support::Ref::new(AnimRefVector3f {
3679                raw: core::ptr::NonNull::new_unchecked(
3680                    ffi::whiteout_m3_M3ParticleEmitter_get_sizeAnimation(self.raw.as_ptr()),
3681                ),
3682            })
3683        }
3684    }
3685
3686    pub fn size_animation_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector3f> {
3687        // SAFETY: as above; `&mut self` guarantees exclusivity.
3688        unsafe {
3689            crate::support::RefMut::new(AnimRefVector3f {
3690                raw: core::ptr::NonNull::new_unchecked(
3691                    ffi::whiteout_m3_M3ParticleEmitter_get_sizeAnimation(self.raw.as_ptr()),
3692                ),
3693            })
3694        }
3695    }
3696
3697    /// Rotation curve (start, mid, end)
3698    /// Borrows the field in place — no copy, no allocation.
3699    pub fn rotation_animation(&self) -> crate::support::Ref<'_, AnimRefVector3f> {
3700        // SAFETY: an interior pointer into `self`, valid for this
3701        // borrow and never freed by the `Ref`.
3702        unsafe {
3703            crate::support::Ref::new(AnimRefVector3f {
3704                raw: core::ptr::NonNull::new_unchecked(
3705                    ffi::whiteout_m3_M3ParticleEmitter_get_rotationAnimation(self.raw.as_ptr()),
3706                ),
3707            })
3708        }
3709    }
3710
3711    pub fn rotation_animation_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector3f> {
3712        // SAFETY: as above; `&mut self` guarantees exclusivity.
3713        unsafe {
3714            crate::support::RefMut::new(AnimRefVector3f {
3715                raw: core::ptr::NonNull::new_unchecked(
3716                    ffi::whiteout_m3_M3ParticleEmitter_get_rotationAnimation(self.raw.as_ptr()),
3717                ),
3718            })
3719        }
3720    }
3721
3722    /// Color at birth
3723    /// Borrows the field in place — no copy, no allocation.
3724    pub fn color_start(&self) -> crate::support::Ref<'_, AnimRefM3ColorBGRA> {
3725        // SAFETY: an interior pointer into `self`, valid for this
3726        // borrow and never freed by the `Ref`.
3727        unsafe {
3728            crate::support::Ref::new(AnimRefM3ColorBGRA {
3729                raw: core::ptr::NonNull::new_unchecked(
3730                    ffi::whiteout_m3_M3ParticleEmitter_get_colorStart(self.raw.as_ptr()),
3731                ),
3732            })
3733        }
3734    }
3735
3736    pub fn color_start_mut(&mut self) -> crate::support::RefMut<'_, AnimRefM3ColorBGRA> {
3737        // SAFETY: as above; `&mut self` guarantees exclusivity.
3738        unsafe {
3739            crate::support::RefMut::new(AnimRefM3ColorBGRA {
3740                raw: core::ptr::NonNull::new_unchecked(
3741                    ffi::whiteout_m3_M3ParticleEmitter_get_colorStart(self.raw.as_ptr()),
3742                ),
3743            })
3744        }
3745    }
3746
3747    /// Color at midpoint
3748    /// Borrows the field in place — no copy, no allocation.
3749    pub fn color_mid(&self) -> crate::support::Ref<'_, AnimRefM3ColorBGRA> {
3750        // SAFETY: an interior pointer into `self`, valid for this
3751        // borrow and never freed by the `Ref`.
3752        unsafe {
3753            crate::support::Ref::new(AnimRefM3ColorBGRA {
3754                raw: core::ptr::NonNull::new_unchecked(
3755                    ffi::whiteout_m3_M3ParticleEmitter_get_colorMid(self.raw.as_ptr()),
3756                ),
3757            })
3758        }
3759    }
3760
3761    pub fn color_mid_mut(&mut self) -> crate::support::RefMut<'_, AnimRefM3ColorBGRA> {
3762        // SAFETY: as above; `&mut self` guarantees exclusivity.
3763        unsafe {
3764            crate::support::RefMut::new(AnimRefM3ColorBGRA {
3765                raw: core::ptr::NonNull::new_unchecked(
3766                    ffi::whiteout_m3_M3ParticleEmitter_get_colorMid(self.raw.as_ptr()),
3767                ),
3768            })
3769        }
3770    }
3771
3772    /// Color at death
3773    /// Borrows the field in place — no copy, no allocation.
3774    pub fn color_end(&self) -> crate::support::Ref<'_, AnimRefM3ColorBGRA> {
3775        // SAFETY: an interior pointer into `self`, valid for this
3776        // borrow and never freed by the `Ref`.
3777        unsafe {
3778            crate::support::Ref::new(AnimRefM3ColorBGRA {
3779                raw: core::ptr::NonNull::new_unchecked(
3780                    ffi::whiteout_m3_M3ParticleEmitter_get_colorEnd(self.raw.as_ptr()),
3781                ),
3782            })
3783        }
3784    }
3785
3786    pub fn color_end_mut(&mut self) -> crate::support::RefMut<'_, AnimRefM3ColorBGRA> {
3787        // SAFETY: as above; `&mut self` guarantees exclusivity.
3788        unsafe {
3789            crate::support::RefMut::new(AnimRefM3ColorBGRA {
3790                raw: core::ptr::NonNull::new_unchecked(
3791                    ffi::whiteout_m3_M3ParticleEmitter_get_colorEnd(self.raw.as_ptr()),
3792                ),
3793            })
3794        }
3795    }
3796
3797    /// Air drag coefficient
3798    pub fn drag(&self) -> f32 {
3799        // SAFETY: plain scalar read through a live handle.
3800        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_drag(self.raw.as_ptr()) }
3801    }
3802
3803    pub fn set_drag(&mut self, value: f32) {
3804        // SAFETY: plain scalar write through a live handle.
3805        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_drag(self.raw.as_ptr(), value) }
3806    }
3807
3808    /// Particle mass
3809    pub fn mass(&self) -> f32 {
3810        // SAFETY: plain scalar read through a live handle.
3811        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_mass(self.raw.as_ptr()) }
3812    }
3813
3814    pub fn set_mass(&mut self, value: f32) {
3815        // SAFETY: plain scalar write through a live handle.
3816        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_mass(self.raw.as_ptr(), value) }
3817    }
3818
3819    /// Random mass variation multiplier
3820    pub fn mass_random(&self) -> f32 {
3821        // SAFETY: plain scalar read through a live handle.
3822        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_massRandom(self.raw.as_ptr()) }
3823    }
3824
3825    pub fn set_mass_random(&mut self, value: f32) {
3826        // SAFETY: plain scalar write through a live handle.
3827        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_massRandom(self.raw.as_ptr(), value) }
3828    }
3829
3830    /// Mass–size coupling (v12+)
3831    pub fn mass_size_multiplier(&self) -> f32 {
3832        // SAFETY: plain scalar read through a live handle.
3833        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_massSizeMultiplier(self.raw.as_ptr()) }
3834    }
3835
3836    pub fn set_mass_size_multiplier(&mut self, value: f32) {
3837        // SAFETY: plain scalar write through a live handle.
3838        unsafe {
3839            ffi::whiteout_m3_M3ParticleEmitter_set_massSizeMultiplier(self.raw.as_ptr(), value)
3840        }
3841    }
3842
3843    /// Local force channel bitmask
3844    pub fn local_forces(&self) -> u16 {
3845        // SAFETY: plain scalar read through a live handle.
3846        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_localForces(self.raw.as_ptr()) }
3847    }
3848
3849    pub fn set_local_forces(&mut self, value: u16) {
3850        // SAFETY: plain scalar write through a live handle.
3851        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_localForces(self.raw.as_ptr(), value) }
3852    }
3853
3854    /// World force channel bitmask
3855    pub fn world_forces(&self) -> u16 {
3856        // SAFETY: plain scalar read through a live handle.
3857        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_worldForces(self.raw.as_ptr()) }
3858    }
3859
3860    pub fn set_world_forces(&mut self, value: u16) {
3861        // SAFETY: plain scalar write through a live handle.
3862        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_worldForces(self.raw.as_ptr(), value) }
3863    }
3864
3865    /// Fallback local force channels
3866    pub fn local_forces_fallback(&self) -> u16 {
3867        // SAFETY: plain scalar read through a live handle.
3868        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_localForcesFallback(self.raw.as_ptr()) }
3869    }
3870
3871    pub fn set_local_forces_fallback(&mut self, value: u16) {
3872        // SAFETY: plain scalar write through a live handle.
3873        unsafe {
3874            ffi::whiteout_m3_M3ParticleEmitter_set_localForcesFallback(self.raw.as_ptr(), value)
3875        }
3876    }
3877
3878    /// Fallback world force channels
3879    pub fn world_forces_fallback(&self) -> u16 {
3880        // SAFETY: plain scalar read through a live handle.
3881        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_worldForcesFallback(self.raw.as_ptr()) }
3882    }
3883
3884    pub fn set_world_forces_fallback(&mut self, value: u16) {
3885        // SAFETY: plain scalar write through a live handle.
3886        unsafe {
3887            ffi::whiteout_m3_M3ParticleEmitter_set_worldForcesFallback(self.raw.as_ptr(), value)
3888        }
3889    }
3890
3891    /// World force mass multiplier (v24+)
3892    pub fn world_forces_mass_multiplier(&self) -> f32 {
3893        // SAFETY: plain scalar read through a live handle.
3894        unsafe {
3895            ffi::whiteout_m3_M3ParticleEmitter_get_worldForcesMassMultiplier(self.raw.as_ptr())
3896        }
3897    }
3898
3899    pub fn set_world_forces_mass_multiplier(&mut self, value: f32) {
3900        // SAFETY: plain scalar write through a live handle.
3901        unsafe {
3902            ffi::whiteout_m3_M3ParticleEmitter_set_worldForcesMassMultiplier(
3903                self.raw.as_ptr(),
3904                value,
3905            )
3906        }
3907    }
3908
3909    /// Noise displacement amplitude
3910    pub fn noise_amplitude(&self) -> f32 {
3911        // SAFETY: plain scalar read through a live handle.
3912        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_noiseAmplitude(self.raw.as_ptr()) }
3913    }
3914
3915    pub fn set_noise_amplitude(&mut self, value: f32) {
3916        // SAFETY: plain scalar write through a live handle.
3917        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_noiseAmplitude(self.raw.as_ptr(), value) }
3918    }
3919
3920    /// Noise spatial frequency
3921    pub fn noise_frequency(&self) -> f32 {
3922        // SAFETY: plain scalar read through a live handle.
3923        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_noiseFrequency(self.raw.as_ptr()) }
3924    }
3925
3926    pub fn set_noise_frequency(&mut self, value: f32) {
3927        // SAFETY: plain scalar write through a live handle.
3928        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_noiseFrequency(self.raw.as_ptr(), value) }
3929    }
3930
3931    /// Noise temporal coherence
3932    pub fn noise_coherence(&self) -> f32 {
3933        // SAFETY: plain scalar read through a live handle.
3934        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_noiseCoherence(self.raw.as_ptr()) }
3935    }
3936
3937    pub fn set_noise_coherence(&mut self, value: f32) {
3938        // SAFETY: plain scalar write through a live handle.
3939        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_noiseCoherence(self.raw.as_ptr(), value) }
3940    }
3941
3942    /// Noise edge sharpness
3943    pub fn noise_edge(&self) -> f32 {
3944        // SAFETY: plain scalar read through a live handle.
3945        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_noiseEdge(self.raw.as_ptr()) }
3946    }
3947
3948    pub fn set_noise_edge(&mut self, value: f32) {
3949        // SAFETY: plain scalar write through a live handle.
3950        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_noiseEdge(self.raw.as_ptr(), value) }
3951    }
3952
3953    /// Index + length (v11+)
3954    pub fn index_plus_length(&self) -> u32 {
3955        // SAFETY: plain scalar read through a live handle.
3956        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_indexPlusLength(self.raw.as_ptr()) }
3957    }
3958
3959    pub fn set_index_plus_length(&mut self, value: u32) {
3960        // SAFETY: plain scalar write through a live handle.
3961        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_indexPlusLength(self.raw.as_ptr(), value) }
3962    }
3963
3964    /// Maximum live particle count
3965    pub fn max_particles(&self) -> u32 {
3966        // SAFETY: plain scalar read through a live handle.
3967        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_maxParticles(self.raw.as_ptr()) }
3968    }
3969
3970    pub fn set_max_particles(&mut self, value: u32) {
3971        // SAFETY: plain scalar write through a live handle.
3972        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_maxParticles(self.raw.as_ptr(), value) }
3973    }
3974
3975    /// Animated emission rate (particles/sec)
3976    /// Borrows the field in place — no copy, no allocation.
3977    pub fn emission_rate(&self) -> crate::support::Ref<'_, AnimRefF32> {
3978        // SAFETY: an interior pointer into `self`, valid for this
3979        // borrow and never freed by the `Ref`.
3980        unsafe {
3981            crate::support::Ref::new(AnimRefF32 {
3982                raw: core::ptr::NonNull::new_unchecked(
3983                    ffi::whiteout_m3_M3ParticleEmitter_get_emissionRate(self.raw.as_ptr()),
3984                ),
3985            })
3986        }
3987    }
3988
3989    pub fn emission_rate_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
3990        // SAFETY: as above; `&mut self` guarantees exclusivity.
3991        unsafe {
3992            crate::support::RefMut::new(AnimRefF32 {
3993                raw: core::ptr::NonNull::new_unchecked(
3994                    ffi::whiteout_m3_M3ParticleEmitter_get_emissionRate(self.raw.as_ptr()),
3995                ),
3996            })
3997        }
3998    }
3999
4000    /// Emission shape
4001    pub fn emitter_shape(&self) -> EmitterShape {
4002        // SAFETY: scalar read; the discriminant is validated below.
4003        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_emitterShape(self.raw.as_ptr()) }
4004            .try_into()
4005            .expect("unknown enum discriminant from the native library")
4006    }
4007
4008    pub fn set_emitter_shape(&mut self, value: EmitterShape) {
4009        // SAFETY: scalar write through a live handle.
4010        unsafe {
4011            ffi::whiteout_m3_M3ParticleEmitter_set_emitterShape(self.raw.as_ptr(), value as i32)
4012        }
4013    }
4014
4015    /// Animated outer shape dimensions
4016    /// Borrows the field in place — no copy, no allocation.
4017    pub fn shape_outer(&self) -> crate::support::Ref<'_, AnimRefVector3f> {
4018        // SAFETY: an interior pointer into `self`, valid for this
4019        // borrow and never freed by the `Ref`.
4020        unsafe {
4021            crate::support::Ref::new(AnimRefVector3f {
4022                raw: core::ptr::NonNull::new_unchecked(
4023                    ffi::whiteout_m3_M3ParticleEmitter_get_shapeOuter(self.raw.as_ptr()),
4024                ),
4025            })
4026        }
4027    }
4028
4029    pub fn shape_outer_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector3f> {
4030        // SAFETY: as above; `&mut self` guarantees exclusivity.
4031        unsafe {
4032            crate::support::RefMut::new(AnimRefVector3f {
4033                raw: core::ptr::NonNull::new_unchecked(
4034                    ffi::whiteout_m3_M3ParticleEmitter_get_shapeOuter(self.raw.as_ptr()),
4035                ),
4036            })
4037        }
4038    }
4039
4040    /// Animated inner shape dimensions
4041    /// Borrows the field in place — no copy, no allocation.
4042    pub fn shape_inner(&self) -> crate::support::Ref<'_, AnimRefVector3f> {
4043        // SAFETY: an interior pointer into `self`, valid for this
4044        // borrow and never freed by the `Ref`.
4045        unsafe {
4046            crate::support::Ref::new(AnimRefVector3f {
4047                raw: core::ptr::NonNull::new_unchecked(
4048                    ffi::whiteout_m3_M3ParticleEmitter_get_shapeInner(self.raw.as_ptr()),
4049                ),
4050            })
4051        }
4052    }
4053
4054    pub fn shape_inner_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector3f> {
4055        // SAFETY: as above; `&mut self` guarantees exclusivity.
4056        unsafe {
4057            crate::support::RefMut::new(AnimRefVector3f {
4058                raw: core::ptr::NonNull::new_unchecked(
4059                    ffi::whiteout_m3_M3ParticleEmitter_get_shapeInner(self.raw.as_ptr()),
4060                ),
4061            })
4062        }
4063    }
4064
4065    /// Animated outer radius
4066    /// Borrows the field in place — no copy, no allocation.
4067    pub fn outer_radius(&self) -> crate::support::Ref<'_, AnimRefF32> {
4068        // SAFETY: an interior pointer into `self`, valid for this
4069        // borrow and never freed by the `Ref`.
4070        unsafe {
4071            crate::support::Ref::new(AnimRefF32 {
4072                raw: core::ptr::NonNull::new_unchecked(
4073                    ffi::whiteout_m3_M3ParticleEmitter_get_outerRadius(self.raw.as_ptr()),
4074                ),
4075            })
4076        }
4077    }
4078
4079    pub fn outer_radius_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
4080        // SAFETY: as above; `&mut self` guarantees exclusivity.
4081        unsafe {
4082            crate::support::RefMut::new(AnimRefF32 {
4083                raw: core::ptr::NonNull::new_unchecked(
4084                    ffi::whiteout_m3_M3ParticleEmitter_get_outerRadius(self.raw.as_ptr()),
4085                ),
4086            })
4087        }
4088    }
4089
4090    /// Animated inner radius
4091    /// Borrows the field in place — no copy, no allocation.
4092    pub fn inner_radius(&self) -> crate::support::Ref<'_, AnimRefF32> {
4093        // SAFETY: an interior pointer into `self`, valid for this
4094        // borrow and never freed by the `Ref`.
4095        unsafe {
4096            crate::support::Ref::new(AnimRefF32 {
4097                raw: core::ptr::NonNull::new_unchecked(
4098                    ffi::whiteout_m3_M3ParticleEmitter_get_innerRadius(self.raw.as_ptr()),
4099                ),
4100            })
4101        }
4102    }
4103
4104    pub fn inner_radius_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
4105        // SAFETY: as above; `&mut self` guarantees exclusivity.
4106        unsafe {
4107            crate::support::RefMut::new(AnimRefF32 {
4108                raw: core::ptr::NonNull::new_unchecked(
4109                    ffi::whiteout_m3_M3ParticleEmitter_get_innerRadius(self.raw.as_ptr()),
4110                ),
4111            })
4112        }
4113    }
4114
4115    /// Shape region indices (U32_, v14+), which mesh region from div to use
4116    /// Zero-copy view of the underlying `std::vector`.
4117    pub fn shape_regions(&self) -> &[u32] {
4118        // SAFETY: `_data`/`_count` describe one contiguous C++
4119        // allocation, borrowed for as long as `self` is.
4120        unsafe {
4121            let n = ffi::whiteout_m3_M3ParticleEmitter_get_shapeRegions_count(self.raw.as_ptr());
4122            let p = ffi::whiteout_m3_M3ParticleEmitter_get_shapeRegions_data(self.raw.as_ptr());
4123            if p.is_null() || n == 0 {
4124                &[]
4125            } else {
4126                core::slice::from_raw_parts(p, n)
4127            }
4128        }
4129    }
4130
4131    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
4132    pub fn shape_regions_mut(&mut self) -> &mut [u32] {
4133        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
4134        unsafe {
4135            let n = ffi::whiteout_m3_M3ParticleEmitter_get_shapeRegions_count(self.raw.as_ptr());
4136            let p = ffi::whiteout_m3_M3ParticleEmitter_get_shapeRegions_data(self.raw.as_ptr())
4137                as *mut u32;
4138            if p.is_null() || n == 0 {
4139                &mut []
4140            } else {
4141                core::slice::from_raw_parts_mut(p, n)
4142            }
4143        }
4144    }
4145
4146    pub fn set_shape_regions(&mut self, values: &[u32]) {
4147        // SAFETY: the native side copies `values` before returning.
4148        unsafe {
4149            ffi::whiteout_m3_M3ParticleEmitter_assign_shapeRegions(
4150                self.raw.as_ptr(),
4151                values.as_ptr() as *const _,
4152                values.len(),
4153            )
4154        }
4155    }
4156
4157    pub fn resize_shape_regions(&mut self, count: usize) {
4158        // SAFETY: reallocation is safe here precisely because
4159        // `&mut self` means no slice borrow is outstanding.
4160        unsafe { ffi::whiteout_m3_M3ParticleEmitter_resize_shapeRegions(self.raw.as_ptr(), count) }
4161    }
4162
4163    /// Velocity randomization type
4164    pub fn velocity_type(&self) -> u32 {
4165        // SAFETY: plain scalar read through a live handle.
4166        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_velocityType(self.raw.as_ptr()) }
4167    }
4168
4169    pub fn set_velocity_type(&mut self, value: u32) {
4170        // SAFETY: plain scalar write through a live handle.
4171        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_velocityType(self.raw.as_ptr(), value) }
4172    }
4173
4174    /// Enable size randomization
4175    pub fn size_random_enable(&self) -> u32 {
4176        // SAFETY: plain scalar read through a live handle.
4177        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_sizeRandomEnable(self.raw.as_ptr()) }
4178    }
4179
4180    pub fn set_size_random_enable(&mut self, value: u32) {
4181        // SAFETY: plain scalar write through a live handle.
4182        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_sizeRandomEnable(self.raw.as_ptr(), value) }
4183    }
4184
4185    /// Random size curve
4186    /// Borrows the field in place — no copy, no allocation.
4187    pub fn size_random_animation(&self) -> crate::support::Ref<'_, AnimRefVector3f> {
4188        // SAFETY: an interior pointer into `self`, valid for this
4189        // borrow and never freed by the `Ref`.
4190        unsafe {
4191            crate::support::Ref::new(AnimRefVector3f {
4192                raw: core::ptr::NonNull::new_unchecked(
4193                    ffi::whiteout_m3_M3ParticleEmitter_get_sizeRandomAnimation(self.raw.as_ptr()),
4194                ),
4195            })
4196        }
4197    }
4198
4199    pub fn size_random_animation_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector3f> {
4200        // SAFETY: as above; `&mut self` guarantees exclusivity.
4201        unsafe {
4202            crate::support::RefMut::new(AnimRefVector3f {
4203                raw: core::ptr::NonNull::new_unchecked(
4204                    ffi::whiteout_m3_M3ParticleEmitter_get_sizeRandomAnimation(self.raw.as_ptr()),
4205                ),
4206            })
4207        }
4208    }
4209
4210    /// Enable rotation randomization
4211    pub fn rotation_random_enable(&self) -> u32 {
4212        // SAFETY: plain scalar read through a live handle.
4213        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_rotationRandomEnable(self.raw.as_ptr()) }
4214    }
4215
4216    pub fn set_rotation_random_enable(&mut self, value: u32) {
4217        // SAFETY: plain scalar write through a live handle.
4218        unsafe {
4219            ffi::whiteout_m3_M3ParticleEmitter_set_rotationRandomEnable(self.raw.as_ptr(), value)
4220        }
4221    }
4222
4223    /// Random rotation curve
4224    /// Borrows the field in place — no copy, no allocation.
4225    pub fn rotation_random_animation(&self) -> crate::support::Ref<'_, AnimRefVector3f> {
4226        // SAFETY: an interior pointer into `self`, valid for this
4227        // borrow and never freed by the `Ref`.
4228        unsafe {
4229            crate::support::Ref::new(AnimRefVector3f {
4230                raw: core::ptr::NonNull::new_unchecked(
4231                    ffi::whiteout_m3_M3ParticleEmitter_get_rotationRandomAnimation(
4232                        self.raw.as_ptr(),
4233                    ),
4234                ),
4235            })
4236        }
4237    }
4238
4239    pub fn rotation_random_animation_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector3f> {
4240        // SAFETY: as above; `&mut self` guarantees exclusivity.
4241        unsafe {
4242            crate::support::RefMut::new(AnimRefVector3f {
4243                raw: core::ptr::NonNull::new_unchecked(
4244                    ffi::whiteout_m3_M3ParticleEmitter_get_rotationRandomAnimation(
4245                        self.raw.as_ptr(),
4246                    ),
4247                ),
4248            })
4249        }
4250    }
4251
4252    /// Enable color randomization
4253    pub fn color_random_enable(&self) -> u32 {
4254        // SAFETY: plain scalar read through a live handle.
4255        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_colorRandomEnable(self.raw.as_ptr()) }
4256    }
4257
4258    pub fn set_color_random_enable(&mut self, value: u32) {
4259        // SAFETY: plain scalar write through a live handle.
4260        unsafe {
4261            ffi::whiteout_m3_M3ParticleEmitter_set_colorRandomEnable(self.raw.as_ptr(), value)
4262        }
4263    }
4264
4265    /// Random color at birth
4266    /// Borrows the field in place — no copy, no allocation.
4267    pub fn color_start_random(&self) -> crate::support::Ref<'_, AnimRefM3ColorBGRA> {
4268        // SAFETY: an interior pointer into `self`, valid for this
4269        // borrow and never freed by the `Ref`.
4270        unsafe {
4271            crate::support::Ref::new(AnimRefM3ColorBGRA {
4272                raw: core::ptr::NonNull::new_unchecked(
4273                    ffi::whiteout_m3_M3ParticleEmitter_get_colorStartRandom(self.raw.as_ptr()),
4274                ),
4275            })
4276        }
4277    }
4278
4279    pub fn color_start_random_mut(&mut self) -> crate::support::RefMut<'_, AnimRefM3ColorBGRA> {
4280        // SAFETY: as above; `&mut self` guarantees exclusivity.
4281        unsafe {
4282            crate::support::RefMut::new(AnimRefM3ColorBGRA {
4283                raw: core::ptr::NonNull::new_unchecked(
4284                    ffi::whiteout_m3_M3ParticleEmitter_get_colorStartRandom(self.raw.as_ptr()),
4285                ),
4286            })
4287        }
4288    }
4289
4290    /// Random color at midpoint
4291    /// Borrows the field in place — no copy, no allocation.
4292    pub fn color_mid_random(&self) -> crate::support::Ref<'_, AnimRefM3ColorBGRA> {
4293        // SAFETY: an interior pointer into `self`, valid for this
4294        // borrow and never freed by the `Ref`.
4295        unsafe {
4296            crate::support::Ref::new(AnimRefM3ColorBGRA {
4297                raw: core::ptr::NonNull::new_unchecked(
4298                    ffi::whiteout_m3_M3ParticleEmitter_get_colorMidRandom(self.raw.as_ptr()),
4299                ),
4300            })
4301        }
4302    }
4303
4304    pub fn color_mid_random_mut(&mut self) -> crate::support::RefMut<'_, AnimRefM3ColorBGRA> {
4305        // SAFETY: as above; `&mut self` guarantees exclusivity.
4306        unsafe {
4307            crate::support::RefMut::new(AnimRefM3ColorBGRA {
4308                raw: core::ptr::NonNull::new_unchecked(
4309                    ffi::whiteout_m3_M3ParticleEmitter_get_colorMidRandom(self.raw.as_ptr()),
4310                ),
4311            })
4312        }
4313    }
4314
4315    /// Random color at death
4316    /// Borrows the field in place — no copy, no allocation.
4317    pub fn color_end_random(&self) -> crate::support::Ref<'_, AnimRefM3ColorBGRA> {
4318        // SAFETY: an interior pointer into `self`, valid for this
4319        // borrow and never freed by the `Ref`.
4320        unsafe {
4321            crate::support::Ref::new(AnimRefM3ColorBGRA {
4322                raw: core::ptr::NonNull::new_unchecked(
4323                    ffi::whiteout_m3_M3ParticleEmitter_get_colorEndRandom(self.raw.as_ptr()),
4324                ),
4325            })
4326        }
4327    }
4328
4329    pub fn color_end_random_mut(&mut self) -> crate::support::RefMut<'_, AnimRefM3ColorBGRA> {
4330        // SAFETY: as above; `&mut self` guarantees exclusivity.
4331        unsafe {
4332            crate::support::RefMut::new(AnimRefM3ColorBGRA {
4333                raw: core::ptr::NonNull::new_unchecked(
4334                    ffi::whiteout_m3_M3ParticleEmitter_get_colorEndRandom(self.raw.as_ptr()),
4335                ),
4336            })
4337        }
4338    }
4339
4340    /// Enable alpha randomization
4341    pub fn alpha_random_enable(&self) -> u32 {
4342        // SAFETY: plain scalar read through a live handle.
4343        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_alphaRandomEnable(self.raw.as_ptr()) }
4344    }
4345
4346    pub fn set_alpha_random_enable(&mut self, value: u32) {
4347        // SAFETY: plain scalar write through a live handle.
4348        unsafe {
4349            ffi::whiteout_m3_M3ParticleEmitter_set_alphaRandomEnable(self.raw.as_ptr(), value)
4350        }
4351    }
4352
4353    /// Animated squirt burst count
4354    /// Borrows the field in place — no copy, no allocation.
4355    pub fn squirt_amount(&self) -> crate::support::Ref<'_, AnimRefU16> {
4356        // SAFETY: an interior pointer into `self`, valid for this
4357        // borrow and never freed by the `Ref`.
4358        unsafe {
4359            crate::support::Ref::new(AnimRefU16 {
4360                raw: core::ptr::NonNull::new_unchecked(
4361                    ffi::whiteout_m3_M3ParticleEmitter_get_squirtAmount(self.raw.as_ptr()),
4362                ),
4363            })
4364        }
4365    }
4366
4367    pub fn squirt_amount_mut(&mut self) -> crate::support::RefMut<'_, AnimRefU16> {
4368        // SAFETY: as above; `&mut self` guarantees exclusivity.
4369        unsafe {
4370            crate::support::RefMut::new(AnimRefU16 {
4371                raw: core::ptr::NonNull::new_unchecked(
4372                    ffi::whiteout_m3_M3ParticleEmitter_get_squirtAmount(self.raw.as_ptr()),
4373                ),
4374            })
4375        }
4376    }
4377
4378    /// Flipbook start initial frame index
4379    pub fn flipbook_start_init_index(&self) -> u8 {
4380        // SAFETY: plain scalar read through a live handle.
4381        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_flipbookStartInitIndex(self.raw.as_ptr()) }
4382    }
4383
4384    pub fn set_flipbook_start_init_index(&mut self, value: u8) {
4385        // SAFETY: plain scalar write through a live handle.
4386        unsafe {
4387            ffi::whiteout_m3_M3ParticleEmitter_set_flipbookStartInitIndex(self.raw.as_ptr(), value)
4388        }
4389    }
4390
4391    /// Flipbook start stop frame index
4392    pub fn flipbook_start_stop_index(&self) -> u8 {
4393        // SAFETY: plain scalar read through a live handle.
4394        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_flipbookStartStopIndex(self.raw.as_ptr()) }
4395    }
4396
4397    pub fn set_flipbook_start_stop_index(&mut self, value: u8) {
4398        // SAFETY: plain scalar write through a live handle.
4399        unsafe {
4400            ffi::whiteout_m3_M3ParticleEmitter_set_flipbookStartStopIndex(self.raw.as_ptr(), value)
4401        }
4402    }
4403
4404    /// Flipbook end initial frame index
4405    pub fn flipbook_end_init_index(&self) -> u8 {
4406        // SAFETY: plain scalar read through a live handle.
4407        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_flipbookEndInitIndex(self.raw.as_ptr()) }
4408    }
4409
4410    pub fn set_flipbook_end_init_index(&mut self, value: u8) {
4411        // SAFETY: plain scalar write through a live handle.
4412        unsafe {
4413            ffi::whiteout_m3_M3ParticleEmitter_set_flipbookEndInitIndex(self.raw.as_ptr(), value)
4414        }
4415    }
4416
4417    /// Flipbook end stop frame index
4418    pub fn flipbook_end_stop_index(&self) -> u8 {
4419        // SAFETY: plain scalar read through a live handle.
4420        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_flipbookEndStopIndex(self.raw.as_ptr()) }
4421    }
4422
4423    pub fn set_flipbook_end_stop_index(&mut self, value: u8) {
4424        // SAFETY: plain scalar write through a live handle.
4425        unsafe {
4426            ffi::whiteout_m3_M3ParticleEmitter_set_flipbookEndStopIndex(self.raw.as_ptr(), value)
4427        }
4428    }
4429
4430    /// Flipbook midpoint time (0–1)
4431    pub fn flipbook_mid_time(&self) -> f32 {
4432        // SAFETY: plain scalar read through a live handle.
4433        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_flipbookMidTime(self.raw.as_ptr()) }
4434    }
4435
4436    pub fn set_flipbook_mid_time(&mut self, value: f32) {
4437        // SAFETY: plain scalar write through a live handle.
4438        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_flipbookMidTime(self.raw.as_ptr(), value) }
4439    }
4440
4441    /// Flipbook grid columns
4442    pub fn flipbook_columns(&self) -> u16 {
4443        // SAFETY: plain scalar read through a live handle.
4444        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_flipbookColumns(self.raw.as_ptr()) }
4445    }
4446
4447    pub fn set_flipbook_columns(&mut self, value: u16) {
4448        // SAFETY: plain scalar write through a live handle.
4449        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_flipbookColumns(self.raw.as_ptr(), value) }
4450    }
4451
4452    /// Flipbook grid rows
4453    pub fn flipbook_rows(&self) -> u16 {
4454        // SAFETY: plain scalar read through a live handle.
4455        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_flipbookRows(self.raw.as_ptr()) }
4456    }
4457
4458    pub fn set_flipbook_rows(&mut self, value: u16) {
4459        // SAFETY: plain scalar write through a live handle.
4460        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_flipbookRows(self.raw.as_ptr(), value) }
4461    }
4462
4463    /// Column fraction (v12+)
4464    pub fn flipbook_column_fraction(&self) -> f32 {
4465        // SAFETY: plain scalar read through a live handle.
4466        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_flipbookColumnFraction(self.raw.as_ptr()) }
4467    }
4468
4469    pub fn set_flipbook_column_fraction(&mut self, value: f32) {
4470        // SAFETY: plain scalar write through a live handle.
4471        unsafe {
4472            ffi::whiteout_m3_M3ParticleEmitter_set_flipbookColumnFraction(self.raw.as_ptr(), value)
4473        }
4474    }
4475
4476    /// Row fraction (v12+)
4477    pub fn flipbook_row_fraction(&self) -> f32 {
4478        // SAFETY: plain scalar read through a live handle.
4479        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_flipbookRowFraction(self.raw.as_ptr()) }
4480    }
4481
4482    pub fn set_flipbook_row_fraction(&mut self, value: f32) {
4483        // SAFETY: plain scalar write through a live handle.
4484        unsafe {
4485            ffi::whiteout_m3_M3ParticleEmitter_set_flipbookRowFraction(self.raw.as_ptr(), value)
4486        }
4487    }
4488
4489    /// Bounce coefficient
4490    pub fn bounce(&self) -> f32 {
4491        // SAFETY: plain scalar read through a live handle.
4492        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_bounce(self.raw.as_ptr()) }
4493    }
4494
4495    pub fn set_bounce(&mut self, value: f32) {
4496        // SAFETY: plain scalar write through a live handle.
4497        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_bounce(self.raw.as_ptr(), value) }
4498    }
4499
4500    /// Friction coefficient
4501    pub fn friction(&self) -> f32 {
4502        // SAFETY: plain scalar read through a live handle.
4503        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_friction(self.raw.as_ptr()) }
4504    }
4505
4506    pub fn set_friction(&mut self, value: f32) {
4507        // SAFETY: plain scalar write through a live handle.
4508        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_friction(self.raw.as_ptr(), value) }
4509    }
4510
4511    /// Emitter index to spawn on collision (-1 = none)
4512    pub fn collision_spawn_index(&self) -> i32 {
4513        // SAFETY: plain scalar read through a live handle.
4514        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_collisionSpawnIndex(self.raw.as_ptr()) }
4515    }
4516
4517    pub fn set_collision_spawn_index(&mut self, value: i32) {
4518        // SAFETY: plain scalar write through a live handle.
4519        unsafe {
4520            ffi::whiteout_m3_M3ParticleEmitter_set_collisionSpawnIndex(self.raw.as_ptr(), value)
4521        }
4522    }
4523
4524    /// Minimum spawn count on collision
4525    pub fn collision_spawn_min(&self) -> u32 {
4526        // SAFETY: plain scalar read through a live handle.
4527        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_collisionSpawnMin(self.raw.as_ptr()) }
4528    }
4529
4530    pub fn set_collision_spawn_min(&mut self, value: u32) {
4531        // SAFETY: plain scalar write through a live handle.
4532        unsafe {
4533            ffi::whiteout_m3_M3ParticleEmitter_set_collisionSpawnMin(self.raw.as_ptr(), value)
4534        }
4535    }
4536
4537    /// Maximum spawn count on collision
4538    pub fn collision_spawn_max(&self) -> u32 {
4539        // SAFETY: plain scalar read through a live handle.
4540        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_collisionSpawnMax(self.raw.as_ptr()) }
4541    }
4542
4543    pub fn set_collision_spawn_max(&mut self, value: u32) {
4544        // SAFETY: plain scalar write through a live handle.
4545        unsafe {
4546            ffi::whiteout_m3_M3ParticleEmitter_set_collisionSpawnMax(self.raw.as_ptr(), value)
4547        }
4548    }
4549
4550    /// Spawn probability on collision
4551    pub fn collision_spawn_chance(&self) -> f32 {
4552        // SAFETY: plain scalar read through a live handle.
4553        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_collisionSpawnChance(self.raw.as_ptr()) }
4554    }
4555
4556    pub fn set_collision_spawn_chance(&mut self, value: f32) {
4557        // SAFETY: plain scalar write through a live handle.
4558        unsafe {
4559            ffi::whiteout_m3_M3ParticleEmitter_set_collisionSpawnChance(self.raw.as_ptr(), value)
4560        }
4561    }
4562
4563    /// Spawn energy transfer
4564    pub fn collision_spawn_energy(&self) -> f32 {
4565        // SAFETY: plain scalar read through a live handle.
4566        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_collisionSpawnEnergy(self.raw.as_ptr()) }
4567    }
4568
4569    pub fn set_collision_spawn_energy(&mut self, value: f32) {
4570        // SAFETY: plain scalar write through a live handle.
4571        unsafe {
4572            ffi::whiteout_m3_M3ParticleEmitter_set_collisionSpawnEnergy(self.raw.as_ptr(), value)
4573        }
4574    }
4575
4576    /// Die after N bounces
4577    pub fn collision_die_bounce(&self) -> u32 {
4578        // SAFETY: plain scalar read through a live handle.
4579        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_collisionDieBounce(self.raw.as_ptr()) }
4580    }
4581
4582    pub fn set_collision_die_bounce(&mut self, value: u32) {
4583        // SAFETY: plain scalar write through a live handle.
4584        unsafe {
4585            ffi::whiteout_m3_M3ParticleEmitter_set_collisionDieBounce(self.raw.as_ptr(), value)
4586        }
4587    }
4588
4589    /// Visual type → shader b_iInstanceType
4590    pub fn instance_type(&self) -> ParticleInstanceType {
4591        // SAFETY: scalar read; the discriminant is validated below.
4592        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_instanceType(self.raw.as_ptr()) }
4593            .try_into()
4594            .expect("unknown enum discriminant from the native library")
4595    }
4596
4597    pub fn set_instance_type(&mut self, value: ParticleInstanceType) {
4598        // SAFETY: scalar write through a live handle.
4599        unsafe {
4600            ffi::whiteout_m3_M3ParticleEmitter_set_instanceType(self.raw.as_ptr(), value as i32)
4601        }
4602    }
4603
4604    /// Tail length for Tail/Trail types
4605    pub fn tail_length(&self) -> f32 {
4606        // SAFETY: plain scalar read through a live handle.
4607        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_tailLength(self.raw.as_ptr()) }
4608    }
4609
4610    pub fn set_tail_length(&mut self, value: f32) {
4611        // SAFETY: plain scalar write through a live handle.
4612        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_tailLength(self.raw.as_ptr(), value) }
4613    }
4614
4615    /// Instance orientation angles
4616    pub fn instance_angle(&self) -> crate::math::Vector3f {
4617        // SAFETY: the getter returns an interior pointer to a
4618        // layout-identical POD; we copy it out immediately.
4619        unsafe {
4620            *(ffi::whiteout_m3_M3ParticleEmitter_get_instanceAngle(self.raw.as_ptr())
4621                as *const crate::math::Vector3f)
4622        }
4623    }
4624
4625    pub fn set_instance_angle(&mut self, value: crate::math::Vector3f) {
4626        // SAFETY: as above, in the other direction.
4627        unsafe {
4628            ffi::whiteout_m3_M3ParticleEmitter_set_instanceAngle(
4629                self.raw.as_ptr(),
4630                &value as *const crate::math::Vector3f as *const _,
4631            )
4632        }
4633    }
4634
4635    /// Instance distance (v17+)
4636    pub fn instance_distance(&self) -> f32 {
4637        // SAFETY: plain scalar read through a live handle.
4638        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_instanceDistance(self.raw.as_ptr()) }
4639    }
4640
4641    pub fn set_instance_distance(&mut self, value: f32) {
4642        // SAFETY: plain scalar write through a live handle.
4643        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_instanceDistance(self.raw.as_ptr(), value) }
4644    }
4645
4646    /// Pitch variation type
4647    pub fn pitch_type(&self) -> u32 {
4648        // SAFETY: plain scalar read through a live handle.
4649        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_pitchType(self.raw.as_ptr()) }
4650    }
4651
4652    pub fn set_pitch_type(&mut self, value: u32) {
4653        // SAFETY: plain scalar write through a live handle.
4654        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_pitchType(self.raw.as_ptr(), value) }
4655    }
4656
4657    /// Pitch variation amplitude
4658    /// Borrows the field in place — no copy, no allocation.
4659    pub fn pitch_amplitude(&self) -> crate::support::Ref<'_, AnimRefF32> {
4660        // SAFETY: an interior pointer into `self`, valid for this
4661        // borrow and never freed by the `Ref`.
4662        unsafe {
4663            crate::support::Ref::new(AnimRefF32 {
4664                raw: core::ptr::NonNull::new_unchecked(
4665                    ffi::whiteout_m3_M3ParticleEmitter_get_pitchAmplitude(self.raw.as_ptr()),
4666                ),
4667            })
4668        }
4669    }
4670
4671    pub fn pitch_amplitude_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
4672        // SAFETY: as above; `&mut self` guarantees exclusivity.
4673        unsafe {
4674            crate::support::RefMut::new(AnimRefF32 {
4675                raw: core::ptr::NonNull::new_unchecked(
4676                    ffi::whiteout_m3_M3ParticleEmitter_get_pitchAmplitude(self.raw.as_ptr()),
4677                ),
4678            })
4679        }
4680    }
4681
4682    /// Pitch variation frequency
4683    /// Borrows the field in place — no copy, no allocation.
4684    pub fn pitch_frequency(&self) -> crate::support::Ref<'_, AnimRefF32> {
4685        // SAFETY: an interior pointer into `self`, valid for this
4686        // borrow and never freed by the `Ref`.
4687        unsafe {
4688            crate::support::Ref::new(AnimRefF32 {
4689                raw: core::ptr::NonNull::new_unchecked(
4690                    ffi::whiteout_m3_M3ParticleEmitter_get_pitchFrequency(self.raw.as_ptr()),
4691                ),
4692            })
4693        }
4694    }
4695
4696    pub fn pitch_frequency_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
4697        // SAFETY: as above; `&mut self` guarantees exclusivity.
4698        unsafe {
4699            crate::support::RefMut::new(AnimRefF32 {
4700                raw: core::ptr::NonNull::new_unchecked(
4701                    ffi::whiteout_m3_M3ParticleEmitter_get_pitchFrequency(self.raw.as_ptr()),
4702                ),
4703            })
4704        }
4705    }
4706
4707    /// Yaw variation type
4708    pub fn yaw_type(&self) -> u32 {
4709        // SAFETY: plain scalar read through a live handle.
4710        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_yawType(self.raw.as_ptr()) }
4711    }
4712
4713    pub fn set_yaw_type(&mut self, value: u32) {
4714        // SAFETY: plain scalar write through a live handle.
4715        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_yawType(self.raw.as_ptr(), value) }
4716    }
4717
4718    /// Yaw variation amplitude
4719    /// Borrows the field in place — no copy, no allocation.
4720    pub fn yaw_amplitude(&self) -> crate::support::Ref<'_, AnimRefF32> {
4721        // SAFETY: an interior pointer into `self`, valid for this
4722        // borrow and never freed by the `Ref`.
4723        unsafe {
4724            crate::support::Ref::new(AnimRefF32 {
4725                raw: core::ptr::NonNull::new_unchecked(
4726                    ffi::whiteout_m3_M3ParticleEmitter_get_yawAmplitude(self.raw.as_ptr()),
4727                ),
4728            })
4729        }
4730    }
4731
4732    pub fn yaw_amplitude_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
4733        // SAFETY: as above; `&mut self` guarantees exclusivity.
4734        unsafe {
4735            crate::support::RefMut::new(AnimRefF32 {
4736                raw: core::ptr::NonNull::new_unchecked(
4737                    ffi::whiteout_m3_M3ParticleEmitter_get_yawAmplitude(self.raw.as_ptr()),
4738                ),
4739            })
4740        }
4741    }
4742
4743    /// Yaw variation frequency
4744    /// Borrows the field in place — no copy, no allocation.
4745    pub fn yaw_frequency(&self) -> crate::support::Ref<'_, AnimRefF32> {
4746        // SAFETY: an interior pointer into `self`, valid for this
4747        // borrow and never freed by the `Ref`.
4748        unsafe {
4749            crate::support::Ref::new(AnimRefF32 {
4750                raw: core::ptr::NonNull::new_unchecked(
4751                    ffi::whiteout_m3_M3ParticleEmitter_get_yawFrequency(self.raw.as_ptr()),
4752                ),
4753            })
4754        }
4755    }
4756
4757    pub fn yaw_frequency_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
4758        // SAFETY: as above; `&mut self` guarantees exclusivity.
4759        unsafe {
4760            crate::support::RefMut::new(AnimRefF32 {
4761                raw: core::ptr::NonNull::new_unchecked(
4762                    ffi::whiteout_m3_M3ParticleEmitter_get_yawFrequency(self.raw.as_ptr()),
4763                ),
4764            })
4765        }
4766    }
4767
4768    /// Speed variation type
4769    pub fn speed_type(&self) -> u32 {
4770        // SAFETY: plain scalar read through a live handle.
4771        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_speedType(self.raw.as_ptr()) }
4772    }
4773
4774    pub fn set_speed_type(&mut self, value: u32) {
4775        // SAFETY: plain scalar write through a live handle.
4776        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_speedType(self.raw.as_ptr(), value) }
4777    }
4778
4779    /// Speed variation amplitude
4780    /// Borrows the field in place — no copy, no allocation.
4781    pub fn speed_amplitude(&self) -> crate::support::Ref<'_, AnimRefF32> {
4782        // SAFETY: an interior pointer into `self`, valid for this
4783        // borrow and never freed by the `Ref`.
4784        unsafe {
4785            crate::support::Ref::new(AnimRefF32 {
4786                raw: core::ptr::NonNull::new_unchecked(
4787                    ffi::whiteout_m3_M3ParticleEmitter_get_speedAmplitude(self.raw.as_ptr()),
4788                ),
4789            })
4790        }
4791    }
4792
4793    pub fn speed_amplitude_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
4794        // SAFETY: as above; `&mut self` guarantees exclusivity.
4795        unsafe {
4796            crate::support::RefMut::new(AnimRefF32 {
4797                raw: core::ptr::NonNull::new_unchecked(
4798                    ffi::whiteout_m3_M3ParticleEmitter_get_speedAmplitude(self.raw.as_ptr()),
4799                ),
4800            })
4801        }
4802    }
4803
4804    /// Speed variation frequency
4805    /// Borrows the field in place — no copy, no allocation.
4806    pub fn speed_frequency(&self) -> crate::support::Ref<'_, AnimRefF32> {
4807        // SAFETY: an interior pointer into `self`, valid for this
4808        // borrow and never freed by the `Ref`.
4809        unsafe {
4810            crate::support::Ref::new(AnimRefF32 {
4811                raw: core::ptr::NonNull::new_unchecked(
4812                    ffi::whiteout_m3_M3ParticleEmitter_get_speedFrequency(self.raw.as_ptr()),
4813                ),
4814            })
4815        }
4816    }
4817
4818    pub fn speed_frequency_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
4819        // SAFETY: as above; `&mut self` guarantees exclusivity.
4820        unsafe {
4821            crate::support::RefMut::new(AnimRefF32 {
4822                raw: core::ptr::NonNull::new_unchecked(
4823                    ffi::whiteout_m3_M3ParticleEmitter_get_speedFrequency(self.raw.as_ptr()),
4824                ),
4825            })
4826        }
4827    }
4828
4829    /// Size variation type
4830    pub fn size_type(&self) -> u32 {
4831        // SAFETY: plain scalar read through a live handle.
4832        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_sizeType(self.raw.as_ptr()) }
4833    }
4834
4835    pub fn set_size_type(&mut self, value: u32) {
4836        // SAFETY: plain scalar write through a live handle.
4837        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_sizeType(self.raw.as_ptr(), value) }
4838    }
4839
4840    /// Size variation amplitude
4841    /// Borrows the field in place — no copy, no allocation.
4842    pub fn size_amplitude(&self) -> crate::support::Ref<'_, AnimRefF32> {
4843        // SAFETY: an interior pointer into `self`, valid for this
4844        // borrow and never freed by the `Ref`.
4845        unsafe {
4846            crate::support::Ref::new(AnimRefF32 {
4847                raw: core::ptr::NonNull::new_unchecked(
4848                    ffi::whiteout_m3_M3ParticleEmitter_get_sizeAmplitude(self.raw.as_ptr()),
4849                ),
4850            })
4851        }
4852    }
4853
4854    pub fn size_amplitude_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
4855        // SAFETY: as above; `&mut self` guarantees exclusivity.
4856        unsafe {
4857            crate::support::RefMut::new(AnimRefF32 {
4858                raw: core::ptr::NonNull::new_unchecked(
4859                    ffi::whiteout_m3_M3ParticleEmitter_get_sizeAmplitude(self.raw.as_ptr()),
4860                ),
4861            })
4862        }
4863    }
4864
4865    /// Size variation frequency
4866    /// Borrows the field in place — no copy, no allocation.
4867    pub fn size_frequency(&self) -> crate::support::Ref<'_, AnimRefF32> {
4868        // SAFETY: an interior pointer into `self`, valid for this
4869        // borrow and never freed by the `Ref`.
4870        unsafe {
4871            crate::support::Ref::new(AnimRefF32 {
4872                raw: core::ptr::NonNull::new_unchecked(
4873                    ffi::whiteout_m3_M3ParticleEmitter_get_sizeFrequency(self.raw.as_ptr()),
4874                ),
4875            })
4876        }
4877    }
4878
4879    pub fn size_frequency_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
4880        // SAFETY: as above; `&mut self` guarantees exclusivity.
4881        unsafe {
4882            crate::support::RefMut::new(AnimRefF32 {
4883                raw: core::ptr::NonNull::new_unchecked(
4884                    ffi::whiteout_m3_M3ParticleEmitter_get_sizeFrequency(self.raw.as_ptr()),
4885                ),
4886            })
4887        }
4888    }
4889
4890    /// Alpha variation type
4891    pub fn alpha_type(&self) -> u32 {
4892        // SAFETY: plain scalar read through a live handle.
4893        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_alphaType(self.raw.as_ptr()) }
4894    }
4895
4896    pub fn set_alpha_type(&mut self, value: u32) {
4897        // SAFETY: plain scalar write through a live handle.
4898        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_alphaType(self.raw.as_ptr(), value) }
4899    }
4900
4901    /// Alpha variation amplitude
4902    /// Borrows the field in place — no copy, no allocation.
4903    pub fn alpha_amplitude(&self) -> crate::support::Ref<'_, AnimRefF32> {
4904        // SAFETY: an interior pointer into `self`, valid for this
4905        // borrow and never freed by the `Ref`.
4906        unsafe {
4907            crate::support::Ref::new(AnimRefF32 {
4908                raw: core::ptr::NonNull::new_unchecked(
4909                    ffi::whiteout_m3_M3ParticleEmitter_get_alphaAmplitude(self.raw.as_ptr()),
4910                ),
4911            })
4912        }
4913    }
4914
4915    pub fn alpha_amplitude_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
4916        // SAFETY: as above; `&mut self` guarantees exclusivity.
4917        unsafe {
4918            crate::support::RefMut::new(AnimRefF32 {
4919                raw: core::ptr::NonNull::new_unchecked(
4920                    ffi::whiteout_m3_M3ParticleEmitter_get_alphaAmplitude(self.raw.as_ptr()),
4921                ),
4922            })
4923        }
4924    }
4925
4926    /// Alpha variation frequency
4927    /// Borrows the field in place — no copy, no allocation.
4928    pub fn alpha_frequency(&self) -> crate::support::Ref<'_, AnimRefF32> {
4929        // SAFETY: an interior pointer into `self`, valid for this
4930        // borrow and never freed by the `Ref`.
4931        unsafe {
4932            crate::support::Ref::new(AnimRefF32 {
4933                raw: core::ptr::NonNull::new_unchecked(
4934                    ffi::whiteout_m3_M3ParticleEmitter_get_alphaFrequency(self.raw.as_ptr()),
4935                ),
4936            })
4937        }
4938    }
4939
4940    pub fn alpha_frequency_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
4941        // SAFETY: as above; `&mut self` guarantees exclusivity.
4942        unsafe {
4943            crate::support::RefMut::new(AnimRefF32 {
4944                raw: core::ptr::NonNull::new_unchecked(
4945                    ffi::whiteout_m3_M3ParticleEmitter_get_alphaFrequency(self.raw.as_ptr()),
4946                ),
4947            })
4948        }
4949    }
4950
4951    /// Color variation type
4952    pub fn color_type(&self) -> u32 {
4953        // SAFETY: plain scalar read through a live handle.
4954        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_colorType(self.raw.as_ptr()) }
4955    }
4956
4957    pub fn set_color_type(&mut self, value: u32) {
4958        // SAFETY: plain scalar write through a live handle.
4959        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_colorType(self.raw.as_ptr(), value) }
4960    }
4961
4962    /// Color variation amplitude
4963    /// Borrows the field in place — no copy, no allocation.
4964    pub fn color_amplitude(&self) -> crate::support::Ref<'_, AnimRefF32> {
4965        // SAFETY: an interior pointer into `self`, valid for this
4966        // borrow and never freed by the `Ref`.
4967        unsafe {
4968            crate::support::Ref::new(AnimRefF32 {
4969                raw: core::ptr::NonNull::new_unchecked(
4970                    ffi::whiteout_m3_M3ParticleEmitter_get_colorAmplitude(self.raw.as_ptr()),
4971                ),
4972            })
4973        }
4974    }
4975
4976    pub fn color_amplitude_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
4977        // SAFETY: as above; `&mut self` guarantees exclusivity.
4978        unsafe {
4979            crate::support::RefMut::new(AnimRefF32 {
4980                raw: core::ptr::NonNull::new_unchecked(
4981                    ffi::whiteout_m3_M3ParticleEmitter_get_colorAmplitude(self.raw.as_ptr()),
4982                ),
4983            })
4984        }
4985    }
4986
4987    /// Color variation frequency
4988    /// Borrows the field in place — no copy, no allocation.
4989    pub fn color_frequency(&self) -> crate::support::Ref<'_, AnimRefF32> {
4990        // SAFETY: an interior pointer into `self`, valid for this
4991        // borrow and never freed by the `Ref`.
4992        unsafe {
4993            crate::support::Ref::new(AnimRefF32 {
4994                raw: core::ptr::NonNull::new_unchecked(
4995                    ffi::whiteout_m3_M3ParticleEmitter_get_colorFrequency(self.raw.as_ptr()),
4996                ),
4997            })
4998        }
4999    }
5000
5001    pub fn color_frequency_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
5002        // SAFETY: as above; `&mut self` guarantees exclusivity.
5003        unsafe {
5004            crate::support::RefMut::new(AnimRefF32 {
5005                raw: core::ptr::NonNull::new_unchecked(
5006                    ffi::whiteout_m3_M3ParticleEmitter_get_colorFrequency(self.raw.as_ptr()),
5007                ),
5008            })
5009        }
5010    }
5011
5012    /// Rotation variation type
5013    pub fn rotation_type(&self) -> u32 {
5014        // SAFETY: plain scalar read through a live handle.
5015        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_rotationType(self.raw.as_ptr()) }
5016    }
5017
5018    pub fn set_rotation_type(&mut self, value: u32) {
5019        // SAFETY: plain scalar write through a live handle.
5020        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_rotationType(self.raw.as_ptr(), value) }
5021    }
5022
5023    /// Rotation variation amplitude
5024    /// Borrows the field in place — no copy, no allocation.
5025    pub fn rotation_amplitude(&self) -> crate::support::Ref<'_, AnimRefF32> {
5026        // SAFETY: an interior pointer into `self`, valid for this
5027        // borrow and never freed by the `Ref`.
5028        unsafe {
5029            crate::support::Ref::new(AnimRefF32 {
5030                raw: core::ptr::NonNull::new_unchecked(
5031                    ffi::whiteout_m3_M3ParticleEmitter_get_rotationAmplitude(self.raw.as_ptr()),
5032                ),
5033            })
5034        }
5035    }
5036
5037    pub fn rotation_amplitude_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
5038        // SAFETY: as above; `&mut self` guarantees exclusivity.
5039        unsafe {
5040            crate::support::RefMut::new(AnimRefF32 {
5041                raw: core::ptr::NonNull::new_unchecked(
5042                    ffi::whiteout_m3_M3ParticleEmitter_get_rotationAmplitude(self.raw.as_ptr()),
5043                ),
5044            })
5045        }
5046    }
5047
5048    /// Rotation variation frequency
5049    /// Borrows the field in place — no copy, no allocation.
5050    pub fn rotation_frequency(&self) -> crate::support::Ref<'_, AnimRefF32> {
5051        // SAFETY: an interior pointer into `self`, valid for this
5052        // borrow and never freed by the `Ref`.
5053        unsafe {
5054            crate::support::Ref::new(AnimRefF32 {
5055                raw: core::ptr::NonNull::new_unchecked(
5056                    ffi::whiteout_m3_M3ParticleEmitter_get_rotationFrequency(self.raw.as_ptr()),
5057                ),
5058            })
5059        }
5060    }
5061
5062    pub fn rotation_frequency_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
5063        // SAFETY: as above; `&mut self` guarantees exclusivity.
5064        unsafe {
5065            crate::support::RefMut::new(AnimRefF32 {
5066                raw: core::ptr::NonNull::new_unchecked(
5067                    ffi::whiteout_m3_M3ParticleEmitter_get_rotationFrequency(self.raw.as_ptr()),
5068                ),
5069            })
5070        }
5071    }
5072
5073    /// Horizontal variation type
5074    pub fn horizontal_type(&self) -> u32 {
5075        // SAFETY: plain scalar read through a live handle.
5076        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_horizontalType(self.raw.as_ptr()) }
5077    }
5078
5079    pub fn set_horizontal_type(&mut self, value: u32) {
5080        // SAFETY: plain scalar write through a live handle.
5081        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_horizontalType(self.raw.as_ptr(), value) }
5082    }
5083
5084    /// Horizontal variation amplitude
5085    /// Borrows the field in place — no copy, no allocation.
5086    pub fn horizontal_amplitude(&self) -> crate::support::Ref<'_, AnimRefF32> {
5087        // SAFETY: an interior pointer into `self`, valid for this
5088        // borrow and never freed by the `Ref`.
5089        unsafe {
5090            crate::support::Ref::new(AnimRefF32 {
5091                raw: core::ptr::NonNull::new_unchecked(
5092                    ffi::whiteout_m3_M3ParticleEmitter_get_horizontalAmplitude(self.raw.as_ptr()),
5093                ),
5094            })
5095        }
5096    }
5097
5098    pub fn horizontal_amplitude_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
5099        // SAFETY: as above; `&mut self` guarantees exclusivity.
5100        unsafe {
5101            crate::support::RefMut::new(AnimRefF32 {
5102                raw: core::ptr::NonNull::new_unchecked(
5103                    ffi::whiteout_m3_M3ParticleEmitter_get_horizontalAmplitude(self.raw.as_ptr()),
5104                ),
5105            })
5106        }
5107    }
5108
5109    /// Horizontal variation frequency
5110    /// Borrows the field in place — no copy, no allocation.
5111    pub fn horizontal_frequency(&self) -> crate::support::Ref<'_, AnimRefF32> {
5112        // SAFETY: an interior pointer into `self`, valid for this
5113        // borrow and never freed by the `Ref`.
5114        unsafe {
5115            crate::support::Ref::new(AnimRefF32 {
5116                raw: core::ptr::NonNull::new_unchecked(
5117                    ffi::whiteout_m3_M3ParticleEmitter_get_horizontalFrequency(self.raw.as_ptr()),
5118                ),
5119            })
5120        }
5121    }
5122
5123    pub fn horizontal_frequency_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
5124        // SAFETY: as above; `&mut self` guarantees exclusivity.
5125        unsafe {
5126            crate::support::RefMut::new(AnimRefF32 {
5127                raw: core::ptr::NonNull::new_unchecked(
5128                    ffi::whiteout_m3_M3ParticleEmitter_get_horizontalFrequency(self.raw.as_ptr()),
5129                ),
5130            })
5131        }
5132    }
5133
5134    /// Vertical variation type
5135    pub fn vertical_type(&self) -> u32 {
5136        // SAFETY: plain scalar read through a live handle.
5137        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_verticalType(self.raw.as_ptr()) }
5138    }
5139
5140    pub fn set_vertical_type(&mut self, value: u32) {
5141        // SAFETY: plain scalar write through a live handle.
5142        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_verticalType(self.raw.as_ptr(), value) }
5143    }
5144
5145    /// Vertical variation amplitude
5146    /// Borrows the field in place — no copy, no allocation.
5147    pub fn vertical_amplitude(&self) -> crate::support::Ref<'_, AnimRefF32> {
5148        // SAFETY: an interior pointer into `self`, valid for this
5149        // borrow and never freed by the `Ref`.
5150        unsafe {
5151            crate::support::Ref::new(AnimRefF32 {
5152                raw: core::ptr::NonNull::new_unchecked(
5153                    ffi::whiteout_m3_M3ParticleEmitter_get_verticalAmplitude(self.raw.as_ptr()),
5154                ),
5155            })
5156        }
5157    }
5158
5159    pub fn vertical_amplitude_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
5160        // SAFETY: as above; `&mut self` guarantees exclusivity.
5161        unsafe {
5162            crate::support::RefMut::new(AnimRefF32 {
5163                raw: core::ptr::NonNull::new_unchecked(
5164                    ffi::whiteout_m3_M3ParticleEmitter_get_verticalAmplitude(self.raw.as_ptr()),
5165                ),
5166            })
5167        }
5168    }
5169
5170    /// Vertical variation frequency;
5171    /// Borrows the field in place — no copy, no allocation.
5172    pub fn vertical_frequency(&self) -> crate::support::Ref<'_, AnimRefF32> {
5173        // SAFETY: an interior pointer into `self`, valid for this
5174        // borrow and never freed by the `Ref`.
5175        unsafe {
5176            crate::support::Ref::new(AnimRefF32 {
5177                raw: core::ptr::NonNull::new_unchecked(
5178                    ffi::whiteout_m3_M3ParticleEmitter_get_verticalFrequency(self.raw.as_ptr()),
5179                ),
5180            })
5181        }
5182    }
5183
5184    pub fn vertical_frequency_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
5185        // SAFETY: as above; `&mut self` guarantees exclusivity.
5186        unsafe {
5187            crate::support::RefMut::new(AnimRefF32 {
5188                raw: core::ptr::NonNull::new_unchecked(
5189                    ffi::whiteout_m3_M3ParticleEmitter_get_verticalFrequency(self.raw.as_ptr()),
5190                ),
5191            })
5192        }
5193    }
5194
5195    /// Animated parent velocity influence
5196    /// Borrows the field in place — no copy, no allocation.
5197    pub fn particle_velocity(&self) -> crate::support::Ref<'_, AnimRefF32> {
5198        // SAFETY: an interior pointer into `self`, valid for this
5199        // borrow and never freed by the `Ref`.
5200        unsafe {
5201            crate::support::Ref::new(AnimRefF32 {
5202                raw: core::ptr::NonNull::new_unchecked(
5203                    ffi::whiteout_m3_M3ParticleEmitter_get_particleVelocity(self.raw.as_ptr()),
5204                ),
5205            })
5206        }
5207    }
5208
5209    pub fn particle_velocity_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
5210        // SAFETY: as above; `&mut self` guarantees exclusivity.
5211        unsafe {
5212            crate::support::RefMut::new(AnimRefF32 {
5213                raw: core::ptr::NonNull::new_unchecked(
5214                    ffi::whiteout_m3_M3ParticleEmitter_get_particleVelocity(self.raw.as_ptr()),
5215                ),
5216            })
5217        }
5218    }
5219
5220    /// Animated phase shift (v22+)
5221    /// Borrows the field in place — no copy, no allocation.
5222    pub fn phase_shift(&self) -> crate::support::Ref<'_, AnimRefF32> {
5223        // SAFETY: an interior pointer into `self`, valid for this
5224        // borrow and never freed by the `Ref`.
5225        unsafe {
5226            crate::support::Ref::new(AnimRefF32 {
5227                raw: core::ptr::NonNull::new_unchecked(
5228                    ffi::whiteout_m3_M3ParticleEmitter_get_phaseShift(self.raw.as_ptr()),
5229                ),
5230            })
5231        }
5232    }
5233
5234    pub fn phase_shift_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
5235        // SAFETY: as above; `&mut self` guarantees exclusivity.
5236        unsafe {
5237            crate::support::RefMut::new(AnimRefF32 {
5238                raw: core::ptr::NonNull::new_unchecked(
5239                    ffi::whiteout_m3_M3ParticleEmitter_get_phaseShift(self.raw.as_ptr()),
5240                ),
5241            })
5242        }
5243    }
5244
5245    /// Main particle flags
5246    pub fn flags(&self) -> ParticleFlag {
5247        // SAFETY: scalar read; a flag set accepts any bits.
5248        ParticleFlag(unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_flags(self.raw.as_ptr()) })
5249    }
5250
5251    pub fn set_flags(&mut self, value: ParticleFlag) {
5252        // SAFETY: scalar write through a live handle.
5253        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_flags(self.raw.as_ptr(), value.0) }
5254    }
5255
5256    /// Rotation flags (v18+)
5257    pub fn rotation_flags(&self) -> ParticleRotationFlag {
5258        // SAFETY: scalar read; the discriminant is validated below.
5259        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_rotationFlags(self.raw.as_ptr()) }
5260            .try_into()
5261            .expect("unknown enum discriminant from the native library")
5262    }
5263
5264    pub fn set_rotation_flags(&mut self, value: ParticleRotationFlag) {
5265        // SAFETY: scalar write through a live handle.
5266        unsafe {
5267            ffi::whiteout_m3_M3ParticleEmitter_set_rotationFlags(self.raw.as_ptr(), value as i32)
5268        }
5269    }
5270
5271    pub fn color_smoothing(&self) -> InterpolationMode {
5272        // SAFETY: scalar read; the discriminant is validated below.
5273        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_colorSmoothing(self.raw.as_ptr()) }
5274            .try_into()
5275            .expect("unknown enum discriminant from the native library")
5276    }
5277
5278    pub fn set_color_smoothing(&mut self, value: InterpolationMode) {
5279        // SAFETY: scalar write through a live handle.
5280        unsafe {
5281            ffi::whiteout_m3_M3ParticleEmitter_set_colorSmoothing(self.raw.as_ptr(), value as i32)
5282        }
5283    }
5284
5285    pub fn size_smoothing(&self) -> InterpolationMode {
5286        // SAFETY: scalar read; the discriminant is validated below.
5287        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_sizeSmoothing(self.raw.as_ptr()) }
5288            .try_into()
5289            .expect("unknown enum discriminant from the native library")
5290    }
5291
5292    pub fn set_size_smoothing(&mut self, value: InterpolationMode) {
5293        // SAFETY: scalar write through a live handle.
5294        unsafe {
5295            ffi::whiteout_m3_M3ParticleEmitter_set_sizeSmoothing(self.raw.as_ptr(), value as i32)
5296        }
5297    }
5298
5299    pub fn rotation_smoothing(&self) -> InterpolationMode {
5300        // SAFETY: scalar read; the discriminant is validated below.
5301        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_rotationSmoothing(self.raw.as_ptr()) }
5302            .try_into()
5303            .expect("unknown enum discriminant from the native library")
5304    }
5305
5306    pub fn set_rotation_smoothing(&mut self, value: InterpolationMode) {
5307        // SAFETY: scalar write through a live handle.
5308        unsafe {
5309            ffi::whiteout_m3_M3ParticleEmitter_set_rotationSmoothing(
5310                self.raw.as_ptr(),
5311                value as i32,
5312            )
5313        }
5314    }
5315
5316    /// Animated alpha threshold
5317    /// Borrows the field in place — no copy, no allocation.
5318    pub fn alpha_threshold(&self) -> crate::support::Ref<'_, AnimRefF32> {
5319        // SAFETY: an interior pointer into `self`, valid for this
5320        // borrow and never freed by the `Ref`.
5321        unsafe {
5322            crate::support::Ref::new(AnimRefF32 {
5323                raw: core::ptr::NonNull::new_unchecked(
5324                    ffi::whiteout_m3_M3ParticleEmitter_get_alphaThreshold(self.raw.as_ptr()),
5325                ),
5326            })
5327        }
5328    }
5329
5330    pub fn alpha_threshold_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
5331        // SAFETY: as above; `&mut self` guarantees exclusivity.
5332        unsafe {
5333            crate::support::RefMut::new(AnimRefF32 {
5334                raw: core::ptr::NonNull::new_unchecked(
5335                    ffi::whiteout_m3_M3ParticleEmitter_get_alphaThreshold(self.raw.as_ptr()),
5336                ),
5337            })
5338        }
5339    }
5340
5341    /// Animated UV offset
5342    /// Borrows the field in place — no copy, no allocation.
5343    pub fn uv_offset(&self) -> crate::support::Ref<'_, AnimRefVector2f> {
5344        // SAFETY: an interior pointer into `self`, valid for this
5345        // borrow and never freed by the `Ref`.
5346        unsafe {
5347            crate::support::Ref::new(AnimRefVector2f {
5348                raw: core::ptr::NonNull::new_unchecked(
5349                    ffi::whiteout_m3_M3ParticleEmitter_get_uvOffset(self.raw.as_ptr()),
5350                ),
5351            })
5352        }
5353    }
5354
5355    pub fn uv_offset_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector2f> {
5356        // SAFETY: as above; `&mut self` guarantees exclusivity.
5357        unsafe {
5358            crate::support::RefMut::new(AnimRefVector2f {
5359                raw: core::ptr::NonNull::new_unchecked(
5360                    ffi::whiteout_m3_M3ParticleEmitter_get_uvOffset(self.raw.as_ptr()),
5361                ),
5362            })
5363        }
5364    }
5365
5366    /// Animated UV rotation angles
5367    /// Borrows the field in place — no copy, no allocation.
5368    pub fn uv_angle(&self) -> crate::support::Ref<'_, AnimRefVector3f> {
5369        // SAFETY: an interior pointer into `self`, valid for this
5370        // borrow and never freed by the `Ref`.
5371        unsafe {
5372            crate::support::Ref::new(AnimRefVector3f {
5373                raw: core::ptr::NonNull::new_unchecked(
5374                    ffi::whiteout_m3_M3ParticleEmitter_get_uvAngle(self.raw.as_ptr()),
5375                ),
5376            })
5377        }
5378    }
5379
5380    pub fn uv_angle_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector3f> {
5381        // SAFETY: as above; `&mut self` guarantees exclusivity.
5382        unsafe {
5383            crate::support::RefMut::new(AnimRefVector3f {
5384                raw: core::ptr::NonNull::new_unchecked(
5385                    ffi::whiteout_m3_M3ParticleEmitter_get_uvAngle(self.raw.as_ptr()),
5386                ),
5387            })
5388        }
5389    }
5390
5391    /// Animated UV tiling
5392    /// Borrows the field in place — no copy, no allocation.
5393    pub fn uv_tiling(&self) -> crate::support::Ref<'_, AnimRefVector2f> {
5394        // SAFETY: an interior pointer into `self`, valid for this
5395        // borrow and never freed by the `Ref`.
5396        unsafe {
5397            crate::support::Ref::new(AnimRefVector2f {
5398                raw: core::ptr::NonNull::new_unchecked(
5399                    ffi::whiteout_m3_M3ParticleEmitter_get_uvTiling(self.raw.as_ptr()),
5400                ),
5401            })
5402        }
5403    }
5404
5405    pub fn uv_tiling_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector2f> {
5406        // SAFETY: as above; `&mut self` guarantees exclusivity.
5407        unsafe {
5408            crate::support::RefMut::new(AnimRefVector2f {
5409                raw: core::ptr::NonNull::new_unchecked(
5410                    ffi::whiteout_m3_M3ParticleEmitter_get_uvTiling(self.raw.as_ptr()),
5411                ),
5412            })
5413        }
5414    }
5415
5416    /// Spline control points (SVC3)
5417    pub fn spline_line_data_len(&self) -> usize {
5418        // SAFETY: scalar read through a live handle.
5419        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_splineLineData_count(self.raw.as_ptr()) }
5420    }
5421
5422    /// Borrows element `index` in place. `None` when out of range.
5423    pub fn spline_line_data(
5424        &self,
5425        index: usize,
5426    ) -> Option<crate::support::Ref<'_, AnimRefVector3f>> {
5427        if index >= self.spline_line_data_len() {
5428            return None;
5429        }
5430        // SAFETY: index checked above; the pointer is interior to `self`.
5431        unsafe {
5432            Some(crate::support::Ref::new(AnimRefVector3f {
5433                raw: core::ptr::NonNull::new_unchecked(
5434                    ffi::whiteout_m3_M3ParticleEmitter_get_splineLineData_at(
5435                        self.raw.as_ptr(),
5436                        index,
5437                    ),
5438                ),
5439            }))
5440        }
5441    }
5442
5443    pub fn spline_line_data_mut(
5444        &mut self,
5445        index: usize,
5446    ) -> Option<crate::support::RefMut<'_, AnimRefVector3f>> {
5447        if index >= self.spline_line_data_len() {
5448            return None;
5449        }
5450        // SAFETY: as above; `&mut self` guarantees exclusivity.
5451        unsafe {
5452            Some(crate::support::RefMut::new(AnimRefVector3f {
5453                raw: core::ptr::NonNull::new_unchecked(
5454                    ffi::whiteout_m3_M3ParticleEmitter_get_splineLineData_at(
5455                        self.raw.as_ptr(),
5456                        index,
5457                    ),
5458                ),
5459            }))
5460        }
5461    }
5462
5463    /// Iterate the elements, borrowing each in turn.
5464    pub fn spline_line_data_iter(
5465        &self,
5466    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, AnimRefVector3f>> {
5467        (0..self.spline_line_data_len())
5468            .map(move |i| self.spline_line_data(i).expect("index below len"))
5469    }
5470
5471    pub fn resize_spline_line_data(&mut self, count: usize) {
5472        // SAFETY: exclusive access, so no borrow is outstanding.
5473        unsafe {
5474            ffi::whiteout_m3_M3ParticleEmitter_resize_splineLineData(self.raw.as_ptr(), count)
5475        }
5476    }
5477
5478    /// Wind influence multiplier
5479    pub fn wind_multiplier(&self) -> f32 {
5480        // SAFETY: plain scalar read through a live handle.
5481        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_windMultiplier(self.raw.as_ptr()) }
5482    }
5483
5484    pub fn set_wind_multiplier(&mut self, value: f32) {
5485        // SAFETY: plain scalar write through a live handle.
5486        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_windMultiplier(self.raw.as_ptr(), value) }
5487    }
5488
5489    /// LOD reduction level
5490    pub fn lod_reduce(&self) -> u32 {
5491        // SAFETY: plain scalar read through a live handle.
5492        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_lodReduce(self.raw.as_ptr()) }
5493    }
5494
5495    pub fn set_lod_reduce(&mut self, value: u32) {
5496        // SAFETY: plain scalar write through a live handle.
5497        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_lodReduce(self.raw.as_ptr(), value) }
5498    }
5499
5500    /// LOD cut-off level
5501    pub fn lod_cut(&self) -> u32 {
5502        // SAFETY: plain scalar read through a live handle.
5503        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_lodCut(self.raw.as_ptr()) }
5504    }
5505
5506    pub fn set_lod_cut(&mut self, value: u32) {
5507        // SAFETY: plain scalar write through a live handle.
5508        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_lodCut(self.raw.as_ptr(), value) }
5509    }
5510
5511    /// Animated lower bound
5512    /// Borrows the field in place — no copy, no allocation.
5513    pub fn lower_bound(&self) -> crate::support::Ref<'_, AnimRefF32> {
5514        // SAFETY: an interior pointer into `self`, valid for this
5515        // borrow and never freed by the `Ref`.
5516        unsafe {
5517            crate::support::Ref::new(AnimRefF32 {
5518                raw: core::ptr::NonNull::new_unchecked(
5519                    ffi::whiteout_m3_M3ParticleEmitter_get_lowerBound(self.raw.as_ptr()),
5520                ),
5521            })
5522        }
5523    }
5524
5525    pub fn lower_bound_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
5526        // SAFETY: as above; `&mut self` guarantees exclusivity.
5527        unsafe {
5528            crate::support::RefMut::new(AnimRefF32 {
5529                raw: core::ptr::NonNull::new_unchecked(
5530                    ffi::whiteout_m3_M3ParticleEmitter_get_lowerBound(self.raw.as_ptr()),
5531                ),
5532            })
5533        }
5534    }
5535
5536    /// Animated upper bound
5537    /// Borrows the field in place — no copy, no allocation.
5538    pub fn upper_bound(&self) -> crate::support::Ref<'_, AnimRefF32> {
5539        // SAFETY: an interior pointer into `self`, valid for this
5540        // borrow and never freed by the `Ref`.
5541        unsafe {
5542            crate::support::Ref::new(AnimRefF32 {
5543                raw: core::ptr::NonNull::new_unchecked(
5544                    ffi::whiteout_m3_M3ParticleEmitter_get_upperBound(self.raw.as_ptr()),
5545                ),
5546            })
5547        }
5548    }
5549
5550    pub fn upper_bound_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
5551        // SAFETY: as above; `&mut self` guarantees exclusivity.
5552        unsafe {
5553            crate::support::RefMut::new(AnimRefF32 {
5554                raw: core::ptr::NonNull::new_unchecked(
5555                    ffi::whiteout_m3_M3ParticleEmitter_get_upperBound(self.raw.as_ptr()),
5556                ),
5557            })
5558        }
5559    }
5560
5561    pub fn trail_link_index(&self) -> i32 {
5562        // SAFETY: plain scalar read through a live handle.
5563        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_trailLinkIndex(self.raw.as_ptr()) }
5564    }
5565
5566    pub fn set_trail_link_index(&mut self, value: i32) {
5567        // SAFETY: plain scalar write through a live handle.
5568        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_trailLinkIndex(self.raw.as_ptr(), value) }
5569    }
5570
5571    /// Trail spawn probability
5572    pub fn trail_chance(&self) -> f32 {
5573        // SAFETY: plain scalar read through a live handle.
5574        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_trailChance(self.raw.as_ptr()) }
5575    }
5576
5577    pub fn set_trail_chance(&mut self, value: f32) {
5578        // SAFETY: plain scalar write through a live handle.
5579        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_trailChance(self.raw.as_ptr(), value) }
5580    }
5581
5582    /// Animated trail emission rate
5583    /// Borrows the field in place — no copy, no allocation.
5584    pub fn trail_emission_rate(&self) -> crate::support::Ref<'_, AnimRefF32> {
5585        // SAFETY: an interior pointer into `self`, valid for this
5586        // borrow and never freed by the `Ref`.
5587        unsafe {
5588            crate::support::Ref::new(AnimRefF32 {
5589                raw: core::ptr::NonNull::new_unchecked(
5590                    ffi::whiteout_m3_M3ParticleEmitter_get_trailEmissionRate(self.raw.as_ptr()),
5591                ),
5592            })
5593        }
5594    }
5595
5596    pub fn trail_emission_rate_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
5597        // SAFETY: as above; `&mut self` guarantees exclusivity.
5598        unsafe {
5599            crate::support::RefMut::new(AnimRefF32 {
5600                raw: core::ptr::NonNull::new_unchecked(
5601                    ffi::whiteout_m3_M3ParticleEmitter_get_trailEmissionRate(self.raw.as_ptr()),
5602                ),
5603            })
5604        }
5605    }
5606
5607    /// Linked projector index (-1 = none)
5608    pub fn splat_projection_index(&self) -> i32 {
5609        // SAFETY: plain scalar read through a live handle.
5610        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_splatProjectionIndex(self.raw.as_ptr()) }
5611    }
5612
5613    pub fn set_splat_projection_index(&mut self, value: i32) {
5614        // SAFETY: plain scalar write through a live handle.
5615        unsafe {
5616            ffi::whiteout_m3_M3ParticleEmitter_set_splatProjectionIndex(self.raw.as_ptr(), value)
5617        }
5618    }
5619
5620    /// Splat spawn probability
5621    pub fn splat_chance(&self) -> f32 {
5622        // SAFETY: plain scalar read through a live handle.
5623        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_splatChance(self.raw.as_ptr()) }
5624    }
5625
5626    pub fn set_splat_chance(&mut self, value: f32) {
5627        // SAFETY: plain scalar write through a live handle.
5628        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_splatChance(self.raw.as_ptr(), value) }
5629    }
5630
5631    /// Emitter copy indices (U32_)
5632    /// Zero-copy view of the underlying `std::vector`.
5633    pub fn copy_indices(&self) -> &[u32] {
5634        // SAFETY: `_data`/`_count` describe one contiguous C++
5635        // allocation, borrowed for as long as `self` is.
5636        unsafe {
5637            let n = ffi::whiteout_m3_M3ParticleEmitter_get_copyIndices_count(self.raw.as_ptr());
5638            let p = ffi::whiteout_m3_M3ParticleEmitter_get_copyIndices_data(self.raw.as_ptr());
5639            if p.is_null() || n == 0 {
5640                &[]
5641            } else {
5642                core::slice::from_raw_parts(p, n)
5643            }
5644        }
5645    }
5646
5647    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
5648    pub fn copy_indices_mut(&mut self) -> &mut [u32] {
5649        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
5650        unsafe {
5651            let n = ffi::whiteout_m3_M3ParticleEmitter_get_copyIndices_count(self.raw.as_ptr());
5652            let p = ffi::whiteout_m3_M3ParticleEmitter_get_copyIndices_data(self.raw.as_ptr())
5653                as *mut u32;
5654            if p.is_null() || n == 0 {
5655                &mut []
5656            } else {
5657                core::slice::from_raw_parts_mut(p, n)
5658            }
5659        }
5660    }
5661
5662    pub fn set_copy_indices(&mut self, values: &[u32]) {
5663        // SAFETY: the native side copies `values` before returning.
5664        unsafe {
5665            ffi::whiteout_m3_M3ParticleEmitter_assign_copyIndices(
5666                self.raw.as_ptr(),
5667                values.as_ptr() as *const _,
5668                values.len(),
5669            )
5670        }
5671    }
5672
5673    pub fn resize_copy_indices(&mut self, count: usize) {
5674        // SAFETY: reallocation is safe here precisely because
5675        // `&mut self` means no slice borrow is outstanding.
5676        unsafe { ffi::whiteout_m3_M3ParticleEmitter_resize_copyIndices(self.raw.as_ptr(), count) }
5677    }
5678
5679    /// Ribbon spawn probability on bounce (v23+)
5680    pub fn spawn_ribbon_on_bounce_chance(&self) -> f32 {
5681        // SAFETY: plain scalar read through a live handle.
5682        unsafe {
5683            ffi::whiteout_m3_M3ParticleEmitter_get_spawnRibbonOnBounceChance(self.raw.as_ptr())
5684        }
5685    }
5686
5687    pub fn set_spawn_ribbon_on_bounce_chance(&mut self, value: f32) {
5688        // SAFETY: plain scalar write through a live handle.
5689        unsafe {
5690            ffi::whiteout_m3_M3ParticleEmitter_set_spawnRibbonOnBounceChance(
5691                self.raw.as_ptr(),
5692                value,
5693            )
5694        }
5695    }
5696
5697    /// Index into RIB_ array (-1 = none, v23+)
5698    pub fn ribbon_link_index(&self) -> i32 {
5699        // SAFETY: plain scalar read through a live handle.
5700        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_ribbonLinkIndex(self.raw.as_ptr()) }
5701    }
5702
5703    pub fn set_ribbon_link_index(&mut self, value: i32) {
5704        // SAFETY: plain scalar write through a live handle.
5705        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_ribbonLinkIndex(self.raw.as_ptr(), value) }
5706    }
5707}
5708
5709impl Default for ParticleEmitter {
5710    fn default() -> Self {
5711        Self::new()
5712    }
5713}
5714
5715/// PARC — Particle emitter copy (v0, 40 bytes)
5716///
5717/// Lightweight copy of a particle emitter with overridden emission rate, squirt amount, and bone index. References the original PAR_ via Model.copyIndices.
5718pub struct ParticleEmitterCopy {
5719    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3ParticleEmitterCopy>,
5720}
5721
5722impl Drop for ParticleEmitterCopy {
5723    fn drop(&mut self) {
5724        // SAFETY: `raw` came from a native constructor and Drop runs once.
5725        unsafe { ffi::whiteout_m3_M3ParticleEmitterCopy_delete(self.raw.as_ptr()) }
5726    }
5727}
5728
5729impl ParticleEmitterCopy {
5730    /// # Safety
5731    /// `raw` must be a live handle this value takes ownership of.
5732    #[allow(dead_code)] // used by whichever methods return this type
5733    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3ParticleEmitterCopy) -> Option<Self> {
5734        core::ptr::NonNull::new(raw).map(|raw| ParticleEmitterCopy { raw })
5735    }
5736}
5737
5738// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
5739// is deliberately NOT implemented — the C++ types make no documented
5740// guarantee about concurrent use, and claiming one we haven't verified
5741// would be unsound. See `@bind thread_safe` in the plan.
5742unsafe impl Send for ParticleEmitterCopy {}
5743
5744impl core::fmt::Debug for ParticleEmitterCopy {
5745    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
5746        f.debug_struct("ParticleEmitterCopy")
5747            .finish_non_exhaustive()
5748    }
5749}
5750
5751impl ParticleEmitterCopy {
5752    /// # Panics
5753    /// Panics if the native allocation fails.
5754    pub fn new() -> Self {
5755        // SAFETY: the native constructor returns a live handle; a null here
5756        // means the library is unusable.
5757        unsafe {
5758            let raw = ffi::whiteout_m3_M3ParticleEmitterCopy_new();
5759            Self::from_raw(raw).expect("native ParticleEmitterCopy allocation failed")
5760        }
5761    }
5762
5763    /// Overridden emission rate
5764    /// Borrows the field in place — no copy, no allocation.
5765    pub fn emission_rate(&self) -> crate::support::Ref<'_, AnimRefF32> {
5766        // SAFETY: an interior pointer into `self`, valid for this
5767        // borrow and never freed by the `Ref`.
5768        unsafe {
5769            crate::support::Ref::new(AnimRefF32 {
5770                raw: core::ptr::NonNull::new_unchecked(
5771                    ffi::whiteout_m3_M3ParticleEmitterCopy_get_emissionRate(self.raw.as_ptr()),
5772                ),
5773            })
5774        }
5775    }
5776
5777    pub fn emission_rate_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
5778        // SAFETY: as above; `&mut self` guarantees exclusivity.
5779        unsafe {
5780            crate::support::RefMut::new(AnimRefF32 {
5781                raw: core::ptr::NonNull::new_unchecked(
5782                    ffi::whiteout_m3_M3ParticleEmitterCopy_get_emissionRate(self.raw.as_ptr()),
5783                ),
5784            })
5785        }
5786    }
5787
5788    /// Overridden squirt burst count
5789    /// Borrows the field in place — no copy, no allocation.
5790    pub fn squirt_amount(&self) -> crate::support::Ref<'_, AnimRefU16> {
5791        // SAFETY: an interior pointer into `self`, valid for this
5792        // borrow and never freed by the `Ref`.
5793        unsafe {
5794            crate::support::Ref::new(AnimRefU16 {
5795                raw: core::ptr::NonNull::new_unchecked(
5796                    ffi::whiteout_m3_M3ParticleEmitterCopy_get_squirtAmount(self.raw.as_ptr()),
5797                ),
5798            })
5799        }
5800    }
5801
5802    pub fn squirt_amount_mut(&mut self) -> crate::support::RefMut<'_, AnimRefU16> {
5803        // SAFETY: as above; `&mut self` guarantees exclusivity.
5804        unsafe {
5805            crate::support::RefMut::new(AnimRefU16 {
5806                raw: core::ptr::NonNull::new_unchecked(
5807                    ffi::whiteout_m3_M3ParticleEmitterCopy_get_squirtAmount(self.raw.as_ptr()),
5808                ),
5809            })
5810        }
5811    }
5812
5813    /// Index into BONE array
5814    pub fn bone_index(&self) -> u32 {
5815        // SAFETY: plain scalar read through a live handle.
5816        unsafe { ffi::whiteout_m3_M3ParticleEmitterCopy_get_boneIndex(self.raw.as_ptr()) }
5817    }
5818
5819    pub fn set_bone_index(&mut self, value: u32) {
5820        // SAFETY: plain scalar write through a live handle.
5821        unsafe { ffi::whiteout_m3_M3ParticleEmitterCopy_set_boneIndex(self.raw.as_ptr(), value) }
5822    }
5823}
5824
5825impl Default for ParticleEmitterCopy {
5826    fn default() -> Self {
5827        Self::new()
5828    }
5829}
5830
5831/// SRIB — Spline ribbon segment (v0, 272 bytes)
5832///
5833/// Defines a single segment of a spline-based ribbon with emission offset/vector, velocity, bone binding, and pitch/yaw/velocity variation channels.
5834pub struct SplineRibbon {
5835    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3SplineRibbon>,
5836}
5837
5838impl Drop for SplineRibbon {
5839    fn drop(&mut self) {
5840        // SAFETY: `raw` came from a native constructor and Drop runs once.
5841        unsafe { ffi::whiteout_m3_M3SplineRibbon_delete(self.raw.as_ptr()) }
5842    }
5843}
5844
5845impl SplineRibbon {
5846    /// # Safety
5847    /// `raw` must be a live handle this value takes ownership of.
5848    #[allow(dead_code)] // used by whichever methods return this type
5849    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3SplineRibbon) -> Option<Self> {
5850        core::ptr::NonNull::new(raw).map(|raw| SplineRibbon { raw })
5851    }
5852}
5853
5854// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
5855// is deliberately NOT implemented — the C++ types make no documented
5856// guarantee about concurrent use, and claiming one we haven't verified
5857// would be unsound. See `@bind thread_safe` in the plan.
5858unsafe impl Send for SplineRibbon {}
5859
5860impl core::fmt::Debug for SplineRibbon {
5861    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
5862        f.debug_struct("SplineRibbon").finish_non_exhaustive()
5863    }
5864}
5865
5866impl SplineRibbon {
5867    /// # Panics
5868    /// Panics if the native allocation fails.
5869    pub fn new() -> Self {
5870        // SAFETY: the native constructor returns a live handle; a null here
5871        // means the library is unusable.
5872        unsafe {
5873            let raw = ffi::whiteout_m3_M3SplineRibbon_new();
5874            Self::from_raw(raw).expect("native SplineRibbon allocation failed")
5875        }
5876    }
5877
5878    /// Emission point offset from bone
5879    pub fn emission_offset(&self) -> crate::math::Vector3f {
5880        // SAFETY: the getter returns an interior pointer to a
5881        // layout-identical POD; we copy it out immediately.
5882        unsafe {
5883            *(ffi::whiteout_m3_M3SplineRibbon_get_emissionOffset(self.raw.as_ptr())
5884                as *const crate::math::Vector3f)
5885        }
5886    }
5887
5888    pub fn set_emission_offset(&mut self, value: crate::math::Vector3f) {
5889        // SAFETY: as above, in the other direction.
5890        unsafe {
5891            ffi::whiteout_m3_M3SplineRibbon_set_emissionOffset(
5892                self.raw.as_ptr(),
5893                &value as *const crate::math::Vector3f as *const _,
5894            )
5895        }
5896    }
5897
5898    /// Emission direction vector
5899    pub fn emission_vector(&self) -> crate::math::Vector3f {
5900        // SAFETY: the getter returns an interior pointer to a
5901        // layout-identical POD; we copy it out immediately.
5902        unsafe {
5903            *(ffi::whiteout_m3_M3SplineRibbon_get_emissionVector(self.raw.as_ptr())
5904                as *const crate::math::Vector3f)
5905        }
5906    }
5907
5908    pub fn set_emission_vector(&mut self, value: crate::math::Vector3f) {
5909        // SAFETY: as above, in the other direction.
5910        unsafe {
5911            ffi::whiteout_m3_M3SplineRibbon_set_emissionVector(
5912                self.raw.as_ptr(),
5913                &value as *const crate::math::Vector3f as *const _,
5914            )
5915        }
5916    }
5917
5918    /// Animated base velocity
5919    /// Borrows the field in place — no copy, no allocation.
5920    pub fn velocity(&self) -> crate::support::Ref<'_, AnimRefF32> {
5921        // SAFETY: an interior pointer into `self`, valid for this
5922        // borrow and never freed by the `Ref`.
5923        unsafe {
5924            crate::support::Ref::new(AnimRefF32 {
5925                raw: core::ptr::NonNull::new_unchecked(
5926                    ffi::whiteout_m3_M3SplineRibbon_get_velocity(self.raw.as_ptr()),
5927                ),
5928            })
5929        }
5930    }
5931
5932    pub fn velocity_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
5933        // SAFETY: as above; `&mut self` guarantees exclusivity.
5934        unsafe {
5935            crate::support::RefMut::new(AnimRefF32 {
5936                raw: core::ptr::NonNull::new_unchecked(
5937                    ffi::whiteout_m3_M3SplineRibbon_get_velocity(self.raw.as_ptr()),
5938                ),
5939            })
5940        }
5941    }
5942
5943    /// Reserved (always 0)
5944    pub fn reserved(&self) -> u32 {
5945        // SAFETY: plain scalar read through a live handle.
5946        unsafe { ffi::whiteout_m3_M3SplineRibbon_get_reserved(self.raw.as_ptr()) }
5947    }
5948
5949    pub fn set_reserved(&mut self, value: u32) {
5950        // SAFETY: plain scalar write through a live handle.
5951        unsafe { ffi::whiteout_m3_M3SplineRibbon_set_reserved(self.raw.as_ptr(), value) }
5952    }
5953
5954    /// Index into BONE array
5955    pub fn bone_index(&self) -> u32 {
5956        // SAFETY: plain scalar read through a live handle.
5957        unsafe { ffi::whiteout_m3_M3SplineRibbon_get_boneIndex(self.raw.as_ptr()) }
5958    }
5959
5960    pub fn set_bone_index(&mut self, value: u32) {
5961        // SAFETY: plain scalar write through a live handle.
5962        unsafe { ffi::whiteout_m3_M3SplineRibbon_set_boneIndex(self.raw.as_ptr(), value) }
5963    }
5964
5965    /// Animated base velocity factor
5966    /// Borrows the field in place — no copy, no allocation.
5967    pub fn velocity_base_factor(&self) -> crate::support::Ref<'_, AnimRefF32> {
5968        // SAFETY: an interior pointer into `self`, valid for this
5969        // borrow and never freed by the `Ref`.
5970        unsafe {
5971            crate::support::Ref::new(AnimRefF32 {
5972                raw: core::ptr::NonNull::new_unchecked(
5973                    ffi::whiteout_m3_M3SplineRibbon_get_velocityBaseFactor(self.raw.as_ptr()),
5974                ),
5975            })
5976        }
5977    }
5978
5979    pub fn velocity_base_factor_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
5980        // SAFETY: as above; `&mut self` guarantees exclusivity.
5981        unsafe {
5982            crate::support::RefMut::new(AnimRefF32 {
5983                raw: core::ptr::NonNull::new_unchecked(
5984                    ffi::whiteout_m3_M3SplineRibbon_get_velocityBaseFactor(self.raw.as_ptr()),
5985                ),
5986            })
5987        }
5988    }
5989
5990    /// Animated end velocity factor
5991    /// Borrows the field in place — no copy, no allocation.
5992    pub fn velocity_end_factor(&self) -> crate::support::Ref<'_, AnimRefF32> {
5993        // SAFETY: an interior pointer into `self`, valid for this
5994        // borrow and never freed by the `Ref`.
5995        unsafe {
5996            crate::support::Ref::new(AnimRefF32 {
5997                raw: core::ptr::NonNull::new_unchecked(
5998                    ffi::whiteout_m3_M3SplineRibbon_get_velocityEndFactor(self.raw.as_ptr()),
5999                ),
6000            })
6001        }
6002    }
6003
6004    pub fn velocity_end_factor_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
6005        // SAFETY: as above; `&mut self` guarantees exclusivity.
6006        unsafe {
6007            crate::support::RefMut::new(AnimRefF32 {
6008                raw: core::ptr::NonNull::new_unchecked(
6009                    ffi::whiteout_m3_M3SplineRibbon_get_velocityEndFactor(self.raw.as_ptr()),
6010                ),
6011            })
6012        }
6013    }
6014
6015    /// Yaw variation type
6016    pub fn yaw_type(&self) -> u32 {
6017        // SAFETY: plain scalar read through a live handle.
6018        unsafe { ffi::whiteout_m3_M3SplineRibbon_get_yawType(self.raw.as_ptr()) }
6019    }
6020
6021    pub fn set_yaw_type(&mut self, value: u32) {
6022        // SAFETY: plain scalar write through a live handle.
6023        unsafe { ffi::whiteout_m3_M3SplineRibbon_set_yawType(self.raw.as_ptr(), value) }
6024    }
6025
6026    /// Yaw variation amplitude
6027    /// Borrows the field in place — no copy, no allocation.
6028    pub fn yaw_amplitude(&self) -> crate::support::Ref<'_, AnimRefF32> {
6029        // SAFETY: an interior pointer into `self`, valid for this
6030        // borrow and never freed by the `Ref`.
6031        unsafe {
6032            crate::support::Ref::new(AnimRefF32 {
6033                raw: core::ptr::NonNull::new_unchecked(
6034                    ffi::whiteout_m3_M3SplineRibbon_get_yawAmplitude(self.raw.as_ptr()),
6035                ),
6036            })
6037        }
6038    }
6039
6040    pub fn yaw_amplitude_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
6041        // SAFETY: as above; `&mut self` guarantees exclusivity.
6042        unsafe {
6043            crate::support::RefMut::new(AnimRefF32 {
6044                raw: core::ptr::NonNull::new_unchecked(
6045                    ffi::whiteout_m3_M3SplineRibbon_get_yawAmplitude(self.raw.as_ptr()),
6046                ),
6047            })
6048        }
6049    }
6050
6051    /// Yaw variation frequency
6052    /// Borrows the field in place — no copy, no allocation.
6053    pub fn yaw_frequency(&self) -> crate::support::Ref<'_, AnimRefF32> {
6054        // SAFETY: an interior pointer into `self`, valid for this
6055        // borrow and never freed by the `Ref`.
6056        unsafe {
6057            crate::support::Ref::new(AnimRefF32 {
6058                raw: core::ptr::NonNull::new_unchecked(
6059                    ffi::whiteout_m3_M3SplineRibbon_get_yawFrequency(self.raw.as_ptr()),
6060                ),
6061            })
6062        }
6063    }
6064
6065    pub fn yaw_frequency_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
6066        // SAFETY: as above; `&mut self` guarantees exclusivity.
6067        unsafe {
6068            crate::support::RefMut::new(AnimRefF32 {
6069                raw: core::ptr::NonNull::new_unchecked(
6070                    ffi::whiteout_m3_M3SplineRibbon_get_yawFrequency(self.raw.as_ptr()),
6071                ),
6072            })
6073        }
6074    }
6075
6076    /// Pitch variation type
6077    pub fn pitch_type(&self) -> u32 {
6078        // SAFETY: plain scalar read through a live handle.
6079        unsafe { ffi::whiteout_m3_M3SplineRibbon_get_pitchType(self.raw.as_ptr()) }
6080    }
6081
6082    pub fn set_pitch_type(&mut self, value: u32) {
6083        // SAFETY: plain scalar write through a live handle.
6084        unsafe { ffi::whiteout_m3_M3SplineRibbon_set_pitchType(self.raw.as_ptr(), value) }
6085    }
6086
6087    /// Pitch variation amplitude
6088    /// Borrows the field in place — no copy, no allocation.
6089    pub fn pitch_amplitude(&self) -> crate::support::Ref<'_, AnimRefF32> {
6090        // SAFETY: an interior pointer into `self`, valid for this
6091        // borrow and never freed by the `Ref`.
6092        unsafe {
6093            crate::support::Ref::new(AnimRefF32 {
6094                raw: core::ptr::NonNull::new_unchecked(
6095                    ffi::whiteout_m3_M3SplineRibbon_get_pitchAmplitude(self.raw.as_ptr()),
6096                ),
6097            })
6098        }
6099    }
6100
6101    pub fn pitch_amplitude_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
6102        // SAFETY: as above; `&mut self` guarantees exclusivity.
6103        unsafe {
6104            crate::support::RefMut::new(AnimRefF32 {
6105                raw: core::ptr::NonNull::new_unchecked(
6106                    ffi::whiteout_m3_M3SplineRibbon_get_pitchAmplitude(self.raw.as_ptr()),
6107                ),
6108            })
6109        }
6110    }
6111
6112    /// Pitch variation frequency
6113    /// Borrows the field in place — no copy, no allocation.
6114    pub fn pitch_frequency(&self) -> crate::support::Ref<'_, AnimRefF32> {
6115        // SAFETY: an interior pointer into `self`, valid for this
6116        // borrow and never freed by the `Ref`.
6117        unsafe {
6118            crate::support::Ref::new(AnimRefF32 {
6119                raw: core::ptr::NonNull::new_unchecked(
6120                    ffi::whiteout_m3_M3SplineRibbon_get_pitchFrequency(self.raw.as_ptr()),
6121                ),
6122            })
6123        }
6124    }
6125
6126    pub fn pitch_frequency_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
6127        // SAFETY: as above; `&mut self` guarantees exclusivity.
6128        unsafe {
6129            crate::support::RefMut::new(AnimRefF32 {
6130                raw: core::ptr::NonNull::new_unchecked(
6131                    ffi::whiteout_m3_M3SplineRibbon_get_pitchFrequency(self.raw.as_ptr()),
6132                ),
6133            })
6134        }
6135    }
6136
6137    /// Velocity variation type
6138    pub fn velocity_type(&self) -> u32 {
6139        // SAFETY: plain scalar read through a live handle.
6140        unsafe { ffi::whiteout_m3_M3SplineRibbon_get_velocityType(self.raw.as_ptr()) }
6141    }
6142
6143    pub fn set_velocity_type(&mut self, value: u32) {
6144        // SAFETY: plain scalar write through a live handle.
6145        unsafe { ffi::whiteout_m3_M3SplineRibbon_set_velocityType(self.raw.as_ptr(), value) }
6146    }
6147
6148    /// Velocity variation amplitude
6149    /// Borrows the field in place — no copy, no allocation.
6150    pub fn velocity_amplitude(&self) -> crate::support::Ref<'_, AnimRefF32> {
6151        // SAFETY: an interior pointer into `self`, valid for this
6152        // borrow and never freed by the `Ref`.
6153        unsafe {
6154            crate::support::Ref::new(AnimRefF32 {
6155                raw: core::ptr::NonNull::new_unchecked(
6156                    ffi::whiteout_m3_M3SplineRibbon_get_velocityAmplitude(self.raw.as_ptr()),
6157                ),
6158            })
6159        }
6160    }
6161
6162    pub fn velocity_amplitude_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
6163        // SAFETY: as above; `&mut self` guarantees exclusivity.
6164        unsafe {
6165            crate::support::RefMut::new(AnimRefF32 {
6166                raw: core::ptr::NonNull::new_unchecked(
6167                    ffi::whiteout_m3_M3SplineRibbon_get_velocityAmplitude(self.raw.as_ptr()),
6168                ),
6169            })
6170        }
6171    }
6172
6173    /// Velocity variation frequency
6174    /// Borrows the field in place — no copy, no allocation.
6175    pub fn velocity_frequency(&self) -> crate::support::Ref<'_, AnimRefF32> {
6176        // SAFETY: an interior pointer into `self`, valid for this
6177        // borrow and never freed by the `Ref`.
6178        unsafe {
6179            crate::support::Ref::new(AnimRefF32 {
6180                raw: core::ptr::NonNull::new_unchecked(
6181                    ffi::whiteout_m3_M3SplineRibbon_get_velocityFrequency(self.raw.as_ptr()),
6182                ),
6183            })
6184        }
6185    }
6186
6187    pub fn velocity_frequency_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
6188        // SAFETY: as above; `&mut self` guarantees exclusivity.
6189        unsafe {
6190            crate::support::RefMut::new(AnimRefF32 {
6191                raw: core::ptr::NonNull::new_unchecked(
6192                    ffi::whiteout_m3_M3SplineRibbon_get_velocityFrequency(self.raw.as_ptr()),
6193                ),
6194            })
6195        }
6196    }
6197
6198    /// Animated yaw angle
6199    /// Borrows the field in place — no copy, no allocation.
6200    pub fn yaw(&self) -> crate::support::Ref<'_, AnimRefF32> {
6201        // SAFETY: an interior pointer into `self`, valid for this
6202        // borrow and never freed by the `Ref`.
6203        unsafe {
6204            crate::support::Ref::new(AnimRefF32 {
6205                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3SplineRibbon_get_yaw(
6206                    self.raw.as_ptr(),
6207                )),
6208            })
6209        }
6210    }
6211
6212    pub fn yaw_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
6213        // SAFETY: as above; `&mut self` guarantees exclusivity.
6214        unsafe {
6215            crate::support::RefMut::new(AnimRefF32 {
6216                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3SplineRibbon_get_yaw(
6217                    self.raw.as_ptr(),
6218                )),
6219            })
6220        }
6221    }
6222
6223    /// Animated pitch angle
6224    /// Borrows the field in place — no copy, no allocation.
6225    pub fn pitch(&self) -> crate::support::Ref<'_, AnimRefF32> {
6226        // SAFETY: an interior pointer into `self`, valid for this
6227        // borrow and never freed by the `Ref`.
6228        unsafe {
6229            crate::support::Ref::new(AnimRefF32 {
6230                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3SplineRibbon_get_pitch(
6231                    self.raw.as_ptr(),
6232                )),
6233            })
6234        }
6235    }
6236
6237    pub fn pitch_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
6238        // SAFETY: as above; `&mut self` guarantees exclusivity.
6239        unsafe {
6240            crate::support::RefMut::new(AnimRefF32 {
6241                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3SplineRibbon_get_pitch(
6242                    self.raw.as_ptr(),
6243                )),
6244            })
6245        }
6246    }
6247
6248    /// Precomputed ≈ 0.01 / |emissionVector|
6249    pub fn emission_vector_norm_factor(&self) -> f32 {
6250        // SAFETY: plain scalar read through a live handle.
6251        unsafe { ffi::whiteout_m3_M3SplineRibbon_get_emissionVectorNormFactor(self.raw.as_ptr()) }
6252    }
6253
6254    pub fn set_emission_vector_norm_factor(&mut self, value: f32) {
6255        // SAFETY: plain scalar write through a live handle.
6256        unsafe {
6257            ffi::whiteout_m3_M3SplineRibbon_set_emissionVectorNormFactor(self.raw.as_ptr(), value)
6258        }
6259    }
6260
6261    /// Precomputed ≈ 0.01 / velocity.initValue
6262    pub fn velocity_norm_factor(&self) -> f32 {
6263        // SAFETY: plain scalar read through a live handle.
6264        unsafe { ffi::whiteout_m3_M3SplineRibbon_get_velocityNormFactor(self.raw.as_ptr()) }
6265    }
6266
6267    pub fn set_velocity_norm_factor(&mut self, value: f32) {
6268        // SAFETY: plain scalar write through a live handle.
6269        unsafe { ffi::whiteout_m3_M3SplineRibbon_set_velocityNormFactor(self.raw.as_ptr(), value) }
6270    }
6271}
6272
6273impl Default for SplineRibbon {
6274    fn default() -> Self {
6275        Self::new()
6276    }
6277}
6278
6279/// RIB_ — Ribbon emitter (v4–v9, 744–760 bytes)
6280///
6281/// Ribbon strip effect with per-particle lifetime, velocity, color/size curves, physics, noise, spline segments, variation channels, and smoothing/collision settings. Shares many fields with ParticleEmitter.
6282pub struct RibbonEmitter {
6283    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3RibbonEmitter>,
6284}
6285
6286impl Drop for RibbonEmitter {
6287    fn drop(&mut self) {
6288        // SAFETY: `raw` came from a native constructor and Drop runs once.
6289        unsafe { ffi::whiteout_m3_M3RibbonEmitter_delete(self.raw.as_ptr()) }
6290    }
6291}
6292
6293impl RibbonEmitter {
6294    /// # Safety
6295    /// `raw` must be a live handle this value takes ownership of.
6296    #[allow(dead_code)] // used by whichever methods return this type
6297    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3RibbonEmitter) -> Option<Self> {
6298        core::ptr::NonNull::new(raw).map(|raw| RibbonEmitter { raw })
6299    }
6300}
6301
6302// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
6303// is deliberately NOT implemented — the C++ types make no documented
6304// guarantee about concurrent use, and claiming one we haven't verified
6305// would be unsound. See `@bind thread_safe` in the plan.
6306unsafe impl Send for RibbonEmitter {}
6307
6308impl core::fmt::Debug for RibbonEmitter {
6309    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
6310        f.debug_struct("RibbonEmitter").finish_non_exhaustive()
6311    }
6312}
6313
6314impl RibbonEmitter {
6315    /// # Panics
6316    /// Panics if the native allocation fails.
6317    pub fn new() -> Self {
6318        // SAFETY: the native constructor returns a live handle; a null here
6319        // means the library is unusable.
6320        unsafe {
6321            let raw = ffi::whiteout_m3_M3RibbonEmitter_new();
6322            Self::from_raw(raw).expect("native RibbonEmitter allocation failed")
6323        }
6324    }
6325
6326    /// Primary bone index
6327    pub fn bone_index(&self) -> u16 {
6328        // SAFETY: plain scalar read through a live handle.
6329        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_boneIndex(self.raw.as_ptr()) }
6330    }
6331
6332    pub fn set_bone_index(&mut self, value: u16) {
6333        // SAFETY: plain scalar write through a live handle.
6334        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_boneIndex(self.raw.as_ptr(), value) }
6335    }
6336
6337    /// Fallback bone index
6338    pub fn bone_index_fallback(&self) -> u16 {
6339        // SAFETY: plain scalar read through a live handle.
6340        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_boneIndexFallback(self.raw.as_ptr()) }
6341    }
6342
6343    pub fn set_bone_index_fallback(&mut self, value: u16) {
6344        // SAFETY: plain scalar write through a live handle.
6345        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_boneIndexFallback(self.raw.as_ptr(), value) }
6346    }
6347
6348    /// Index into MATM material map array
6349    pub fn material_index(&self) -> u32 {
6350        // SAFETY: plain scalar read through a live handle.
6351        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_materialIndex(self.raw.as_ptr()) }
6352    }
6353
6354    pub fn set_material_index(&mut self, value: u32) {
6355        // SAFETY: plain scalar write through a live handle.
6356        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_materialIndex(self.raw.as_ptr(), value) }
6357    }
6358
6359    /// Additional flags (v8+)
6360    pub fn additional_flags(&self) -> RibbonAdditionalFlag {
6361        // SAFETY: scalar read; a flag set accepts any bits.
6362        RibbonAdditionalFlag(unsafe {
6363            ffi::whiteout_m3_M3RibbonEmitter_get_additionalFlags(self.raw.as_ptr())
6364        })
6365    }
6366
6367    pub fn set_additional_flags(&mut self, value: RibbonAdditionalFlag) {
6368        // SAFETY: scalar write through a live handle.
6369        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_additionalFlags(self.raw.as_ptr(), value.0) }
6370    }
6371
6372    /// Initial ribbon segment speed
6373    /// Borrows the field in place — no copy, no allocation.
6374    pub fn initial_speed(&self) -> crate::support::Ref<'_, AnimRefF32> {
6375        // SAFETY: an interior pointer into `self`, valid for this
6376        // borrow and never freed by the `Ref`.
6377        unsafe {
6378            crate::support::Ref::new(AnimRefF32 {
6379                raw: core::ptr::NonNull::new_unchecked(
6380                    ffi::whiteout_m3_M3RibbonEmitter_get_initialSpeed(self.raw.as_ptr()),
6381                ),
6382            })
6383        }
6384    }
6385
6386    pub fn initial_speed_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
6387        // SAFETY: as above; `&mut self` guarantees exclusivity.
6388        unsafe {
6389            crate::support::RefMut::new(AnimRefF32 {
6390                raw: core::ptr::NonNull::new_unchecked(
6391                    ffi::whiteout_m3_M3RibbonEmitter_get_initialSpeed(self.raw.as_ptr()),
6392                ),
6393            })
6394        }
6395    }
6396
6397    /// Random speed variation
6398    /// Borrows the field in place — no copy, no allocation.
6399    pub fn initial_speed_random(&self) -> crate::support::Ref<'_, AnimRefF32> {
6400        // SAFETY: an interior pointer into `self`, valid for this
6401        // borrow and never freed by the `Ref`.
6402        unsafe {
6403            crate::support::Ref::new(AnimRefF32 {
6404                raw: core::ptr::NonNull::new_unchecked(
6405                    ffi::whiteout_m3_M3RibbonEmitter_get_initialSpeedRandom(self.raw.as_ptr()),
6406                ),
6407            })
6408        }
6409    }
6410
6411    pub fn initial_speed_random_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
6412        // SAFETY: as above; `&mut self` guarantees exclusivity.
6413        unsafe {
6414            crate::support::RefMut::new(AnimRefF32 {
6415                raw: core::ptr::NonNull::new_unchecked(
6416                    ffi::whiteout_m3_M3RibbonEmitter_get_initialSpeedRandom(self.raw.as_ptr()),
6417                ),
6418            })
6419        }
6420    }
6421
6422    /// Initial yaw angle
6423    /// Borrows the field in place — no copy, no allocation.
6424    pub fn initial_yaw(&self) -> crate::support::Ref<'_, AnimRefF32> {
6425        // SAFETY: an interior pointer into `self`, valid for this
6426        // borrow and never freed by the `Ref`.
6427        unsafe {
6428            crate::support::Ref::new(AnimRefF32 {
6429                raw: core::ptr::NonNull::new_unchecked(
6430                    ffi::whiteout_m3_M3RibbonEmitter_get_initialYaw(self.raw.as_ptr()),
6431                ),
6432            })
6433        }
6434    }
6435
6436    pub fn initial_yaw_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
6437        // SAFETY: as above; `&mut self` guarantees exclusivity.
6438        unsafe {
6439            crate::support::RefMut::new(AnimRefF32 {
6440                raw: core::ptr::NonNull::new_unchecked(
6441                    ffi::whiteout_m3_M3RibbonEmitter_get_initialYaw(self.raw.as_ptr()),
6442                ),
6443            })
6444        }
6445    }
6446
6447    /// Initial pitch angle
6448    /// Borrows the field in place — no copy, no allocation.
6449    pub fn initial_pitch(&self) -> crate::support::Ref<'_, AnimRefF32> {
6450        // SAFETY: an interior pointer into `self`, valid for this
6451        // borrow and never freed by the `Ref`.
6452        unsafe {
6453            crate::support::Ref::new(AnimRefF32 {
6454                raw: core::ptr::NonNull::new_unchecked(
6455                    ffi::whiteout_m3_M3RibbonEmitter_get_initialPitch(self.raw.as_ptr()),
6456                ),
6457            })
6458        }
6459    }
6460
6461    pub fn initial_pitch_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
6462        // SAFETY: as above; `&mut self` guarantees exclusivity.
6463        unsafe {
6464            crate::support::RefMut::new(AnimRefF32 {
6465                raw: core::ptr::NonNull::new_unchecked(
6466                    ffi::whiteout_m3_M3RibbonEmitter_get_initialPitch(self.raw.as_ptr()),
6467                ),
6468            })
6469        }
6470    }
6471
6472    /// Initial horizontal spread
6473    /// Borrows the field in place — no copy, no allocation.
6474    pub fn initial_horizontal(&self) -> crate::support::Ref<'_, AnimRefF32> {
6475        // SAFETY: an interior pointer into `self`, valid for this
6476        // borrow and never freed by the `Ref`.
6477        unsafe {
6478            crate::support::Ref::new(AnimRefF32 {
6479                raw: core::ptr::NonNull::new_unchecked(
6480                    ffi::whiteout_m3_M3RibbonEmitter_get_initialHorizontal(self.raw.as_ptr()),
6481                ),
6482            })
6483        }
6484    }
6485
6486    pub fn initial_horizontal_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
6487        // SAFETY: as above; `&mut self` guarantees exclusivity.
6488        unsafe {
6489            crate::support::RefMut::new(AnimRefF32 {
6490                raw: core::ptr::NonNull::new_unchecked(
6491                    ffi::whiteout_m3_M3RibbonEmitter_get_initialHorizontal(self.raw.as_ptr()),
6492                ),
6493            })
6494        }
6495    }
6496
6497    /// Initial vertical spread
6498    /// Borrows the field in place — no copy, no allocation.
6499    pub fn initial_vertical(&self) -> crate::support::Ref<'_, AnimRefF32> {
6500        // SAFETY: an interior pointer into `self`, valid for this
6501        // borrow and never freed by the `Ref`.
6502        unsafe {
6503            crate::support::Ref::new(AnimRefF32 {
6504                raw: core::ptr::NonNull::new_unchecked(
6505                    ffi::whiteout_m3_M3RibbonEmitter_get_initialVertical(self.raw.as_ptr()),
6506                ),
6507            })
6508        }
6509    }
6510
6511    pub fn initial_vertical_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
6512        // SAFETY: as above; `&mut self` guarantees exclusivity.
6513        unsafe {
6514            crate::support::RefMut::new(AnimRefF32 {
6515                raw: core::ptr::NonNull::new_unchecked(
6516                    ffi::whiteout_m3_M3RibbonEmitter_get_initialVertical(self.raw.as_ptr()),
6517                ),
6518            })
6519        }
6520    }
6521
6522    /// Base segment lifetime
6523    /// Borrows the field in place — no copy, no allocation.
6524    pub fn lifetime(&self) -> crate::support::Ref<'_, AnimRefF32> {
6525        // SAFETY: an interior pointer into `self`, valid for this
6526        // borrow and never freed by the `Ref`.
6527        unsafe {
6528            crate::support::Ref::new(AnimRefF32 {
6529                raw: core::ptr::NonNull::new_unchecked(
6530                    ffi::whiteout_m3_M3RibbonEmitter_get_lifetime(self.raw.as_ptr()),
6531                ),
6532            })
6533        }
6534    }
6535
6536    pub fn lifetime_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
6537        // SAFETY: as above; `&mut self` guarantees exclusivity.
6538        unsafe {
6539            crate::support::RefMut::new(AnimRefF32 {
6540                raw: core::ptr::NonNull::new_unchecked(
6541                    ffi::whiteout_m3_M3RibbonEmitter_get_lifetime(self.raw.as_ptr()),
6542                ),
6543            })
6544        }
6545    }
6546
6547    /// Random lifetime variation
6548    /// Borrows the field in place — no copy, no allocation.
6549    pub fn lifetime_random(&self) -> crate::support::Ref<'_, AnimRefF32> {
6550        // SAFETY: an interior pointer into `self`, valid for this
6551        // borrow and never freed by the `Ref`.
6552        unsafe {
6553            crate::support::Ref::new(AnimRefF32 {
6554                raw: core::ptr::NonNull::new_unchecked(
6555                    ffi::whiteout_m3_M3RibbonEmitter_get_lifetimeRandom(self.raw.as_ptr()),
6556                ),
6557            })
6558        }
6559    }
6560
6561    pub fn lifetime_random_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
6562        // SAFETY: as above; `&mut self` guarantees exclusivity.
6563        unsafe {
6564            crate::support::RefMut::new(AnimRefF32 {
6565                raw: core::ptr::NonNull::new_unchecked(
6566                    ffi::whiteout_m3_M3RibbonEmitter_get_lifetimeRandom(self.raw.as_ptr()),
6567                ),
6568            })
6569        }
6570    }
6571
6572    /// Kill radius
6573    pub fn kill_radius(&self) -> u32 {
6574        // SAFETY: plain scalar read through a live handle.
6575        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_killRadius(self.raw.as_ptr()) }
6576    }
6577
6578    pub fn set_kill_radius(&mut self, value: u32) {
6579        // SAFETY: plain scalar write through a live handle.
6580        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_killRadius(self.raw.as_ptr(), value) }
6581    }
6582
6583    /// Gravity X component
6584    pub fn gravity_x(&self) -> f32 {
6585        // SAFETY: plain scalar read through a live handle.
6586        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_gravityX(self.raw.as_ptr()) }
6587    }
6588
6589    pub fn set_gravity_x(&mut self, value: f32) {
6590        // SAFETY: plain scalar write through a live handle.
6591        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_gravityX(self.raw.as_ptr(), value) }
6592    }
6593
6594    /// Gravity Y component
6595    pub fn gravity_y(&self) -> f32 {
6596        // SAFETY: plain scalar read through a live handle.
6597        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_gravityY(self.raw.as_ptr()) }
6598    }
6599
6600    pub fn set_gravity_y(&mut self, value: f32) {
6601        // SAFETY: plain scalar write through a live handle.
6602        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_gravityY(self.raw.as_ptr(), value) }
6603    }
6604
6605    /// Gravity Z component
6606    pub fn gravity(&self) -> f32 {
6607        // SAFETY: plain scalar read through a live handle.
6608        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_gravity(self.raw.as_ptr()) }
6609    }
6610
6611    pub fn set_gravity(&mut self, value: f32) {
6612        // SAFETY: plain scalar write through a live handle.
6613        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_gravity(self.raw.as_ptr(), value) }
6614    }
6615
6616    /// Size midpoint time (0–1)
6617    pub fn size_mid_time(&self) -> f32 {
6618        // SAFETY: plain scalar read through a live handle.
6619        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_sizeMidTime(self.raw.as_ptr()) }
6620    }
6621
6622    pub fn set_size_mid_time(&mut self, value: f32) {
6623        // SAFETY: plain scalar write through a live handle.
6624        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_sizeMidTime(self.raw.as_ptr(), value) }
6625    }
6626
6627    /// Color midpoint time (0–1)
6628    pub fn color_mid_time(&self) -> f32 {
6629        // SAFETY: plain scalar read through a live handle.
6630        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_colorMidTime(self.raw.as_ptr()) }
6631    }
6632
6633    pub fn set_color_mid_time(&mut self, value: f32) {
6634        // SAFETY: plain scalar write through a live handle.
6635        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_colorMidTime(self.raw.as_ptr(), value) }
6636    }
6637
6638    /// Alpha midpoint time (0–1)
6639    pub fn alpha_mid_time(&self) -> f32 {
6640        // SAFETY: plain scalar read through a live handle.
6641        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_alphaMidTime(self.raw.as_ptr()) }
6642    }
6643
6644    pub fn set_alpha_mid_time(&mut self, value: f32) {
6645        // SAFETY: plain scalar write through a live handle.
6646        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_alphaMidTime(self.raw.as_ptr(), value) }
6647    }
6648
6649    /// Rotation midpoint time (0–1)
6650    pub fn rotation_mid_time(&self) -> f32 {
6651        // SAFETY: plain scalar read through a live handle.
6652        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_rotationMidTime(self.raw.as_ptr()) }
6653    }
6654
6655    pub fn set_rotation_mid_time(&mut self, value: f32) {
6656        // SAFETY: plain scalar write through a live handle.
6657        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_rotationMidTime(self.raw.as_ptr(), value) }
6658    }
6659
6660    /// Size hold time at midpoint
6661    pub fn size_mid_hold_time(&self) -> f32 {
6662        // SAFETY: plain scalar read through a live handle.
6663        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_sizeMidHoldTime(self.raw.as_ptr()) }
6664    }
6665
6666    pub fn set_size_mid_hold_time(&mut self, value: f32) {
6667        // SAFETY: plain scalar write through a live handle.
6668        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_sizeMidHoldTime(self.raw.as_ptr(), value) }
6669    }
6670
6671    /// Color hold time at midpoint
6672    pub fn color_mid_hold_time(&self) -> f32 {
6673        // SAFETY: plain scalar read through a live handle.
6674        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_colorMidHoldTime(self.raw.as_ptr()) }
6675    }
6676
6677    pub fn set_color_mid_hold_time(&mut self, value: f32) {
6678        // SAFETY: plain scalar write through a live handle.
6679        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_colorMidHoldTime(self.raw.as_ptr(), value) }
6680    }
6681
6682    /// Alpha hold time at midpoint
6683    pub fn alpha_mid_hold_time(&self) -> f32 {
6684        // SAFETY: plain scalar read through a live handle.
6685        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_alphaMidHoldTime(self.raw.as_ptr()) }
6686    }
6687
6688    pub fn set_alpha_mid_hold_time(&mut self, value: f32) {
6689        // SAFETY: plain scalar write through a live handle.
6690        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_alphaMidHoldTime(self.raw.as_ptr(), value) }
6691    }
6692
6693    /// Rotation hold time at midpoint
6694    pub fn rotation_mid_hold_time(&self) -> f32 {
6695        // SAFETY: plain scalar read through a live handle.
6696        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_rotationMidHoldTime(self.raw.as_ptr()) }
6697    }
6698
6699    pub fn set_rotation_mid_hold_time(&mut self, value: f32) {
6700        // SAFETY: plain scalar write through a live handle.
6701        unsafe {
6702            ffi::whiteout_m3_M3RibbonEmitter_set_rotationMidHoldTime(self.raw.as_ptr(), value)
6703        }
6704    }
6705
6706    /// Size curve (start, mid, end)
6707    /// Borrows the field in place — no copy, no allocation.
6708    pub fn size_animation(&self) -> crate::support::Ref<'_, AnimRefVector3f> {
6709        // SAFETY: an interior pointer into `self`, valid for this
6710        // borrow and never freed by the `Ref`.
6711        unsafe {
6712            crate::support::Ref::new(AnimRefVector3f {
6713                raw: core::ptr::NonNull::new_unchecked(
6714                    ffi::whiteout_m3_M3RibbonEmitter_get_sizeAnimation(self.raw.as_ptr()),
6715                ),
6716            })
6717        }
6718    }
6719
6720    pub fn size_animation_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector3f> {
6721        // SAFETY: as above; `&mut self` guarantees exclusivity.
6722        unsafe {
6723            crate::support::RefMut::new(AnimRefVector3f {
6724                raw: core::ptr::NonNull::new_unchecked(
6725                    ffi::whiteout_m3_M3RibbonEmitter_get_sizeAnimation(self.raw.as_ptr()),
6726                ),
6727            })
6728        }
6729    }
6730
6731    /// Rotation curve (start, mid, end)
6732    /// Borrows the field in place — no copy, no allocation.
6733    pub fn rotation_animation(&self) -> crate::support::Ref<'_, AnimRefVector3f> {
6734        // SAFETY: an interior pointer into `self`, valid for this
6735        // borrow and never freed by the `Ref`.
6736        unsafe {
6737            crate::support::Ref::new(AnimRefVector3f {
6738                raw: core::ptr::NonNull::new_unchecked(
6739                    ffi::whiteout_m3_M3RibbonEmitter_get_rotationAnimation(self.raw.as_ptr()),
6740                ),
6741            })
6742        }
6743    }
6744
6745    pub fn rotation_animation_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector3f> {
6746        // SAFETY: as above; `&mut self` guarantees exclusivity.
6747        unsafe {
6748            crate::support::RefMut::new(AnimRefVector3f {
6749                raw: core::ptr::NonNull::new_unchecked(
6750                    ffi::whiteout_m3_M3RibbonEmitter_get_rotationAnimation(self.raw.as_ptr()),
6751                ),
6752            })
6753        }
6754    }
6755
6756    /// Color at birth
6757    /// Borrows the field in place — no copy, no allocation.
6758    pub fn color_start(&self) -> crate::support::Ref<'_, AnimRefM3ColorBGRA> {
6759        // SAFETY: an interior pointer into `self`, valid for this
6760        // borrow and never freed by the `Ref`.
6761        unsafe {
6762            crate::support::Ref::new(AnimRefM3ColorBGRA {
6763                raw: core::ptr::NonNull::new_unchecked(
6764                    ffi::whiteout_m3_M3RibbonEmitter_get_colorStart(self.raw.as_ptr()),
6765                ),
6766            })
6767        }
6768    }
6769
6770    pub fn color_start_mut(&mut self) -> crate::support::RefMut<'_, AnimRefM3ColorBGRA> {
6771        // SAFETY: as above; `&mut self` guarantees exclusivity.
6772        unsafe {
6773            crate::support::RefMut::new(AnimRefM3ColorBGRA {
6774                raw: core::ptr::NonNull::new_unchecked(
6775                    ffi::whiteout_m3_M3RibbonEmitter_get_colorStart(self.raw.as_ptr()),
6776                ),
6777            })
6778        }
6779    }
6780
6781    /// Color at midpoint
6782    /// Borrows the field in place — no copy, no allocation.
6783    pub fn color_mid(&self) -> crate::support::Ref<'_, AnimRefM3ColorBGRA> {
6784        // SAFETY: an interior pointer into `self`, valid for this
6785        // borrow and never freed by the `Ref`.
6786        unsafe {
6787            crate::support::Ref::new(AnimRefM3ColorBGRA {
6788                raw: core::ptr::NonNull::new_unchecked(
6789                    ffi::whiteout_m3_M3RibbonEmitter_get_colorMid(self.raw.as_ptr()),
6790                ),
6791            })
6792        }
6793    }
6794
6795    pub fn color_mid_mut(&mut self) -> crate::support::RefMut<'_, AnimRefM3ColorBGRA> {
6796        // SAFETY: as above; `&mut self` guarantees exclusivity.
6797        unsafe {
6798            crate::support::RefMut::new(AnimRefM3ColorBGRA {
6799                raw: core::ptr::NonNull::new_unchecked(
6800                    ffi::whiteout_m3_M3RibbonEmitter_get_colorMid(self.raw.as_ptr()),
6801                ),
6802            })
6803        }
6804    }
6805
6806    /// Color at death
6807    /// Borrows the field in place — no copy, no allocation.
6808    pub fn color_end(&self) -> crate::support::Ref<'_, AnimRefM3ColorBGRA> {
6809        // SAFETY: an interior pointer into `self`, valid for this
6810        // borrow and never freed by the `Ref`.
6811        unsafe {
6812            crate::support::Ref::new(AnimRefM3ColorBGRA {
6813                raw: core::ptr::NonNull::new_unchecked(
6814                    ffi::whiteout_m3_M3RibbonEmitter_get_colorEnd(self.raw.as_ptr()),
6815                ),
6816            })
6817        }
6818    }
6819
6820    pub fn color_end_mut(&mut self) -> crate::support::RefMut<'_, AnimRefM3ColorBGRA> {
6821        // SAFETY: as above; `&mut self` guarantees exclusivity.
6822        unsafe {
6823            crate::support::RefMut::new(AnimRefM3ColorBGRA {
6824                raw: core::ptr::NonNull::new_unchecked(
6825                    ffi::whiteout_m3_M3RibbonEmitter_get_colorEnd(self.raw.as_ptr()),
6826                ),
6827            })
6828        }
6829    }
6830
6831    /// Air drag coefficient
6832    pub fn drag(&self) -> f32 {
6833        // SAFETY: plain scalar read through a live handle.
6834        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_drag(self.raw.as_ptr()) }
6835    }
6836
6837    pub fn set_drag(&mut self, value: f32) {
6838        // SAFETY: plain scalar write through a live handle.
6839        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_drag(self.raw.as_ptr(), value) }
6840    }
6841
6842    /// Segment mass
6843    pub fn mass(&self) -> f32 {
6844        // SAFETY: plain scalar read through a live handle.
6845        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_mass(self.raw.as_ptr()) }
6846    }
6847
6848    pub fn set_mass(&mut self, value: f32) {
6849        // SAFETY: plain scalar write through a live handle.
6850        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_mass(self.raw.as_ptr(), value) }
6851    }
6852
6853    /// Random mass variation
6854    pub fn mass_random(&self) -> f32 {
6855        // SAFETY: plain scalar read through a live handle.
6856        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_massRandom(self.raw.as_ptr()) }
6857    }
6858
6859    pub fn set_mass_random(&mut self, value: f32) {
6860        // SAFETY: plain scalar write through a live handle.
6861        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_massRandom(self.raw.as_ptr(), value) }
6862    }
6863
6864    /// Mass–size coupling
6865    pub fn mass_size_multiplier(&self) -> f32 {
6866        // SAFETY: plain scalar read through a live handle.
6867        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_massSizeMultiplier(self.raw.as_ptr()) }
6868    }
6869
6870    pub fn set_mass_size_multiplier(&mut self, value: f32) {
6871        // SAFETY: plain scalar write through a live handle.
6872        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_massSizeMultiplier(self.raw.as_ptr(), value) }
6873    }
6874
6875    /// Local force channel bitmask
6876    pub fn local_forces(&self) -> u16 {
6877        // SAFETY: plain scalar read through a live handle.
6878        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_localForces(self.raw.as_ptr()) }
6879    }
6880
6881    pub fn set_local_forces(&mut self, value: u16) {
6882        // SAFETY: plain scalar write through a live handle.
6883        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_localForces(self.raw.as_ptr(), value) }
6884    }
6885
6886    /// World force channel bitmask
6887    pub fn world_forces(&self) -> u16 {
6888        // SAFETY: plain scalar read through a live handle.
6889        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_worldForces(self.raw.as_ptr()) }
6890    }
6891
6892    pub fn set_world_forces(&mut self, value: u16) {
6893        // SAFETY: plain scalar write through a live handle.
6894        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_worldForces(self.raw.as_ptr(), value) }
6895    }
6896
6897    /// Fallback local force channels
6898    pub fn local_forces_fallback(&self) -> u16 {
6899        // SAFETY: plain scalar read through a live handle.
6900        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_localForcesFallback(self.raw.as_ptr()) }
6901    }
6902
6903    pub fn set_local_forces_fallback(&mut self, value: u16) {
6904        // SAFETY: plain scalar write through a live handle.
6905        unsafe {
6906            ffi::whiteout_m3_M3RibbonEmitter_set_localForcesFallback(self.raw.as_ptr(), value)
6907        }
6908    }
6909
6910    /// Fallback world force channels
6911    pub fn world_forces_fallback(&self) -> u16 {
6912        // SAFETY: plain scalar read through a live handle.
6913        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_worldForcesFallback(self.raw.as_ptr()) }
6914    }
6915
6916    pub fn set_world_forces_fallback(&mut self, value: u16) {
6917        // SAFETY: plain scalar write through a live handle.
6918        unsafe {
6919            ffi::whiteout_m3_M3RibbonEmitter_set_worldForcesFallback(self.raw.as_ptr(), value)
6920        }
6921    }
6922
6923    /// World force mass multiplier
6924    pub fn world_forces_mass_multiplier(&self) -> f32 {
6925        // SAFETY: plain scalar read through a live handle.
6926        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_worldForcesMassMultiplier(self.raw.as_ptr()) }
6927    }
6928
6929    pub fn set_world_forces_mass_multiplier(&mut self, value: f32) {
6930        // SAFETY: plain scalar write through a live handle.
6931        unsafe {
6932            ffi::whiteout_m3_M3RibbonEmitter_set_worldForcesMassMultiplier(self.raw.as_ptr(), value)
6933        }
6934    }
6935
6936    /// Noise displacement amplitude
6937    pub fn noise_amplitude(&self) -> f32 {
6938        // SAFETY: plain scalar read through a live handle.
6939        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_noiseAmplitude(self.raw.as_ptr()) }
6940    }
6941
6942    pub fn set_noise_amplitude(&mut self, value: f32) {
6943        // SAFETY: plain scalar write through a live handle.
6944        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_noiseAmplitude(self.raw.as_ptr(), value) }
6945    }
6946
6947    /// Noise spatial frequency
6948    pub fn noise_frequency(&self) -> f32 {
6949        // SAFETY: plain scalar read through a live handle.
6950        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_noiseFrequency(self.raw.as_ptr()) }
6951    }
6952
6953    pub fn set_noise_frequency(&mut self, value: f32) {
6954        // SAFETY: plain scalar write through a live handle.
6955        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_noiseFrequency(self.raw.as_ptr(), value) }
6956    }
6957
6958    /// Noise temporal coherence
6959    pub fn noise_coherence(&self) -> f32 {
6960        // SAFETY: plain scalar read through a live handle.
6961        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_noiseCoherence(self.raw.as_ptr()) }
6962    }
6963
6964    pub fn set_noise_coherence(&mut self, value: f32) {
6965        // SAFETY: plain scalar write through a live handle.
6966        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_noiseCoherence(self.raw.as_ptr(), value) }
6967    }
6968
6969    /// Noise edge sharpness
6970    pub fn noise_edge(&self) -> f32 {
6971        // SAFETY: plain scalar read through a live handle.
6972        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_noiseEdge(self.raw.as_ptr()) }
6973    }
6974
6975    pub fn set_noise_edge(&mut self, value: f32) {
6976        // SAFETY: plain scalar write through a live handle.
6977        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_noiseEdge(self.raw.as_ptr(), value) }
6978    }
6979
6980    /// Index + length
6981    pub fn index_plus_length(&self) -> u32 {
6982        // SAFETY: plain scalar read through a live handle.
6983        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_indexPlusLength(self.raw.as_ptr()) }
6984    }
6985
6986    pub fn set_index_plus_length(&mut self, value: u32) {
6987        // SAFETY: plain scalar write through a live handle.
6988        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_indexPlusLength(self.raw.as_ptr(), value) }
6989    }
6990
6991    /// Emitter shape type
6992    pub fn emitter_shape(&self) -> u32 {
6993        // SAFETY: plain scalar read through a live handle.
6994        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_emitterShape(self.raw.as_ptr()) }
6995    }
6996
6997    pub fn set_emitter_shape(&mut self, value: u32) {
6998        // SAFETY: plain scalar write through a live handle.
6999        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_emitterShape(self.raw.as_ptr(), value) }
7000    }
7001
7002    /// Ribbon cross-section type
7003    pub fn ribbon_type(&self) -> RibbonType {
7004        // SAFETY: scalar read; the discriminant is validated below.
7005        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_ribbonType(self.raw.as_ptr()) }
7006            .try_into()
7007            .expect("unknown enum discriminant from the native library")
7008    }
7009
7010    pub fn set_ribbon_type(&mut self, value: RibbonType) {
7011        // SAFETY: scalar write through a live handle.
7012        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_ribbonType(self.raw.as_ptr(), value as i32) }
7013    }
7014
7015    /// Number of ribbon divisions
7016    pub fn divisions(&self) -> f32 {
7017        // SAFETY: plain scalar read through a live handle.
7018        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_divisions(self.raw.as_ptr()) }
7019    }
7020
7021    pub fn set_divisions(&mut self, value: f32) {
7022        // SAFETY: plain scalar write through a live handle.
7023        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_divisions(self.raw.as_ptr(), value) }
7024    }
7025
7026    /// Number of cross-section edges
7027    pub fn edges(&self) -> u32 {
7028        // SAFETY: plain scalar read through a live handle.
7029        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_edges(self.raw.as_ptr()) }
7030    }
7031
7032    pub fn set_edges(&mut self, value: u32) {
7033        // SAFETY: plain scalar write through a live handle.
7034        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_edges(self.raw.as_ptr(), value) }
7035    }
7036
7037    /// Inner radius
7038    pub fn inner_radius(&self) -> f32 {
7039        // SAFETY: plain scalar read through a live handle.
7040        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_innerRadius(self.raw.as_ptr()) }
7041    }
7042
7043    pub fn set_inner_radius(&mut self, value: f32) {
7044        // SAFETY: plain scalar write through a live handle.
7045        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_innerRadius(self.raw.as_ptr(), value) }
7046    }
7047
7048    /// Animated maximum ribbon length
7049    /// Borrows the field in place — no copy, no allocation.
7050    pub fn max_length(&self) -> crate::support::Ref<'_, AnimRefF32> {
7051        // SAFETY: an interior pointer into `self`, valid for this
7052        // borrow and never freed by the `Ref`.
7053        unsafe {
7054            crate::support::Ref::new(AnimRefF32 {
7055                raw: core::ptr::NonNull::new_unchecked(
7056                    ffi::whiteout_m3_M3RibbonEmitter_get_maxLength(self.raw.as_ptr()),
7057                ),
7058            })
7059        }
7060    }
7061
7062    pub fn max_length_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7063        // SAFETY: as above; `&mut self` guarantees exclusivity.
7064        unsafe {
7065            crate::support::RefMut::new(AnimRefF32 {
7066                raw: core::ptr::NonNull::new_unchecked(
7067                    ffi::whiteout_m3_M3RibbonEmitter_get_maxLength(self.raw.as_ptr()),
7068                ),
7069            })
7070        }
7071    }
7072
7073    /// Spline ribbon segments (SRIB)
7074    pub fn spline_ribbons_len(&self) -> usize {
7075        // SAFETY: scalar read through a live handle.
7076        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_splineRibbons_count(self.raw.as_ptr()) }
7077    }
7078
7079    /// Borrows element `index` in place. `None` when out of range.
7080    pub fn spline_ribbons(&self, index: usize) -> Option<crate::support::Ref<'_, SplineRibbon>> {
7081        if index >= self.spline_ribbons_len() {
7082            return None;
7083        }
7084        // SAFETY: index checked above; the pointer is interior to `self`.
7085        unsafe {
7086            Some(crate::support::Ref::new(SplineRibbon {
7087                raw: core::ptr::NonNull::new_unchecked(
7088                    ffi::whiteout_m3_M3RibbonEmitter_get_splineRibbons_at(self.raw.as_ptr(), index),
7089                ),
7090            }))
7091        }
7092    }
7093
7094    pub fn spline_ribbons_mut(
7095        &mut self,
7096        index: usize,
7097    ) -> Option<crate::support::RefMut<'_, SplineRibbon>> {
7098        if index >= self.spline_ribbons_len() {
7099            return None;
7100        }
7101        // SAFETY: as above; `&mut self` guarantees exclusivity.
7102        unsafe {
7103            Some(crate::support::RefMut::new(SplineRibbon {
7104                raw: core::ptr::NonNull::new_unchecked(
7105                    ffi::whiteout_m3_M3RibbonEmitter_get_splineRibbons_at(self.raw.as_ptr(), index),
7106                ),
7107            }))
7108        }
7109    }
7110
7111    /// Iterate the elements, borrowing each in turn.
7112    pub fn spline_ribbons_iter(
7113        &self,
7114    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, SplineRibbon>> {
7115        (0..self.spline_ribbons_len())
7116            .map(move |i| self.spline_ribbons(i).expect("index below len"))
7117    }
7118
7119    pub fn resize_spline_ribbons(&mut self, count: usize) {
7120        // SAFETY: exclusive access, so no borrow is outstanding.
7121        unsafe { ffi::whiteout_m3_M3RibbonEmitter_resize_splineRibbons(self.raw.as_ptr(), count) }
7122    }
7123
7124    /// Animated active state
7125    /// Borrows the field in place — no copy, no allocation.
7126    pub fn active(&self) -> crate::support::Ref<'_, AnimRefU32> {
7127        // SAFETY: an interior pointer into `self`, valid for this
7128        // borrow and never freed by the `Ref`.
7129        unsafe {
7130            crate::support::Ref::new(AnimRefU32 {
7131                raw: core::ptr::NonNull::new_unchecked(
7132                    ffi::whiteout_m3_M3RibbonEmitter_get_active(self.raw.as_ptr()),
7133                ),
7134            })
7135        }
7136    }
7137
7138    pub fn active_mut(&mut self) -> crate::support::RefMut<'_, AnimRefU32> {
7139        // SAFETY: as above; `&mut self` guarantees exclusivity.
7140        unsafe {
7141            crate::support::RefMut::new(AnimRefU32 {
7142                raw: core::ptr::NonNull::new_unchecked(
7143                    ffi::whiteout_m3_M3RibbonEmitter_get_active(self.raw.as_ptr()),
7144                ),
7145            })
7146        }
7147    }
7148
7149    /// Ribbon emitter flags
7150    pub fn flags(&self) -> RibbonFlag {
7151        // SAFETY: scalar read; a flag set accepts any bits.
7152        RibbonFlag(unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_flags(self.raw.as_ptr()) })
7153    }
7154
7155    pub fn set_flags(&mut self, value: RibbonFlag) {
7156        // SAFETY: scalar write through a live handle.
7157        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_flags(self.raw.as_ptr(), value.0) }
7158    }
7159
7160    /// Size interpolation mode
7161    pub fn size_smoothing(&self) -> InterpolationMode {
7162        // SAFETY: scalar read; the discriminant is validated below.
7163        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_sizeSmoothing(self.raw.as_ptr()) }
7164            .try_into()
7165            .expect("unknown enum discriminant from the native library")
7166    }
7167
7168    pub fn set_size_smoothing(&mut self, value: InterpolationMode) {
7169        // SAFETY: scalar write through a live handle.
7170        unsafe {
7171            ffi::whiteout_m3_M3RibbonEmitter_set_sizeSmoothing(self.raw.as_ptr(), value as i32)
7172        }
7173    }
7174
7175    /// Color interpolation mode
7176    pub fn color_smoothing(&self) -> InterpolationMode {
7177        // SAFETY: scalar read; the discriminant is validated below.
7178        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_colorSmoothing(self.raw.as_ptr()) }
7179            .try_into()
7180            .expect("unknown enum discriminant from the native library")
7181    }
7182
7183    pub fn set_color_smoothing(&mut self, value: InterpolationMode) {
7184        // SAFETY: scalar write through a live handle.
7185        unsafe {
7186            ffi::whiteout_m3_M3RibbonEmitter_set_colorSmoothing(self.raw.as_ptr(), value as i32)
7187        }
7188    }
7189
7190    /// Friction coefficient
7191    pub fn friction(&self) -> f32 {
7192        // SAFETY: plain scalar read through a live handle.
7193        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_friction(self.raw.as_ptr()) }
7194    }
7195
7196    pub fn set_friction(&mut self, value: f32) {
7197        // SAFETY: plain scalar write through a live handle.
7198        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_friction(self.raw.as_ptr(), value) }
7199    }
7200
7201    /// Bounce coefficient
7202    pub fn bounce(&self) -> f32 {
7203        // SAFETY: plain scalar read through a live handle.
7204        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_bounce(self.raw.as_ptr()) }
7205    }
7206
7207    pub fn set_bounce(&mut self, value: f32) {
7208        // SAFETY: plain scalar write through a live handle.
7209        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_bounce(self.raw.as_ptr(), value) }
7210    }
7211
7212    /// LOD reduction level
7213    pub fn lod_reduce(&self) -> u32 {
7214        // SAFETY: plain scalar read through a live handle.
7215        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_lodReduce(self.raw.as_ptr()) }
7216    }
7217
7218    pub fn set_lod_reduce(&mut self, value: u32) {
7219        // SAFETY: plain scalar write through a live handle.
7220        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_lodReduce(self.raw.as_ptr(), value) }
7221    }
7222
7223    /// LOD cut-off level
7224    pub fn lod_cut(&self) -> u32 {
7225        // SAFETY: plain scalar read through a live handle.
7226        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_lodCut(self.raw.as_ptr()) }
7227    }
7228
7229    pub fn set_lod_cut(&mut self, value: u32) {
7230        // SAFETY: plain scalar write through a live handle.
7231        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_lodCut(self.raw.as_ptr(), value) }
7232    }
7233
7234    /// Yaw variation type
7235    pub fn yaw_type(&self) -> u32 {
7236        // SAFETY: plain scalar read through a live handle.
7237        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_yawType(self.raw.as_ptr()) }
7238    }
7239
7240    pub fn set_yaw_type(&mut self, value: u32) {
7241        // SAFETY: plain scalar write through a live handle.
7242        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_yawType(self.raw.as_ptr(), value) }
7243    }
7244
7245    /// Yaw variation amplitude
7246    /// Borrows the field in place — no copy, no allocation.
7247    pub fn yaw_amplitude(&self) -> crate::support::Ref<'_, AnimRefF32> {
7248        // SAFETY: an interior pointer into `self`, valid for this
7249        // borrow and never freed by the `Ref`.
7250        unsafe {
7251            crate::support::Ref::new(AnimRefF32 {
7252                raw: core::ptr::NonNull::new_unchecked(
7253                    ffi::whiteout_m3_M3RibbonEmitter_get_yawAmplitude(self.raw.as_ptr()),
7254                ),
7255            })
7256        }
7257    }
7258
7259    pub fn yaw_amplitude_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7260        // SAFETY: as above; `&mut self` guarantees exclusivity.
7261        unsafe {
7262            crate::support::RefMut::new(AnimRefF32 {
7263                raw: core::ptr::NonNull::new_unchecked(
7264                    ffi::whiteout_m3_M3RibbonEmitter_get_yawAmplitude(self.raw.as_ptr()),
7265                ),
7266            })
7267        }
7268    }
7269
7270    /// Yaw variation frequency
7271    /// Borrows the field in place — no copy, no allocation.
7272    pub fn yaw_frequency(&self) -> crate::support::Ref<'_, AnimRefF32> {
7273        // SAFETY: an interior pointer into `self`, valid for this
7274        // borrow and never freed by the `Ref`.
7275        unsafe {
7276            crate::support::Ref::new(AnimRefF32 {
7277                raw: core::ptr::NonNull::new_unchecked(
7278                    ffi::whiteout_m3_M3RibbonEmitter_get_yawFrequency(self.raw.as_ptr()),
7279                ),
7280            })
7281        }
7282    }
7283
7284    pub fn yaw_frequency_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7285        // SAFETY: as above; `&mut self` guarantees exclusivity.
7286        unsafe {
7287            crate::support::RefMut::new(AnimRefF32 {
7288                raw: core::ptr::NonNull::new_unchecked(
7289                    ffi::whiteout_m3_M3RibbonEmitter_get_yawFrequency(self.raw.as_ptr()),
7290                ),
7291            })
7292        }
7293    }
7294
7295    /// Pitch variation type
7296    pub fn pitch_type(&self) -> u32 {
7297        // SAFETY: plain scalar read through a live handle.
7298        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_pitchType(self.raw.as_ptr()) }
7299    }
7300
7301    pub fn set_pitch_type(&mut self, value: u32) {
7302        // SAFETY: plain scalar write through a live handle.
7303        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_pitchType(self.raw.as_ptr(), value) }
7304    }
7305
7306    /// Pitch variation amplitude
7307    /// Borrows the field in place — no copy, no allocation.
7308    pub fn pitch_amplitude(&self) -> crate::support::Ref<'_, AnimRefF32> {
7309        // SAFETY: an interior pointer into `self`, valid for this
7310        // borrow and never freed by the `Ref`.
7311        unsafe {
7312            crate::support::Ref::new(AnimRefF32 {
7313                raw: core::ptr::NonNull::new_unchecked(
7314                    ffi::whiteout_m3_M3RibbonEmitter_get_pitchAmplitude(self.raw.as_ptr()),
7315                ),
7316            })
7317        }
7318    }
7319
7320    pub fn pitch_amplitude_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7321        // SAFETY: as above; `&mut self` guarantees exclusivity.
7322        unsafe {
7323            crate::support::RefMut::new(AnimRefF32 {
7324                raw: core::ptr::NonNull::new_unchecked(
7325                    ffi::whiteout_m3_M3RibbonEmitter_get_pitchAmplitude(self.raw.as_ptr()),
7326                ),
7327            })
7328        }
7329    }
7330
7331    /// Pitch variation frequency
7332    /// Borrows the field in place — no copy, no allocation.
7333    pub fn pitch_frequency(&self) -> crate::support::Ref<'_, AnimRefF32> {
7334        // SAFETY: an interior pointer into `self`, valid for this
7335        // borrow and never freed by the `Ref`.
7336        unsafe {
7337            crate::support::Ref::new(AnimRefF32 {
7338                raw: core::ptr::NonNull::new_unchecked(
7339                    ffi::whiteout_m3_M3RibbonEmitter_get_pitchFrequency(self.raw.as_ptr()),
7340                ),
7341            })
7342        }
7343    }
7344
7345    pub fn pitch_frequency_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7346        // SAFETY: as above; `&mut self` guarantees exclusivity.
7347        unsafe {
7348            crate::support::RefMut::new(AnimRefF32 {
7349                raw: core::ptr::NonNull::new_unchecked(
7350                    ffi::whiteout_m3_M3RibbonEmitter_get_pitchFrequency(self.raw.as_ptr()),
7351                ),
7352            })
7353        }
7354    }
7355
7356    /// Speed variation type
7357    pub fn speed_type(&self) -> u32 {
7358        // SAFETY: plain scalar read through a live handle.
7359        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_speedType(self.raw.as_ptr()) }
7360    }
7361
7362    pub fn set_speed_type(&mut self, value: u32) {
7363        // SAFETY: plain scalar write through a live handle.
7364        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_speedType(self.raw.as_ptr(), value) }
7365    }
7366
7367    /// Speed variation amplitude
7368    /// Borrows the field in place — no copy, no allocation.
7369    pub fn speed_amplitude(&self) -> crate::support::Ref<'_, AnimRefF32> {
7370        // SAFETY: an interior pointer into `self`, valid for this
7371        // borrow and never freed by the `Ref`.
7372        unsafe {
7373            crate::support::Ref::new(AnimRefF32 {
7374                raw: core::ptr::NonNull::new_unchecked(
7375                    ffi::whiteout_m3_M3RibbonEmitter_get_speedAmplitude(self.raw.as_ptr()),
7376                ),
7377            })
7378        }
7379    }
7380
7381    pub fn speed_amplitude_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7382        // SAFETY: as above; `&mut self` guarantees exclusivity.
7383        unsafe {
7384            crate::support::RefMut::new(AnimRefF32 {
7385                raw: core::ptr::NonNull::new_unchecked(
7386                    ffi::whiteout_m3_M3RibbonEmitter_get_speedAmplitude(self.raw.as_ptr()),
7387                ),
7388            })
7389        }
7390    }
7391
7392    /// Speed variation frequency
7393    /// Borrows the field in place — no copy, no allocation.
7394    pub fn speed_frequency(&self) -> crate::support::Ref<'_, AnimRefF32> {
7395        // SAFETY: an interior pointer into `self`, valid for this
7396        // borrow and never freed by the `Ref`.
7397        unsafe {
7398            crate::support::Ref::new(AnimRefF32 {
7399                raw: core::ptr::NonNull::new_unchecked(
7400                    ffi::whiteout_m3_M3RibbonEmitter_get_speedFrequency(self.raw.as_ptr()),
7401                ),
7402            })
7403        }
7404    }
7405
7406    pub fn speed_frequency_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7407        // SAFETY: as above; `&mut self` guarantees exclusivity.
7408        unsafe {
7409            crate::support::RefMut::new(AnimRefF32 {
7410                raw: core::ptr::NonNull::new_unchecked(
7411                    ffi::whiteout_m3_M3RibbonEmitter_get_speedFrequency(self.raw.as_ptr()),
7412                ),
7413            })
7414        }
7415    }
7416
7417    /// Size variation type
7418    pub fn size_type(&self) -> u32 {
7419        // SAFETY: plain scalar read through a live handle.
7420        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_sizeType(self.raw.as_ptr()) }
7421    }
7422
7423    pub fn set_size_type(&mut self, value: u32) {
7424        // SAFETY: plain scalar write through a live handle.
7425        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_sizeType(self.raw.as_ptr(), value) }
7426    }
7427
7428    /// Size variation amplitude
7429    /// Borrows the field in place — no copy, no allocation.
7430    pub fn size_amplitude(&self) -> crate::support::Ref<'_, AnimRefF32> {
7431        // SAFETY: an interior pointer into `self`, valid for this
7432        // borrow and never freed by the `Ref`.
7433        unsafe {
7434            crate::support::Ref::new(AnimRefF32 {
7435                raw: core::ptr::NonNull::new_unchecked(
7436                    ffi::whiteout_m3_M3RibbonEmitter_get_sizeAmplitude(self.raw.as_ptr()),
7437                ),
7438            })
7439        }
7440    }
7441
7442    pub fn size_amplitude_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7443        // SAFETY: as above; `&mut self` guarantees exclusivity.
7444        unsafe {
7445            crate::support::RefMut::new(AnimRefF32 {
7446                raw: core::ptr::NonNull::new_unchecked(
7447                    ffi::whiteout_m3_M3RibbonEmitter_get_sizeAmplitude(self.raw.as_ptr()),
7448                ),
7449            })
7450        }
7451    }
7452
7453    /// Size variation frequency
7454    /// Borrows the field in place — no copy, no allocation.
7455    pub fn size_frequency(&self) -> crate::support::Ref<'_, AnimRefF32> {
7456        // SAFETY: an interior pointer into `self`, valid for this
7457        // borrow and never freed by the `Ref`.
7458        unsafe {
7459            crate::support::Ref::new(AnimRefF32 {
7460                raw: core::ptr::NonNull::new_unchecked(
7461                    ffi::whiteout_m3_M3RibbonEmitter_get_sizeFrequency(self.raw.as_ptr()),
7462                ),
7463            })
7464        }
7465    }
7466
7467    pub fn size_frequency_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7468        // SAFETY: as above; `&mut self` guarantees exclusivity.
7469        unsafe {
7470            crate::support::RefMut::new(AnimRefF32 {
7471                raw: core::ptr::NonNull::new_unchecked(
7472                    ffi::whiteout_m3_M3RibbonEmitter_get_sizeFrequency(self.raw.as_ptr()),
7473                ),
7474            })
7475        }
7476    }
7477
7478    /// Alpha variation type
7479    pub fn alpha_type(&self) -> u32 {
7480        // SAFETY: plain scalar read through a live handle.
7481        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_alphaType(self.raw.as_ptr()) }
7482    }
7483
7484    pub fn set_alpha_type(&mut self, value: u32) {
7485        // SAFETY: plain scalar write through a live handle.
7486        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_alphaType(self.raw.as_ptr(), value) }
7487    }
7488
7489    /// Alpha variation amplitude
7490    /// Borrows the field in place — no copy, no allocation.
7491    pub fn alpha_amplitude(&self) -> crate::support::Ref<'_, AnimRefF32> {
7492        // SAFETY: an interior pointer into `self`, valid for this
7493        // borrow and never freed by the `Ref`.
7494        unsafe {
7495            crate::support::Ref::new(AnimRefF32 {
7496                raw: core::ptr::NonNull::new_unchecked(
7497                    ffi::whiteout_m3_M3RibbonEmitter_get_alphaAmplitude(self.raw.as_ptr()),
7498                ),
7499            })
7500        }
7501    }
7502
7503    pub fn alpha_amplitude_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7504        // SAFETY: as above; `&mut self` guarantees exclusivity.
7505        unsafe {
7506            crate::support::RefMut::new(AnimRefF32 {
7507                raw: core::ptr::NonNull::new_unchecked(
7508                    ffi::whiteout_m3_M3RibbonEmitter_get_alphaAmplitude(self.raw.as_ptr()),
7509                ),
7510            })
7511        }
7512    }
7513
7514    /// Alpha variation frequency
7515    /// Borrows the field in place — no copy, no allocation.
7516    pub fn alpha_frequency(&self) -> crate::support::Ref<'_, AnimRefF32> {
7517        // SAFETY: an interior pointer into `self`, valid for this
7518        // borrow and never freed by the `Ref`.
7519        unsafe {
7520            crate::support::Ref::new(AnimRefF32 {
7521                raw: core::ptr::NonNull::new_unchecked(
7522                    ffi::whiteout_m3_M3RibbonEmitter_get_alphaFrequency(self.raw.as_ptr()),
7523                ),
7524            })
7525        }
7526    }
7527
7528    pub fn alpha_frequency_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7529        // SAFETY: as above; `&mut self` guarantees exclusivity.
7530        unsafe {
7531            crate::support::RefMut::new(AnimRefF32 {
7532                raw: core::ptr::NonNull::new_unchecked(
7533                    ffi::whiteout_m3_M3RibbonEmitter_get_alphaFrequency(self.raw.as_ptr()),
7534                ),
7535            })
7536        }
7537    }
7538
7539    /// Animated parent velocity influence
7540    /// Borrows the field in place — no copy, no allocation.
7541    pub fn particle_velocity(&self) -> crate::support::Ref<'_, AnimRefF32> {
7542        // SAFETY: an interior pointer into `self`, valid for this
7543        // borrow and never freed by the `Ref`.
7544        unsafe {
7545            crate::support::Ref::new(AnimRefF32 {
7546                raw: core::ptr::NonNull::new_unchecked(
7547                    ffi::whiteout_m3_M3RibbonEmitter_get_particleVelocity(self.raw.as_ptr()),
7548                ),
7549            })
7550        }
7551    }
7552
7553    pub fn particle_velocity_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7554        // SAFETY: as above; `&mut self` guarantees exclusivity.
7555        unsafe {
7556            crate::support::RefMut::new(AnimRefF32 {
7557                raw: core::ptr::NonNull::new_unchecked(
7558                    ffi::whiteout_m3_M3RibbonEmitter_get_particleVelocity(self.raw.as_ptr()),
7559                ),
7560            })
7561        }
7562    }
7563
7564    /// Animated overlay effect
7565    /// Borrows the field in place — no copy, no allocation.
7566    pub fn overlay(&self) -> crate::support::Ref<'_, AnimRefF32> {
7567        // SAFETY: an interior pointer into `self`, valid for this
7568        // borrow and never freed by the `Ref`.
7569        unsafe {
7570            crate::support::Ref::new(AnimRefF32 {
7571                raw: core::ptr::NonNull::new_unchecked(
7572                    ffi::whiteout_m3_M3RibbonEmitter_get_overlay(self.raw.as_ptr()),
7573                ),
7574            })
7575        }
7576    }
7577
7578    pub fn overlay_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7579        // SAFETY: as above; `&mut self` guarantees exclusivity.
7580        unsafe {
7581            crate::support::RefMut::new(AnimRefF32 {
7582                raw: core::ptr::NonNull::new_unchecked(
7583                    ffi::whiteout_m3_M3RibbonEmitter_get_overlay(self.raw.as_ptr()),
7584                ),
7585            })
7586        }
7587    }
7588}
7589
7590impl Default for RibbonEmitter {
7591    fn default() -> Self {
7592        Self::new()
7593    }
7594}
7595
7596/// PROJ — Projector / decal (v0–v5, 388 bytes)
7597///
7598/// Projects a material onto scene geometry with animated offset, orientation, field of view, aspect ratio, clipping planes, alpha lifecycle, and attenuation distance.
7599pub struct Projector {
7600    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3Projector>,
7601}
7602
7603impl Drop for Projector {
7604    fn drop(&mut self) {
7605        // SAFETY: `raw` came from a native constructor and Drop runs once.
7606        unsafe { ffi::whiteout_m3_M3Projector_delete(self.raw.as_ptr()) }
7607    }
7608}
7609
7610impl Projector {
7611    /// # Safety
7612    /// `raw` must be a live handle this value takes ownership of.
7613    #[allow(dead_code)] // used by whichever methods return this type
7614    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3Projector) -> Option<Self> {
7615        core::ptr::NonNull::new(raw).map(|raw| Projector { raw })
7616    }
7617}
7618
7619// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
7620// is deliberately NOT implemented — the C++ types make no documented
7621// guarantee about concurrent use, and claiming one we haven't verified
7622// would be unsound. See `@bind thread_safe` in the plan.
7623unsafe impl Send for Projector {}
7624
7625impl core::fmt::Debug for Projector {
7626    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
7627        f.debug_struct("Projector").finish_non_exhaustive()
7628    }
7629}
7630
7631impl Projector {
7632    /// # Panics
7633    /// Panics if the native allocation fails.
7634    pub fn new() -> Self {
7635        // SAFETY: the native constructor returns a live handle; a null here
7636        // means the library is unusable.
7637        unsafe {
7638            let raw = ffi::whiteout_m3_M3Projector_new();
7639            Self::from_raw(raw).expect("native Projector allocation failed")
7640        }
7641    }
7642
7643    /// Projection type (ortho/perspective)
7644    pub fn projection_type(&self) -> ProjectionType {
7645        // SAFETY: scalar read; the discriminant is validated below.
7646        unsafe { ffi::whiteout_m3_M3Projector_get_projectionType(self.raw.as_ptr()) }
7647            .try_into()
7648            .expect("unknown enum discriminant from the native library")
7649    }
7650
7651    pub fn set_projection_type(&mut self, value: ProjectionType) {
7652        // SAFETY: scalar write through a live handle.
7653        unsafe { ffi::whiteout_m3_M3Projector_set_projectionType(self.raw.as_ptr(), value as i32) }
7654    }
7655
7656    /// Index into BONE array
7657    pub fn bone(&self) -> u32 {
7658        // SAFETY: plain scalar read through a live handle.
7659        unsafe { ffi::whiteout_m3_M3Projector_get_bone(self.raw.as_ptr()) }
7660    }
7661
7662    pub fn set_bone(&mut self, value: u32) {
7663        // SAFETY: plain scalar write through a live handle.
7664        unsafe { ffi::whiteout_m3_M3Projector_set_bone(self.raw.as_ptr(), value) }
7665    }
7666
7667    /// Index into MATM material map
7668    pub fn material_reference_index(&self) -> u32 {
7669        // SAFETY: plain scalar read through a live handle.
7670        unsafe { ffi::whiteout_m3_M3Projector_get_materialReferenceIndex(self.raw.as_ptr()) }
7671    }
7672
7673    pub fn set_material_reference_index(&mut self, value: u32) {
7674        // SAFETY: plain scalar write through a live handle.
7675        unsafe { ffi::whiteout_m3_M3Projector_set_materialReferenceIndex(self.raw.as_ptr(), value) }
7676    }
7677
7678    /// Animated position offset
7679    /// Borrows the field in place — no copy, no allocation.
7680    pub fn offset(&self) -> crate::support::Ref<'_, AnimRefVector3f> {
7681        // SAFETY: an interior pointer into `self`, valid for this
7682        // borrow and never freed by the `Ref`.
7683        unsafe {
7684            crate::support::Ref::new(AnimRefVector3f {
7685                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Projector_get_offset(
7686                    self.raw.as_ptr(),
7687                )),
7688            })
7689        }
7690    }
7691
7692    pub fn offset_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector3f> {
7693        // SAFETY: as above; `&mut self` guarantees exclusivity.
7694        unsafe {
7695            crate::support::RefMut::new(AnimRefVector3f {
7696                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Projector_get_offset(
7697                    self.raw.as_ptr(),
7698                )),
7699            })
7700        }
7701    }
7702
7703    /// Animated pitch angle
7704    /// Borrows the field in place — no copy, no allocation.
7705    pub fn pitch(&self) -> crate::support::Ref<'_, AnimRefF32> {
7706        // SAFETY: an interior pointer into `self`, valid for this
7707        // borrow and never freed by the `Ref`.
7708        unsafe {
7709            crate::support::Ref::new(AnimRefF32 {
7710                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Projector_get_pitch(
7711                    self.raw.as_ptr(),
7712                )),
7713            })
7714        }
7715    }
7716
7717    pub fn pitch_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7718        // SAFETY: as above; `&mut self` guarantees exclusivity.
7719        unsafe {
7720            crate::support::RefMut::new(AnimRefF32 {
7721                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Projector_get_pitch(
7722                    self.raw.as_ptr(),
7723                )),
7724            })
7725        }
7726    }
7727
7728    /// Animated yaw angle
7729    /// Borrows the field in place — no copy, no allocation.
7730    pub fn yaw(&self) -> crate::support::Ref<'_, AnimRefF32> {
7731        // SAFETY: an interior pointer into `self`, valid for this
7732        // borrow and never freed by the `Ref`.
7733        unsafe {
7734            crate::support::Ref::new(AnimRefF32 {
7735                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Projector_get_yaw(
7736                    self.raw.as_ptr(),
7737                )),
7738            })
7739        }
7740    }
7741
7742    pub fn yaw_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7743        // SAFETY: as above; `&mut self` guarantees exclusivity.
7744        unsafe {
7745            crate::support::RefMut::new(AnimRefF32 {
7746                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Projector_get_yaw(
7747                    self.raw.as_ptr(),
7748                )),
7749            })
7750        }
7751    }
7752
7753    /// Animated roll angle
7754    /// Borrows the field in place — no copy, no allocation.
7755    pub fn roll(&self) -> crate::support::Ref<'_, AnimRefF32> {
7756        // SAFETY: an interior pointer into `self`, valid for this
7757        // borrow and never freed by the `Ref`.
7758        unsafe {
7759            crate::support::Ref::new(AnimRefF32 {
7760                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Projector_get_roll(
7761                    self.raw.as_ptr(),
7762                )),
7763            })
7764        }
7765    }
7766
7767    pub fn roll_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7768        // SAFETY: as above; `&mut self` guarantees exclusivity.
7769        unsafe {
7770            crate::support::RefMut::new(AnimRefF32 {
7771                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Projector_get_roll(
7772                    self.raw.as_ptr(),
7773                )),
7774            })
7775        }
7776    }
7777
7778    /// Animated field of view
7779    /// Borrows the field in place — no copy, no allocation.
7780    pub fn field_of_view(&self) -> crate::support::Ref<'_, AnimRefF32> {
7781        // SAFETY: an interior pointer into `self`, valid for this
7782        // borrow and never freed by the `Ref`.
7783        unsafe {
7784            crate::support::Ref::new(AnimRefF32 {
7785                raw: core::ptr::NonNull::new_unchecked(
7786                    ffi::whiteout_m3_M3Projector_get_fieldOfView(self.raw.as_ptr()),
7787                ),
7788            })
7789        }
7790    }
7791
7792    pub fn field_of_view_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7793        // SAFETY: as above; `&mut self` guarantees exclusivity.
7794        unsafe {
7795            crate::support::RefMut::new(AnimRefF32 {
7796                raw: core::ptr::NonNull::new_unchecked(
7797                    ffi::whiteout_m3_M3Projector_get_fieldOfView(self.raw.as_ptr()),
7798                ),
7799            })
7800        }
7801    }
7802
7803    /// Animated aspect ratio
7804    /// Borrows the field in place — no copy, no allocation.
7805    pub fn aspect_ratio(&self) -> crate::support::Ref<'_, AnimRefF32> {
7806        // SAFETY: an interior pointer into `self`, valid for this
7807        // borrow and never freed by the `Ref`.
7808        unsafe {
7809            crate::support::Ref::new(AnimRefF32 {
7810                raw: core::ptr::NonNull::new_unchecked(
7811                    ffi::whiteout_m3_M3Projector_get_aspectRatio(self.raw.as_ptr()),
7812                ),
7813            })
7814        }
7815    }
7816
7817    pub fn aspect_ratio_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7818        // SAFETY: as above; `&mut self` guarantees exclusivity.
7819        unsafe {
7820            crate::support::RefMut::new(AnimRefF32 {
7821                raw: core::ptr::NonNull::new_unchecked(
7822                    ffi::whiteout_m3_M3Projector_get_aspectRatio(self.raw.as_ptr()),
7823                ),
7824            })
7825        }
7826    }
7827
7828    /// Animated near clip plane
7829    /// Borrows the field in place — no copy, no allocation.
7830    pub fn near(&self) -> crate::support::Ref<'_, AnimRefF32> {
7831        // SAFETY: an interior pointer into `self`, valid for this
7832        // borrow and never freed by the `Ref`.
7833        unsafe {
7834            crate::support::Ref::new(AnimRefF32 {
7835                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Projector_get_near(
7836                    self.raw.as_ptr(),
7837                )),
7838            })
7839        }
7840    }
7841
7842    pub fn near_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7843        // SAFETY: as above; `&mut self` guarantees exclusivity.
7844        unsafe {
7845            crate::support::RefMut::new(AnimRefF32 {
7846                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Projector_get_near(
7847                    self.raw.as_ptr(),
7848                )),
7849            })
7850        }
7851    }
7852
7853    /// Animated far clip plane
7854    /// Borrows the field in place — no copy, no allocation.
7855    pub fn far(&self) -> crate::support::Ref<'_, AnimRefF32> {
7856        // SAFETY: an interior pointer into `self`, valid for this
7857        // borrow and never freed by the `Ref`.
7858        unsafe {
7859            crate::support::Ref::new(AnimRefF32 {
7860                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Projector_get_far(
7861                    self.raw.as_ptr(),
7862                )),
7863            })
7864        }
7865    }
7866
7867    pub fn far_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7868        // SAFETY: as above; `&mut self` guarantees exclusivity.
7869        unsafe {
7870            crate::support::RefMut::new(AnimRefF32 {
7871                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Projector_get_far(
7872                    self.raw.as_ptr(),
7873                )),
7874            })
7875        }
7876    }
7877
7878    /// Animated box Z bottom offset
7879    /// Borrows the field in place — no copy, no allocation.
7880    pub fn box_offset_z_bottom(&self) -> crate::support::Ref<'_, AnimRefF32> {
7881        // SAFETY: an interior pointer into `self`, valid for this
7882        // borrow and never freed by the `Ref`.
7883        unsafe {
7884            crate::support::Ref::new(AnimRefF32 {
7885                raw: core::ptr::NonNull::new_unchecked(
7886                    ffi::whiteout_m3_M3Projector_get_boxOffsetZBottom(self.raw.as_ptr()),
7887                ),
7888            })
7889        }
7890    }
7891
7892    pub fn box_offset_z_bottom_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7893        // SAFETY: as above; `&mut self` guarantees exclusivity.
7894        unsafe {
7895            crate::support::RefMut::new(AnimRefF32 {
7896                raw: core::ptr::NonNull::new_unchecked(
7897                    ffi::whiteout_m3_M3Projector_get_boxOffsetZBottom(self.raw.as_ptr()),
7898                ),
7899            })
7900        }
7901    }
7902
7903    /// Animated box Z top offset
7904    /// Borrows the field in place — no copy, no allocation.
7905    pub fn box_offset_z_top(&self) -> crate::support::Ref<'_, AnimRefF32> {
7906        // SAFETY: an interior pointer into `self`, valid for this
7907        // borrow and never freed by the `Ref`.
7908        unsafe {
7909            crate::support::Ref::new(AnimRefF32 {
7910                raw: core::ptr::NonNull::new_unchecked(
7911                    ffi::whiteout_m3_M3Projector_get_boxOffsetZTop(self.raw.as_ptr()),
7912                ),
7913            })
7914        }
7915    }
7916
7917    pub fn box_offset_z_top_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7918        // SAFETY: as above; `&mut self` guarantees exclusivity.
7919        unsafe {
7920            crate::support::RefMut::new(AnimRefF32 {
7921                raw: core::ptr::NonNull::new_unchecked(
7922                    ffi::whiteout_m3_M3Projector_get_boxOffsetZTop(self.raw.as_ptr()),
7923                ),
7924            })
7925        }
7926    }
7927
7928    /// Animated box X left offset
7929    /// Borrows the field in place — no copy, no allocation.
7930    pub fn box_offset_x_left(&self) -> crate::support::Ref<'_, AnimRefF32> {
7931        // SAFETY: an interior pointer into `self`, valid for this
7932        // borrow and never freed by the `Ref`.
7933        unsafe {
7934            crate::support::Ref::new(AnimRefF32 {
7935                raw: core::ptr::NonNull::new_unchecked(
7936                    ffi::whiteout_m3_M3Projector_get_boxOffsetXLeft(self.raw.as_ptr()),
7937                ),
7938            })
7939        }
7940    }
7941
7942    pub fn box_offset_x_left_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7943        // SAFETY: as above; `&mut self` guarantees exclusivity.
7944        unsafe {
7945            crate::support::RefMut::new(AnimRefF32 {
7946                raw: core::ptr::NonNull::new_unchecked(
7947                    ffi::whiteout_m3_M3Projector_get_boxOffsetXLeft(self.raw.as_ptr()),
7948                ),
7949            })
7950        }
7951    }
7952
7953    /// Animated box X right offset
7954    /// Borrows the field in place — no copy, no allocation.
7955    pub fn box_offset_x_right(&self) -> crate::support::Ref<'_, AnimRefF32> {
7956        // SAFETY: an interior pointer into `self`, valid for this
7957        // borrow and never freed by the `Ref`.
7958        unsafe {
7959            crate::support::Ref::new(AnimRefF32 {
7960                raw: core::ptr::NonNull::new_unchecked(
7961                    ffi::whiteout_m3_M3Projector_get_boxOffsetXRight(self.raw.as_ptr()),
7962                ),
7963            })
7964        }
7965    }
7966
7967    pub fn box_offset_x_right_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7968        // SAFETY: as above; `&mut self` guarantees exclusivity.
7969        unsafe {
7970            crate::support::RefMut::new(AnimRefF32 {
7971                raw: core::ptr::NonNull::new_unchecked(
7972                    ffi::whiteout_m3_M3Projector_get_boxOffsetXRight(self.raw.as_ptr()),
7973                ),
7974            })
7975        }
7976    }
7977
7978    /// Animated box Y front offset
7979    /// Borrows the field in place — no copy, no allocation.
7980    pub fn box_offset_y_front(&self) -> crate::support::Ref<'_, AnimRefF32> {
7981        // SAFETY: an interior pointer into `self`, valid for this
7982        // borrow and never freed by the `Ref`.
7983        unsafe {
7984            crate::support::Ref::new(AnimRefF32 {
7985                raw: core::ptr::NonNull::new_unchecked(
7986                    ffi::whiteout_m3_M3Projector_get_boxOffsetYFront(self.raw.as_ptr()),
7987                ),
7988            })
7989        }
7990    }
7991
7992    pub fn box_offset_y_front_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7993        // SAFETY: as above; `&mut self` guarantees exclusivity.
7994        unsafe {
7995            crate::support::RefMut::new(AnimRefF32 {
7996                raw: core::ptr::NonNull::new_unchecked(
7997                    ffi::whiteout_m3_M3Projector_get_boxOffsetYFront(self.raw.as_ptr()),
7998                ),
7999            })
8000        }
8001    }
8002
8003    /// Animated box Y back offset
8004    /// Borrows the field in place — no copy, no allocation.
8005    pub fn box_offset_y_back(&self) -> crate::support::Ref<'_, AnimRefF32> {
8006        // SAFETY: an interior pointer into `self`, valid for this
8007        // borrow and never freed by the `Ref`.
8008        unsafe {
8009            crate::support::Ref::new(AnimRefF32 {
8010                raw: core::ptr::NonNull::new_unchecked(
8011                    ffi::whiteout_m3_M3Projector_get_boxOffsetYBack(self.raw.as_ptr()),
8012                ),
8013            })
8014        }
8015    }
8016
8017    pub fn box_offset_y_back_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
8018        // SAFETY: as above; `&mut self` guarantees exclusivity.
8019        unsafe {
8020            crate::support::RefMut::new(AnimRefF32 {
8021                raw: core::ptr::NonNull::new_unchecked(
8022                    ffi::whiteout_m3_M3Projector_get_boxOffsetYBack(self.raw.as_ptr()),
8023                ),
8024            })
8025        }
8026    }
8027
8028    /// Projection falloff distance
8029    pub fn falloff(&self) -> f32 {
8030        // SAFETY: plain scalar read through a live handle.
8031        unsafe { ffi::whiteout_m3_M3Projector_get_falloff(self.raw.as_ptr()) }
8032    }
8033
8034    pub fn set_falloff(&mut self, value: f32) {
8035        // SAFETY: plain scalar write through a live handle.
8036        unsafe { ffi::whiteout_m3_M3Projector_set_falloff(self.raw.as_ptr(), value) }
8037    }
8038
8039    /// Alpha at creation
8040    pub fn alpha_init(&self) -> f32 {
8041        // SAFETY: plain scalar read through a live handle.
8042        unsafe { ffi::whiteout_m3_M3Projector_get_alphaInit(self.raw.as_ptr()) }
8043    }
8044
8045    pub fn set_alpha_init(&mut self, value: f32) {
8046        // SAFETY: plain scalar write through a live handle.
8047        unsafe { ffi::whiteout_m3_M3Projector_set_alphaInit(self.raw.as_ptr(), value) }
8048    }
8049
8050    /// Alpha at midpoint
8051    pub fn alpha_mid(&self) -> f32 {
8052        // SAFETY: plain scalar read through a live handle.
8053        unsafe { ffi::whiteout_m3_M3Projector_get_alphaMid(self.raw.as_ptr()) }
8054    }
8055
8056    pub fn set_alpha_mid(&mut self, value: f32) {
8057        // SAFETY: plain scalar write through a live handle.
8058        unsafe { ffi::whiteout_m3_M3Projector_set_alphaMid(self.raw.as_ptr(), value) }
8059    }
8060
8061    /// Alpha at end
8062    pub fn alpha_end(&self) -> f32 {
8063        // SAFETY: plain scalar read through a live handle.
8064        unsafe { ffi::whiteout_m3_M3Projector_get_alphaEnd(self.raw.as_ptr()) }
8065    }
8066
8067    pub fn set_alpha_end(&mut self, value: f32) {
8068        // SAFETY: plain scalar write through a live handle.
8069        unsafe { ffi::whiteout_m3_M3Projector_set_alphaEnd(self.raw.as_ptr(), value) }
8070    }
8071
8072    /// Attack phase duration
8073    pub fn lifetime_attack(&self) -> f32 {
8074        // SAFETY: plain scalar read through a live handle.
8075        unsafe { ffi::whiteout_m3_M3Projector_get_lifetimeAttack(self.raw.as_ptr()) }
8076    }
8077
8078    pub fn set_lifetime_attack(&mut self, value: f32) {
8079        // SAFETY: plain scalar write through a live handle.
8080        unsafe { ffi::whiteout_m3_M3Projector_set_lifetimeAttack(self.raw.as_ptr(), value) }
8081    }
8082
8083    /// Attack target time
8084    pub fn lifetime_attack_to(&self) -> f32 {
8085        // SAFETY: plain scalar read through a live handle.
8086        unsafe { ffi::whiteout_m3_M3Projector_get_lifetimeAttackTo(self.raw.as_ptr()) }
8087    }
8088
8089    pub fn set_lifetime_attack_to(&mut self, value: f32) {
8090        // SAFETY: plain scalar write through a live handle.
8091        unsafe { ffi::whiteout_m3_M3Projector_set_lifetimeAttackTo(self.raw.as_ptr(), value) }
8092    }
8093
8094    /// Hold phase duration
8095    pub fn lifetime_hold(&self) -> f32 {
8096        // SAFETY: plain scalar read through a live handle.
8097        unsafe { ffi::whiteout_m3_M3Projector_get_lifetimeHold(self.raw.as_ptr()) }
8098    }
8099
8100    pub fn set_lifetime_hold(&mut self, value: f32) {
8101        // SAFETY: plain scalar write through a live handle.
8102        unsafe { ffi::whiteout_m3_M3Projector_set_lifetimeHold(self.raw.as_ptr(), value) }
8103    }
8104
8105    /// Hold target time
8106    pub fn lifetime_hold_to(&self) -> f32 {
8107        // SAFETY: plain scalar read through a live handle.
8108        unsafe { ffi::whiteout_m3_M3Projector_get_lifetimeHoldTo(self.raw.as_ptr()) }
8109    }
8110
8111    pub fn set_lifetime_hold_to(&mut self, value: f32) {
8112        // SAFETY: plain scalar write through a live handle.
8113        unsafe { ffi::whiteout_m3_M3Projector_set_lifetimeHoldTo(self.raw.as_ptr(), value) }
8114    }
8115
8116    /// Decay phase duration
8117    pub fn lifetime_decay(&self) -> f32 {
8118        // SAFETY: plain scalar read through a live handle.
8119        unsafe { ffi::whiteout_m3_M3Projector_get_lifetimeDecay(self.raw.as_ptr()) }
8120    }
8121
8122    pub fn set_lifetime_decay(&mut self, value: f32) {
8123        // SAFETY: plain scalar write through a live handle.
8124        unsafe { ffi::whiteout_m3_M3Projector_set_lifetimeDecay(self.raw.as_ptr(), value) }
8125    }
8126
8127    /// Decay target time
8128    pub fn lifetime_decay_to(&self) -> f32 {
8129        // SAFETY: plain scalar read through a live handle.
8130        unsafe { ffi::whiteout_m3_M3Projector_get_lifetimeDecayTo(self.raw.as_ptr()) }
8131    }
8132
8133    pub fn set_lifetime_decay_to(&mut self, value: f32) {
8134        // SAFETY: plain scalar write through a live handle.
8135        unsafe { ffi::whiteout_m3_M3Projector_set_lifetimeDecayTo(self.raw.as_ptr(), value) }
8136    }
8137
8138    /// Distance-based attenuation
8139    pub fn attenuation_distance(&self) -> f32 {
8140        // SAFETY: plain scalar read through a live handle.
8141        unsafe { ffi::whiteout_m3_M3Projector_get_attenuationDistance(self.raw.as_ptr()) }
8142    }
8143
8144    pub fn set_attenuation_distance(&mut self, value: f32) {
8145        // SAFETY: plain scalar write through a live handle.
8146        unsafe { ffi::whiteout_m3_M3Projector_set_attenuationDistance(self.raw.as_ptr(), value) }
8147    }
8148
8149    /// Animated active state
8150    /// Borrows the field in place — no copy, no allocation.
8151    pub fn active(&self) -> crate::support::Ref<'_, AnimRefU32> {
8152        // SAFETY: an interior pointer into `self`, valid for this
8153        // borrow and never freed by the `Ref`.
8154        unsafe {
8155            crate::support::Ref::new(AnimRefU32 {
8156                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Projector_get_active(
8157                    self.raw.as_ptr(),
8158                )),
8159            })
8160        }
8161    }
8162
8163    pub fn active_mut(&mut self) -> crate::support::RefMut<'_, AnimRefU32> {
8164        // SAFETY: as above; `&mut self` guarantees exclusivity.
8165        unsafe {
8166            crate::support::RefMut::new(AnimRefU32 {
8167                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Projector_get_active(
8168                    self.raw.as_ptr(),
8169                )),
8170            })
8171        }
8172    }
8173
8174    /// Render layer
8175    pub fn layer(&self) -> u32 {
8176        // SAFETY: plain scalar read through a live handle.
8177        unsafe { ffi::whiteout_m3_M3Projector_get_layer(self.raw.as_ptr()) }
8178    }
8179
8180    pub fn set_layer(&mut self, value: u32) {
8181        // SAFETY: plain scalar write through a live handle.
8182        unsafe { ffi::whiteout_m3_M3Projector_set_layer(self.raw.as_ptr(), value) }
8183    }
8184
8185    /// LOD reduction level
8186    pub fn lod_reduce(&self) -> u32 {
8187        // SAFETY: plain scalar read through a live handle.
8188        unsafe { ffi::whiteout_m3_M3Projector_get_lodReduce(self.raw.as_ptr()) }
8189    }
8190
8191    pub fn set_lod_reduce(&mut self, value: u32) {
8192        // SAFETY: plain scalar write through a live handle.
8193        unsafe { ffi::whiteout_m3_M3Projector_set_lodReduce(self.raw.as_ptr(), value) }
8194    }
8195
8196    /// LOD cut-off level
8197    pub fn lod_cut(&self) -> u32 {
8198        // SAFETY: plain scalar read through a live handle.
8199        unsafe { ffi::whiteout_m3_M3Projector_get_lodCut(self.raw.as_ptr()) }
8200    }
8201
8202    pub fn set_lod_cut(&mut self, value: u32) {
8203        // SAFETY: plain scalar write through a live handle.
8204        unsafe { ffi::whiteout_m3_M3Projector_set_lodCut(self.raw.as_ptr(), value) }
8205    }
8206
8207    /// Projector flags
8208    pub fn flags(&self) -> ProjectorFlag {
8209        // SAFETY: scalar read; a flag set accepts any bits.
8210        ProjectorFlag(unsafe { ffi::whiteout_m3_M3Projector_get_flags(self.raw.as_ptr()) })
8211    }
8212
8213    pub fn set_flags(&mut self, value: ProjectorFlag) {
8214        // SAFETY: scalar write through a live handle.
8215        unsafe { ffi::whiteout_m3_M3Projector_set_flags(self.raw.as_ptr(), value.0) }
8216    }
8217}
8218
8219impl Default for Projector {
8220    fn default() -> Self {
8221        Self::new()
8222    }
8223}
8224
8225/// MATM — Material map entry (v0, 8 bytes)
8226///
8227/// Maps a material type enum to an index into the corresponding material array. The MODL root references an array of these; the renderer uses materialType to dispatch to the correct material vector.
8228pub struct MaterialMap {
8229    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3MaterialMap>,
8230}
8231
8232impl Drop for MaterialMap {
8233    fn drop(&mut self) {
8234        // SAFETY: `raw` came from a native constructor and Drop runs once.
8235        unsafe { ffi::whiteout_m3_M3MaterialMap_delete(self.raw.as_ptr()) }
8236    }
8237}
8238
8239impl MaterialMap {
8240    /// # Safety
8241    /// `raw` must be a live handle this value takes ownership of.
8242    #[allow(dead_code)] // used by whichever methods return this type
8243    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3MaterialMap) -> Option<Self> {
8244        core::ptr::NonNull::new(raw).map(|raw| MaterialMap { raw })
8245    }
8246}
8247
8248// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
8249// is deliberately NOT implemented — the C++ types make no documented
8250// guarantee about concurrent use, and claiming one we haven't verified
8251// would be unsound. See `@bind thread_safe` in the plan.
8252unsafe impl Send for MaterialMap {}
8253
8254impl core::fmt::Debug for MaterialMap {
8255    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
8256        f.debug_struct("MaterialMap").finish_non_exhaustive()
8257    }
8258}
8259
8260impl MaterialMap {
8261    /// # Panics
8262    /// Panics if the native allocation fails.
8263    pub fn new() -> Self {
8264        // SAFETY: the native constructor returns a live handle; a null here
8265        // means the library is unusable.
8266        unsafe {
8267            let raw = ffi::whiteout_m3_M3MaterialMap_new();
8268            Self::from_raw(raw).expect("native MaterialMap allocation failed")
8269        }
8270    }
8271
8272    /// Material type (1=standard, 2=displacement, etc.)
8273    pub fn material_type(&self) -> MaterialType {
8274        // SAFETY: scalar read; the discriminant is validated below.
8275        unsafe { ffi::whiteout_m3_M3MaterialMap_get_materialType(self.raw.as_ptr()) }
8276            .try_into()
8277            .expect("unknown enum discriminant from the native library")
8278    }
8279
8280    pub fn set_material_type(&mut self, value: MaterialType) {
8281        // SAFETY: scalar write through a live handle.
8282        unsafe { ffi::whiteout_m3_M3MaterialMap_set_materialType(self.raw.as_ptr(), value as i32) }
8283    }
8284
8285    /// Index into the typed material array
8286    pub fn material_index(&self) -> u32 {
8287        // SAFETY: plain scalar read through a live handle.
8288        unsafe { ffi::whiteout_m3_M3MaterialMap_get_materialIndex(self.raw.as_ptr()) }
8289    }
8290
8291    pub fn set_material_index(&mut self, value: u32) {
8292        // SAFETY: plain scalar write through a live handle.
8293        unsafe { ffi::whiteout_m3_M3MaterialMap_set_materialIndex(self.raw.as_ptr(), value) }
8294    }
8295}
8296
8297impl Default for MaterialMap {
8298    fn default() -> Self {
8299        Self::new()
8300    }
8301}
8302
8303/// LAYR — Texture layer (v0–v26, 352–464 bytes)
8304///
8305/// A single texture binding with animated color tint, UV transforms, flipbook parameters, fresnel settings, and AVI video playback controls. Materials embed multiple optional TextureLayer instances for diffuse, specular, emissive, normal, and other texture slots.
8306pub struct TextureLayer {
8307    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3TextureLayer>,
8308}
8309
8310impl Drop for TextureLayer {
8311    fn drop(&mut self) {
8312        // SAFETY: `raw` came from a native constructor and Drop runs once.
8313        unsafe { ffi::whiteout_m3_M3TextureLayer_delete(self.raw.as_ptr()) }
8314    }
8315}
8316
8317impl TextureLayer {
8318    /// # Safety
8319    /// `raw` must be a live handle this value takes ownership of.
8320    #[allow(dead_code)] // used by whichever methods return this type
8321    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3TextureLayer) -> Option<Self> {
8322        core::ptr::NonNull::new(raw).map(|raw| TextureLayer { raw })
8323    }
8324}
8325
8326// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
8327// is deliberately NOT implemented — the C++ types make no documented
8328// guarantee about concurrent use, and claiming one we haven't verified
8329// would be unsound. See `@bind thread_safe` in the plan.
8330unsafe impl Send for TextureLayer {}
8331
8332impl core::fmt::Debug for TextureLayer {
8333    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
8334        f.debug_struct("TextureLayer").finish_non_exhaustive()
8335    }
8336}
8337
8338impl TextureLayer {
8339    /// # Panics
8340    /// Panics if the native allocation fails.
8341    pub fn new() -> Self {
8342        // SAFETY: the native constructor returns a live handle; a null here
8343        // means the library is unusable.
8344        unsafe {
8345            let raw = ffi::whiteout_m3_M3TextureLayer_new();
8346            Self::from_raw(raw).expect("native TextureLayer allocation failed")
8347        }
8348    }
8349
8350    /// Layer identifier
8351    pub fn id(&self) -> u32 {
8352        // SAFETY: plain scalar read through a live handle.
8353        unsafe { ffi::whiteout_m3_M3TextureLayer_get_id(self.raw.as_ptr()) }
8354    }
8355
8356    pub fn set_id(&mut self, value: u32) {
8357        // SAFETY: plain scalar write through a live handle.
8358        unsafe { ffi::whiteout_m3_M3TextureLayer_set_id(self.raw.as_ptr(), value) }
8359    }
8360
8361    /// Texture file path (`Ref<CHAR>`)
8362    pub fn texture_path(&self) -> String {
8363        // SAFETY: the native side hands over an owned CString.
8364        unsafe {
8365            crate::support::take_string(ffi::whiteout_m3_M3TextureLayer_get_texturePath(
8366                self.raw.as_ptr(),
8367            ))
8368        }
8369    }
8370
8371    pub fn set_texture_path(&mut self, value: &str) {
8372        let value = std::ffi::CString::new(value).unwrap_or_default();
8373        // SAFETY: the pointer outlives the call.
8374        unsafe {
8375            ffi::whiteout_m3_M3TextureLayer_set_texturePath(self.raw.as_ptr(), value.as_ptr())
8376        }
8377    }
8378
8379    /// Animated color tint
8380    /// Borrows the field in place — no copy, no allocation.
8381    pub fn color(&self) -> crate::support::Ref<'_, AnimRefM3ColorBGRA> {
8382        // SAFETY: an interior pointer into `self`, valid for this
8383        // borrow and never freed by the `Ref`.
8384        unsafe {
8385            crate::support::Ref::new(AnimRefM3ColorBGRA {
8386                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3TextureLayer_get_color(
8387                    self.raw.as_ptr(),
8388                )),
8389            })
8390        }
8391    }
8392
8393    pub fn color_mut(&mut self) -> crate::support::RefMut<'_, AnimRefM3ColorBGRA> {
8394        // SAFETY: as above; `&mut self` guarantees exclusivity.
8395        unsafe {
8396            crate::support::RefMut::new(AnimRefM3ColorBGRA {
8397                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3TextureLayer_get_color(
8398                    self.raw.as_ptr(),
8399                )),
8400            })
8401        }
8402    }
8403
8404    /// Layer flags (wrap, flipbook, video, etc.)
8405    pub fn flags(&self) -> TextureLayerFlag {
8406        // SAFETY: scalar read; a flag set accepts any bits.
8407        TextureLayerFlag(unsafe { ffi::whiteout_m3_M3TextureLayer_get_flags(self.raw.as_ptr()) })
8408    }
8409
8410    pub fn set_flags(&mut self, value: TextureLayerFlag) {
8411        // SAFETY: scalar write through a live handle.
8412        unsafe { ffi::whiteout_m3_M3TextureLayer_set_flags(self.raw.as_ptr(), value.0) }
8413    }
8414
8415    /// UV mapping source
8416    pub fn uv_mapping(&self) -> UVMappingMode {
8417        // SAFETY: scalar read; the discriminant is validated below.
8418        unsafe { ffi::whiteout_m3_M3TextureLayer_get_uvMapping(self.raw.as_ptr()) }
8419            .try_into()
8420            .expect("unknown enum discriminant from the native library")
8421    }
8422
8423    pub fn set_uv_mapping(&mut self, value: UVMappingMode) {
8424        // SAFETY: scalar write through a live handle.
8425        unsafe { ffi::whiteout_m3_M3TextureLayer_set_uvMapping(self.raw.as_ptr(), value as i32) }
8426    }
8427
8428    /// Channel selection
8429    pub fn color_type(&self) -> ColorChannelSelect {
8430        // SAFETY: scalar read; the discriminant is validated below.
8431        unsafe { ffi::whiteout_m3_M3TextureLayer_get_colorType(self.raw.as_ptr()) }
8432            .try_into()
8433            .expect("unknown enum discriminant from the native library")
8434    }
8435
8436    pub fn set_color_type(&mut self, value: ColorChannelSelect) {
8437        // SAFETY: scalar write through a live handle.
8438        unsafe { ffi::whiteout_m3_M3TextureLayer_set_colorType(self.raw.as_ptr(), value as i32) }
8439    }
8440
8441    /// RGB multiply factor
8442    /// Borrows the field in place — no copy, no allocation.
8443    pub fn rgb_multiply(&self) -> crate::support::Ref<'_, AnimRefF32> {
8444        // SAFETY: an interior pointer into `self`, valid for this
8445        // borrow and never freed by the `Ref`.
8446        unsafe {
8447            crate::support::Ref::new(AnimRefF32 {
8448                raw: core::ptr::NonNull::new_unchecked(
8449                    ffi::whiteout_m3_M3TextureLayer_get_rgbMultiply(self.raw.as_ptr()),
8450                ),
8451            })
8452        }
8453    }
8454
8455    pub fn rgb_multiply_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
8456        // SAFETY: as above; `&mut self` guarantees exclusivity.
8457        unsafe {
8458            crate::support::RefMut::new(AnimRefF32 {
8459                raw: core::ptr::NonNull::new_unchecked(
8460                    ffi::whiteout_m3_M3TextureLayer_get_rgbMultiply(self.raw.as_ptr()),
8461                ),
8462            })
8463        }
8464    }
8465
8466    /// RGB additive factor
8467    /// Borrows the field in place — no copy, no allocation.
8468    pub fn rgb_add(&self) -> crate::support::Ref<'_, AnimRefF32> {
8469        // SAFETY: an interior pointer into `self`, valid for this
8470        // borrow and never freed by the `Ref`.
8471        unsafe {
8472            crate::support::Ref::new(AnimRefF32 {
8473                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3TextureLayer_get_rgbAdd(
8474                    self.raw.as_ptr(),
8475                )),
8476            })
8477        }
8478    }
8479
8480    pub fn rgb_add_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
8481        // SAFETY: as above; `&mut self` guarantees exclusivity.
8482        unsafe {
8483            crate::support::RefMut::new(AnimRefF32 {
8484                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3TextureLayer_get_rgbAdd(
8485                    self.raw.as_ptr(),
8486                )),
8487            })
8488        }
8489    }
8490
8491    /// POC texture reference
8492    pub fn poc_texture(&self) -> u32 {
8493        // SAFETY: plain scalar read through a live handle.
8494        unsafe { ffi::whiteout_m3_M3TextureLayer_get_pocTexture(self.raw.as_ptr()) }
8495    }
8496
8497    pub fn set_poc_texture(&mut self, value: u32) {
8498        // SAFETY: plain scalar write through a live handle.
8499        unsafe { ffi::whiteout_m3_M3TextureLayer_set_pocTexture(self.raw.as_ptr(), value) }
8500    }
8501
8502    /// Noise amplitude (v24+)
8503    pub fn noise_amplitude(&self) -> f32 {
8504        // SAFETY: plain scalar read through a live handle.
8505        unsafe { ffi::whiteout_m3_M3TextureLayer_get_noiseAmplitude(self.raw.as_ptr()) }
8506    }
8507
8508    pub fn set_noise_amplitude(&mut self, value: f32) {
8509        // SAFETY: plain scalar write through a live handle.
8510        unsafe { ffi::whiteout_m3_M3TextureLayer_set_noiseAmplitude(self.raw.as_ptr(), value) }
8511    }
8512
8513    /// Noise frequency (v24+)
8514    pub fn noise_frequency(&self) -> f32 {
8515        // SAFETY: plain scalar read through a live handle.
8516        unsafe { ffi::whiteout_m3_M3TextureLayer_get_noiseFrequency(self.raw.as_ptr()) }
8517    }
8518
8519    pub fn set_noise_frequency(&mut self, value: f32) {
8520        // SAFETY: plain scalar write through a live handle.
8521        unsafe { ffi::whiteout_m3_M3TextureLayer_set_noiseFrequency(self.raw.as_ptr(), value) }
8522    }
8523
8524    /// Texture source override
8525    pub fn texture_source(&self) -> u32 {
8526        // SAFETY: plain scalar read through a live handle.
8527        unsafe { ffi::whiteout_m3_M3TextureLayer_get_textureSource(self.raw.as_ptr()) }
8528    }
8529
8530    pub fn set_texture_source(&mut self, value: u32) {
8531        // SAFETY: plain scalar write through a live handle.
8532        unsafe { ffi::whiteout_m3_M3TextureLayer_set_textureSource(self.raw.as_ptr(), value) }
8533    }
8534
8535    /// AVI playback frame rate
8536    pub fn avi_frame_rate(&self) -> u32 {
8537        // SAFETY: plain scalar read through a live handle.
8538        unsafe { ffi::whiteout_m3_M3TextureLayer_get_aviFrameRate(self.raw.as_ptr()) }
8539    }
8540
8541    pub fn set_avi_frame_rate(&mut self, value: u32) {
8542        // SAFETY: plain scalar write through a live handle.
8543        unsafe { ffi::whiteout_m3_M3TextureLayer_set_aviFrameRate(self.raw.as_ptr(), value) }
8544    }
8545
8546    /// AVI start frame
8547    pub fn avi_start(&self) -> u32 {
8548        // SAFETY: plain scalar read through a live handle.
8549        unsafe { ffi::whiteout_m3_M3TextureLayer_get_aviStart(self.raw.as_ptr()) }
8550    }
8551
8552    pub fn set_avi_start(&mut self, value: u32) {
8553        // SAFETY: plain scalar write through a live handle.
8554        unsafe { ffi::whiteout_m3_M3TextureLayer_set_aviStart(self.raw.as_ptr(), value) }
8555    }
8556
8557    /// AVI stop frame
8558    pub fn avi_stop(&self) -> u32 {
8559        // SAFETY: plain scalar read through a live handle.
8560        unsafe { ffi::whiteout_m3_M3TextureLayer_get_aviStop(self.raw.as_ptr()) }
8561    }
8562
8563    pub fn set_avi_stop(&mut self, value: u32) {
8564        // SAFETY: plain scalar write through a live handle.
8565        unsafe { ffi::whiteout_m3_M3TextureLayer_set_aviStop(self.raw.as_ptr(), value) }
8566    }
8567
8568    /// AVI loop mode
8569    pub fn avi_loop(&self) -> u32 {
8570        // SAFETY: plain scalar read through a live handle.
8571        unsafe { ffi::whiteout_m3_M3TextureLayer_get_aviLoop(self.raw.as_ptr()) }
8572    }
8573
8574    pub fn set_avi_loop(&mut self, value: u32) {
8575        // SAFETY: plain scalar write through a live handle.
8576        unsafe { ffi::whiteout_m3_M3TextureLayer_set_aviLoop(self.raw.as_ptr(), value) }
8577    }
8578
8579    /// AVI sync mode
8580    pub fn avi_sync(&self) -> u32 {
8581        // SAFETY: plain scalar read through a live handle.
8582        unsafe { ffi::whiteout_m3_M3TextureLayer_get_aviSync(self.raw.as_ptr()) }
8583    }
8584
8585    pub fn set_avi_sync(&mut self, value: u32) {
8586        // SAFETY: plain scalar write through a live handle.
8587        unsafe { ffi::whiteout_m3_M3TextureLayer_set_aviSync(self.raw.as_ptr(), value) }
8588    }
8589
8590    /// AVI play control
8591    /// Borrows the field in place — no copy, no allocation.
8592    pub fn avi_play(&self) -> crate::support::Ref<'_, AnimRefU32> {
8593        // SAFETY: an interior pointer into `self`, valid for this
8594        // borrow and never freed by the `Ref`.
8595        unsafe {
8596            crate::support::Ref::new(AnimRefU32 {
8597                raw: core::ptr::NonNull::new_unchecked(
8598                    ffi::whiteout_m3_M3TextureLayer_get_aviPlay(self.raw.as_ptr()),
8599                ),
8600            })
8601        }
8602    }
8603
8604    pub fn avi_play_mut(&mut self) -> crate::support::RefMut<'_, AnimRefU32> {
8605        // SAFETY: as above; `&mut self` guarantees exclusivity.
8606        unsafe {
8607            crate::support::RefMut::new(AnimRefU32 {
8608                raw: core::ptr::NonNull::new_unchecked(
8609                    ffi::whiteout_m3_M3TextureLayer_get_aviPlay(self.raw.as_ptr()),
8610                ),
8611            })
8612        }
8613    }
8614
8615    /// AVI restart control
8616    /// Borrows the field in place — no copy, no allocation.
8617    pub fn avi_restart(&self) -> crate::support::Ref<'_, AnimRefU32> {
8618        // SAFETY: an interior pointer into `self`, valid for this
8619        // borrow and never freed by the `Ref`.
8620        unsafe {
8621            crate::support::Ref::new(AnimRefU32 {
8622                raw: core::ptr::NonNull::new_unchecked(
8623                    ffi::whiteout_m3_M3TextureLayer_get_aviRestart(self.raw.as_ptr()),
8624                ),
8625            })
8626        }
8627    }
8628
8629    pub fn avi_restart_mut(&mut self) -> crate::support::RefMut<'_, AnimRefU32> {
8630        // SAFETY: as above; `&mut self` guarantees exclusivity.
8631        unsafe {
8632            crate::support::RefMut::new(AnimRefU32 {
8633                raw: core::ptr::NonNull::new_unchecked(
8634                    ffi::whiteout_m3_M3TextureLayer_get_aviRestart(self.raw.as_ptr()),
8635                ),
8636            })
8637        }
8638    }
8639
8640    /// Flipbook grid rows
8641    pub fn flipbook_rows(&self) -> u32 {
8642        // SAFETY: plain scalar read through a live handle.
8643        unsafe { ffi::whiteout_m3_M3TextureLayer_get_flipbookRows(self.raw.as_ptr()) }
8644    }
8645
8646    pub fn set_flipbook_rows(&mut self, value: u32) {
8647        // SAFETY: plain scalar write through a live handle.
8648        unsafe { ffi::whiteout_m3_M3TextureLayer_set_flipbookRows(self.raw.as_ptr(), value) }
8649    }
8650
8651    /// Flipbook grid columns
8652    pub fn flipbook_columns(&self) -> u32 {
8653        // SAFETY: plain scalar read through a live handle.
8654        unsafe { ffi::whiteout_m3_M3TextureLayer_get_flipbookColumns(self.raw.as_ptr()) }
8655    }
8656
8657    pub fn set_flipbook_columns(&mut self, value: u32) {
8658        // SAFETY: plain scalar write through a live handle.
8659        unsafe { ffi::whiteout_m3_M3TextureLayer_set_flipbookColumns(self.raw.as_ptr(), value) }
8660    }
8661
8662    /// Animated flipbook frame index
8663    /// Borrows the field in place — no copy, no allocation.
8664    pub fn current_frame(&self) -> crate::support::Ref<'_, AnimRefU16> {
8665        // SAFETY: an interior pointer into `self`, valid for this
8666        // borrow and never freed by the `Ref`.
8667        unsafe {
8668            crate::support::Ref::new(AnimRefU16 {
8669                raw: core::ptr::NonNull::new_unchecked(
8670                    ffi::whiteout_m3_M3TextureLayer_get_currentFrame(self.raw.as_ptr()),
8671                ),
8672            })
8673        }
8674    }
8675
8676    pub fn current_frame_mut(&mut self) -> crate::support::RefMut<'_, AnimRefU16> {
8677        // SAFETY: as above; `&mut self` guarantees exclusivity.
8678        unsafe {
8679            crate::support::RefMut::new(AnimRefU16 {
8680                raw: core::ptr::NonNull::new_unchecked(
8681                    ffi::whiteout_m3_M3TextureLayer_get_currentFrame(self.raw.as_ptr()),
8682                ),
8683            })
8684        }
8685    }
8686
8687    /// Animated UV offset
8688    /// Borrows the field in place — no copy, no allocation.
8689    pub fn uv_offset(&self) -> crate::support::Ref<'_, AnimRefVector2f> {
8690        // SAFETY: an interior pointer into `self`, valid for this
8691        // borrow and never freed by the `Ref`.
8692        unsafe {
8693            crate::support::Ref::new(AnimRefVector2f {
8694                raw: core::ptr::NonNull::new_unchecked(
8695                    ffi::whiteout_m3_M3TextureLayer_get_uvOffset(self.raw.as_ptr()),
8696                ),
8697            })
8698        }
8699    }
8700
8701    pub fn uv_offset_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector2f> {
8702        // SAFETY: as above; `&mut self` guarantees exclusivity.
8703        unsafe {
8704            crate::support::RefMut::new(AnimRefVector2f {
8705                raw: core::ptr::NonNull::new_unchecked(
8706                    ffi::whiteout_m3_M3TextureLayer_get_uvOffset(self.raw.as_ptr()),
8707                ),
8708            })
8709        }
8710    }
8711
8712    /// Animated UV rotation angles
8713    /// Borrows the field in place — no copy, no allocation.
8714    pub fn uv_angle(&self) -> crate::support::Ref<'_, AnimRefVector3f> {
8715        // SAFETY: an interior pointer into `self`, valid for this
8716        // borrow and never freed by the `Ref`.
8717        unsafe {
8718            crate::support::Ref::new(AnimRefVector3f {
8719                raw: core::ptr::NonNull::new_unchecked(
8720                    ffi::whiteout_m3_M3TextureLayer_get_uvAngle(self.raw.as_ptr()),
8721                ),
8722            })
8723        }
8724    }
8725
8726    pub fn uv_angle_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector3f> {
8727        // SAFETY: as above; `&mut self` guarantees exclusivity.
8728        unsafe {
8729            crate::support::RefMut::new(AnimRefVector3f {
8730                raw: core::ptr::NonNull::new_unchecked(
8731                    ffi::whiteout_m3_M3TextureLayer_get_uvAngle(self.raw.as_ptr()),
8732                ),
8733            })
8734        }
8735    }
8736
8737    /// Animated UV tiling
8738    /// Borrows the field in place — no copy, no allocation.
8739    pub fn uv_tiling(&self) -> crate::support::Ref<'_, AnimRefVector2f> {
8740        // SAFETY: an interior pointer into `self`, valid for this
8741        // borrow and never freed by the `Ref`.
8742        unsafe {
8743            crate::support::Ref::new(AnimRefVector2f {
8744                raw: core::ptr::NonNull::new_unchecked(
8745                    ffi::whiteout_m3_M3TextureLayer_get_uvTiling(self.raw.as_ptr()),
8746                ),
8747            })
8748        }
8749    }
8750
8751    pub fn uv_tiling_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector2f> {
8752        // SAFETY: as above; `&mut self` guarantees exclusivity.
8753        unsafe {
8754            crate::support::RefMut::new(AnimRefVector2f {
8755                raw: core::ptr::NonNull::new_unchecked(
8756                    ffi::whiteout_m3_M3TextureLayer_get_uvTiling(self.raw.as_ptr()),
8757                ),
8758            })
8759        }
8760    }
8761
8762    /// Animated W offset (3D textures)
8763    /// Borrows the field in place — no copy, no allocation.
8764    pub fn w_offset(&self) -> crate::support::Ref<'_, AnimRefF32> {
8765        // SAFETY: an interior pointer into `self`, valid for this
8766        // borrow and never freed by the `Ref`.
8767        unsafe {
8768            crate::support::Ref::new(AnimRefF32 {
8769                raw: core::ptr::NonNull::new_unchecked(
8770                    ffi::whiteout_m3_M3TextureLayer_get_wOffset(self.raw.as_ptr()),
8771                ),
8772            })
8773        }
8774    }
8775
8776    pub fn w_offset_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
8777        // SAFETY: as above; `&mut self` guarantees exclusivity.
8778        unsafe {
8779            crate::support::RefMut::new(AnimRefF32 {
8780                raw: core::ptr::NonNull::new_unchecked(
8781                    ffi::whiteout_m3_M3TextureLayer_get_wOffset(self.raw.as_ptr()),
8782                ),
8783            })
8784        }
8785    }
8786
8787    /// Animated W tiling (3D textures)
8788    /// Borrows the field in place — no copy, no allocation.
8789    pub fn w_tiling(&self) -> crate::support::Ref<'_, AnimRefF32> {
8790        // SAFETY: an interior pointer into `self`, valid for this
8791        // borrow and never freed by the `Ref`.
8792        unsafe {
8793            crate::support::Ref::new(AnimRefF32 {
8794                raw: core::ptr::NonNull::new_unchecked(
8795                    ffi::whiteout_m3_M3TextureLayer_get_wTiling(self.raw.as_ptr()),
8796                ),
8797            })
8798        }
8799    }
8800
8801    pub fn w_tiling_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
8802        // SAFETY: as above; `&mut self` guarantees exclusivity.
8803        unsafe {
8804            crate::support::RefMut::new(AnimRefF32 {
8805                raw: core::ptr::NonNull::new_unchecked(
8806                    ffi::whiteout_m3_M3TextureLayer_get_wTiling(self.raw.as_ptr()),
8807                ),
8808            })
8809        }
8810    }
8811
8812    /// Animated map alpha
8813    /// Borrows the field in place — no copy, no allocation.
8814    pub fn map_alpha(&self) -> crate::support::Ref<'_, AnimRefF32> {
8815        // SAFETY: an interior pointer into `self`, valid for this
8816        // borrow and never freed by the `Ref`.
8817        unsafe {
8818            crate::support::Ref::new(AnimRefF32 {
8819                raw: core::ptr::NonNull::new_unchecked(
8820                    ffi::whiteout_m3_M3TextureLayer_get_mapAlpha(self.raw.as_ptr()),
8821                ),
8822            })
8823        }
8824    }
8825
8826    pub fn map_alpha_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
8827        // SAFETY: as above; `&mut self` guarantees exclusivity.
8828        unsafe {
8829            crate::support::RefMut::new(AnimRefF32 {
8830                raw: core::ptr::NonNull::new_unchecked(
8831                    ffi::whiteout_m3_M3TextureLayer_get_mapAlpha(self.raw.as_ptr()),
8832                ),
8833            })
8834        }
8835    }
8836
8837    /// Tri-planar UV offset (v23+)
8838    /// Borrows the field in place — no copy, no allocation.
8839    pub fn triplanar_offset(&self) -> crate::support::Ref<'_, AnimRefVector3f> {
8840        // SAFETY: an interior pointer into `self`, valid for this
8841        // borrow and never freed by the `Ref`.
8842        unsafe {
8843            crate::support::Ref::new(AnimRefVector3f {
8844                raw: core::ptr::NonNull::new_unchecked(
8845                    ffi::whiteout_m3_M3TextureLayer_get_triplanarOffset(self.raw.as_ptr()),
8846                ),
8847            })
8848        }
8849    }
8850
8851    pub fn triplanar_offset_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector3f> {
8852        // SAFETY: as above; `&mut self` guarantees exclusivity.
8853        unsafe {
8854            crate::support::RefMut::new(AnimRefVector3f {
8855                raw: core::ptr::NonNull::new_unchecked(
8856                    ffi::whiteout_m3_M3TextureLayer_get_triplanarOffset(self.raw.as_ptr()),
8857                ),
8858            })
8859        }
8860    }
8861
8862    /// Tri-planar UV scale (v23+)
8863    /// Borrows the field in place — no copy, no allocation.
8864    pub fn triplanar_scale(&self) -> crate::support::Ref<'_, AnimRefVector3f> {
8865        // SAFETY: an interior pointer into `self`, valid for this
8866        // borrow and never freed by the `Ref`.
8867        unsafe {
8868            crate::support::Ref::new(AnimRefVector3f {
8869                raw: core::ptr::NonNull::new_unchecked(
8870                    ffi::whiteout_m3_M3TextureLayer_get_triplanarScale(self.raw.as_ptr()),
8871                ),
8872            })
8873        }
8874    }
8875
8876    pub fn triplanar_scale_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector3f> {
8877        // SAFETY: as above; `&mut self` guarantees exclusivity.
8878        unsafe {
8879            crate::support::RefMut::new(AnimRefVector3f {
8880                raw: core::ptr::NonNull::new_unchecked(
8881                    ffi::whiteout_m3_M3TextureLayer_get_triplanarScale(self.raw.as_ptr()),
8882                ),
8883            })
8884        }
8885    }
8886
8887    /// UV source related field
8888    pub fn uv_source_related(&self) -> u32 {
8889        // SAFETY: plain scalar read through a live handle.
8890        unsafe { ffi::whiteout_m3_M3TextureLayer_get_uvSourceRelated(self.raw.as_ptr()) }
8891    }
8892
8893    pub fn set_uv_source_related(&mut self, value: u32) {
8894        // SAFETY: plain scalar write through a live handle.
8895        unsafe { ffi::whiteout_m3_M3TextureLayer_set_uvSourceRelated(self.raw.as_ptr(), value) }
8896    }
8897
8898    /// Fresnel effect mode
8899    pub fn fresnel_mode(&self) -> FresnelMode {
8900        // SAFETY: scalar read; the discriminant is validated below.
8901        unsafe { ffi::whiteout_m3_M3TextureLayer_get_fresnelMode(self.raw.as_ptr()) }
8902            .try_into()
8903            .expect("unknown enum discriminant from the native library")
8904    }
8905
8906    pub fn set_fresnel_mode(&mut self, value: FresnelMode) {
8907        // SAFETY: scalar write through a live handle.
8908        unsafe { ffi::whiteout_m3_M3TextureLayer_set_fresnelMode(self.raw.as_ptr(), value as i32) }
8909    }
8910
8911    /// Fresnel exponent (edge sharpness)
8912    pub fn fresnel_exponent(&self) -> f32 {
8913        // SAFETY: plain scalar read through a live handle.
8914        unsafe { ffi::whiteout_m3_M3TextureLayer_get_fresnelExponent(self.raw.as_ptr()) }
8915    }
8916
8917    pub fn set_fresnel_exponent(&mut self, value: f32) {
8918        // SAFETY: plain scalar write through a live handle.
8919        unsafe { ffi::whiteout_m3_M3TextureLayer_set_fresnelExponent(self.raw.as_ptr(), value) }
8920    }
8921
8922    /// Fresnel minimum intensity
8923    pub fn fresnel_min(&self) -> f32 {
8924        // SAFETY: plain scalar read through a live handle.
8925        unsafe { ffi::whiteout_m3_M3TextureLayer_get_fresnelMin(self.raw.as_ptr()) }
8926    }
8927
8928    pub fn set_fresnel_min(&mut self, value: f32) {
8929        // SAFETY: plain scalar write through a live handle.
8930        unsafe { ffi::whiteout_m3_M3TextureLayer_set_fresnelMin(self.raw.as_ptr(), value) }
8931    }
8932
8933    /// Fresnel maximum intensity
8934    pub fn fresnel_max(&self) -> f32 {
8935        // SAFETY: plain scalar read through a live handle.
8936        unsafe { ffi::whiteout_m3_M3TextureLayer_get_fresnelMax(self.raw.as_ptr()) }
8937    }
8938
8939    pub fn set_fresnel_max(&mut self, value: f32) {
8940        // SAFETY: plain scalar write through a live handle.
8941        unsafe { ffi::whiteout_m3_M3TextureLayer_set_fresnelMax(self.raw.as_ptr(), value) }
8942    }
8943
8944    /// Fresnel UV translation (v25+)
8945    pub fn fresnel_translation(&self) -> crate::math::Vector3f {
8946        // SAFETY: the getter returns an interior pointer to a
8947        // layout-identical POD; we copy it out immediately.
8948        unsafe {
8949            *(ffi::whiteout_m3_M3TextureLayer_get_fresnelTranslation(self.raw.as_ptr())
8950                as *const crate::math::Vector3f)
8951        }
8952    }
8953
8954    pub fn set_fresnel_translation(&mut self, value: crate::math::Vector3f) {
8955        // SAFETY: as above, in the other direction.
8956        unsafe {
8957            ffi::whiteout_m3_M3TextureLayer_set_fresnelTranslation(
8958                self.raw.as_ptr(),
8959                &value as *const crate::math::Vector3f as *const _,
8960            )
8961        }
8962    }
8963
8964    /// Fresnel mask vector (v25+)
8965    pub fn fresnel_mask(&self) -> crate::math::Vector3f {
8966        // SAFETY: the getter returns an interior pointer to a
8967        // layout-identical POD; we copy it out immediately.
8968        unsafe {
8969            *(ffi::whiteout_m3_M3TextureLayer_get_fresnelMask(self.raw.as_ptr())
8970                as *const crate::math::Vector3f)
8971        }
8972    }
8973
8974    pub fn set_fresnel_mask(&mut self, value: crate::math::Vector3f) {
8975        // SAFETY: as above, in the other direction.
8976        unsafe {
8977            ffi::whiteout_m3_M3TextureLayer_set_fresnelMask(
8978                self.raw.as_ptr(),
8979                &value as *const crate::math::Vector3f as *const _,
8980            )
8981        }
8982    }
8983
8984    /// Fresnel UV rotation (v25+)
8985    pub fn fresnel_rotation(&self) -> crate::math::Vector2f {
8986        // SAFETY: the getter returns an interior pointer to a
8987        // layout-identical POD; we copy it out immediately.
8988        unsafe {
8989            *(ffi::whiteout_m3_M3TextureLayer_get_fresnelRotation(self.raw.as_ptr())
8990                as *const crate::math::Vector2f)
8991        }
8992    }
8993
8994    pub fn set_fresnel_rotation(&mut self, value: crate::math::Vector2f) {
8995        // SAFETY: as above, in the other direction.
8996        unsafe {
8997            ffi::whiteout_m3_M3TextureLayer_set_fresnelRotation(
8998                self.raw.as_ptr(),
8999                &value as *const crate::math::Vector2f as *const _,
9000            )
9001        }
9002    }
9003
9004    /// UV density hint (v0–v25, absent in v26)
9005    pub fn uv_density(&self) -> u32 {
9006        // SAFETY: plain scalar read through a live handle.
9007        unsafe { ffi::whiteout_m3_M3TextureLayer_get_uvDensity(self.raw.as_ptr()) }
9008    }
9009
9010    pub fn set_uv_density(&mut self, value: u32) {
9011        // SAFETY: plain scalar write through a live handle.
9012        unsafe { ffi::whiteout_m3_M3TextureLayer_set_uvDensity(self.raw.as_ptr(), value) }
9013    }
9014}
9015
9016impl Default for TextureLayer {
9017    fn default() -> Self {
9018        Self::new()
9019    }
9020}
9021
9022/// MAT_ — Standard material (v0–v20, 268–352 bytes)
9023///
9024/// The primary material type with up to 18 texture layers (diffuse, specular, emissive, normal, height, etc.), blend mode, HDR multipliers, and per-version extensions for normal-blend and gloss layers.
9025pub struct StandardMaterial {
9026    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3StandardMaterial>,
9027}
9028
9029impl Drop for StandardMaterial {
9030    fn drop(&mut self) {
9031        // SAFETY: `raw` came from a native constructor and Drop runs once.
9032        unsafe { ffi::whiteout_m3_M3StandardMaterial_delete(self.raw.as_ptr()) }
9033    }
9034}
9035
9036impl StandardMaterial {
9037    /// # Safety
9038    /// `raw` must be a live handle this value takes ownership of.
9039    #[allow(dead_code)] // used by whichever methods return this type
9040    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3StandardMaterial) -> Option<Self> {
9041        core::ptr::NonNull::new(raw).map(|raw| StandardMaterial { raw })
9042    }
9043}
9044
9045// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
9046// is deliberately NOT implemented — the C++ types make no documented
9047// guarantee about concurrent use, and claiming one we haven't verified
9048// would be unsound. See `@bind thread_safe` in the plan.
9049unsafe impl Send for StandardMaterial {}
9050
9051impl core::fmt::Debug for StandardMaterial {
9052    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
9053        f.debug_struct("StandardMaterial").finish_non_exhaustive()
9054    }
9055}
9056
9057impl StandardMaterial {
9058    /// # Panics
9059    /// Panics if the native allocation fails.
9060    pub fn new() -> Self {
9061        // SAFETY: the native constructor returns a live handle; a null here
9062        // means the library is unusable.
9063        unsafe {
9064            let raw = ffi::whiteout_m3_M3StandardMaterial_new();
9065            Self::from_raw(raw).expect("native StandardMaterial allocation failed")
9066        }
9067    }
9068
9069    /// Material name (`Ref<CHAR>`)
9070    pub fn name(&self) -> String {
9071        // SAFETY: the native side hands over an owned CString.
9072        unsafe {
9073            crate::support::take_string(ffi::whiteout_m3_M3StandardMaterial_get_name(
9074                self.raw.as_ptr(),
9075            ))
9076        }
9077    }
9078
9079    pub fn set_name(&mut self, value: &str) {
9080        let value = std::ffi::CString::new(value).unwrap_or_default();
9081        // SAFETY: the pointer outlives the call.
9082        unsafe { ffi::whiteout_m3_M3StandardMaterial_set_name(self.raw.as_ptr(), value.as_ptr()) }
9083    }
9084
9085    /// Additional flags
9086    pub fn additional_flags(&self) -> MaterialAdditionalFlag {
9087        // SAFETY: scalar read; a flag set accepts any bits.
9088        MaterialAdditionalFlag(unsafe {
9089            ffi::whiteout_m3_M3StandardMaterial_get_additionalFlags(self.raw.as_ptr())
9090        })
9091    }
9092
9093    pub fn set_additional_flags(&mut self, value: MaterialAdditionalFlag) {
9094        // SAFETY: scalar write through a live handle.
9095        unsafe {
9096            ffi::whiteout_m3_M3StandardMaterial_set_additionalFlags(self.raw.as_ptr(), value.0)
9097        }
9098    }
9099
9100    /// Material rendering flags
9101    pub fn flags(&self) -> MaterialFlag {
9102        // SAFETY: scalar read; a flag set accepts any bits.
9103        MaterialFlag(unsafe { ffi::whiteout_m3_M3StandardMaterial_get_flags(self.raw.as_ptr()) })
9104    }
9105
9106    pub fn set_flags(&mut self, value: MaterialFlag) {
9107        // SAFETY: scalar write through a live handle.
9108        unsafe { ffi::whiteout_m3_M3StandardMaterial_set_flags(self.raw.as_ptr(), value.0) }
9109    }
9110
9111    /// Alpha blend mode
9112    pub fn blend_mode(&self) -> BlendMode {
9113        // SAFETY: scalar read; the discriminant is validated below.
9114        unsafe { ffi::whiteout_m3_M3StandardMaterial_get_blendMode(self.raw.as_ptr()) }
9115            .try_into()
9116            .expect("unknown enum discriminant from the native library")
9117    }
9118
9119    pub fn set_blend_mode(&mut self, value: BlendMode) {
9120        // SAFETY: scalar write through a live handle.
9121        unsafe {
9122            ffi::whiteout_m3_M3StandardMaterial_set_blendMode(self.raw.as_ptr(), value as i32)
9123        }
9124    }
9125
9126    /// Render priority (lower = earlier)
9127    pub fn priority(&self) -> i32 {
9128        // SAFETY: plain scalar read through a live handle.
9129        unsafe { ffi::whiteout_m3_M3StandardMaterial_get_priority(self.raw.as_ptr()) }
9130    }
9131
9132    pub fn set_priority(&mut self, value: i32) {
9133        // SAFETY: plain scalar write through a live handle.
9134        unsafe { ffi::whiteout_m3_M3StandardMaterial_set_priority(self.raw.as_ptr(), value) }
9135    }
9136
9137    /// RTT channel mask
9138    pub fn rtt_channels(&self) -> u32 {
9139        // SAFETY: plain scalar read through a live handle.
9140        unsafe { ffi::whiteout_m3_M3StandardMaterial_get_rttChannels(self.raw.as_ptr()) }
9141    }
9142
9143    pub fn set_rtt_channels(&mut self, value: u32) {
9144        // SAFETY: plain scalar write through a live handle.
9145        unsafe { ffi::whiteout_m3_M3StandardMaterial_set_rttChannels(self.raw.as_ptr(), value) }
9146    }
9147
9148    /// Specular highlight exponent
9149    pub fn specular_exponent(&self) -> f32 {
9150        // SAFETY: plain scalar read through a live handle.
9151        unsafe { ffi::whiteout_m3_M3StandardMaterial_get_specularExponent(self.raw.as_ptr()) }
9152    }
9153
9154    pub fn set_specular_exponent(&mut self, value: f32) {
9155        // SAFETY: plain scalar write through a live handle.
9156        unsafe {
9157            ffi::whiteout_m3_M3StandardMaterial_set_specularExponent(self.raw.as_ptr(), value)
9158        }
9159    }
9160
9161    /// Depth blend falloff distance
9162    pub fn depth_blend_falloff(&self) -> f32 {
9163        // SAFETY: plain scalar read through a live handle.
9164        unsafe { ffi::whiteout_m3_M3StandardMaterial_get_depthBlendFalloff(self.raw.as_ptr()) }
9165    }
9166
9167    pub fn set_depth_blend_falloff(&mut self, value: f32) {
9168        // SAFETY: plain scalar write through a live handle.
9169        unsafe {
9170            ffi::whiteout_m3_M3StandardMaterial_set_depthBlendFalloff(self.raw.as_ptr(), value)
9171        }
9172    }
9173
9174    /// Alpha test cut-off value
9175    pub fn alpha_test_threshold(&self) -> u32 {
9176        // SAFETY: plain scalar read through a live handle.
9177        unsafe { ffi::whiteout_m3_M3StandardMaterial_get_alphaTestThreshold(self.raw.as_ptr()) }
9178    }
9179
9180    pub fn set_alpha_test_threshold(&mut self, value: u32) {
9181        // SAFETY: plain scalar write through a live handle.
9182        unsafe {
9183            ffi::whiteout_m3_M3StandardMaterial_set_alphaTestThreshold(self.raw.as_ptr(), value)
9184        }
9185    }
9186
9187    /// HDR specular multiplier
9188    pub fn hdr_specular_multiplier(&self) -> f32 {
9189        // SAFETY: plain scalar read through a live handle.
9190        unsafe { ffi::whiteout_m3_M3StandardMaterial_get_hdrSpecularMultiplier(self.raw.as_ptr()) }
9191    }
9192
9193    pub fn set_hdr_specular_multiplier(&mut self, value: f32) {
9194        // SAFETY: plain scalar write through a live handle.
9195        unsafe {
9196            ffi::whiteout_m3_M3StandardMaterial_set_hdrSpecularMultiplier(self.raw.as_ptr(), value)
9197        }
9198    }
9199
9200    /// HDR emissive multiplier
9201    pub fn hdr_emissive_multiplier(&self) -> f32 {
9202        // SAFETY: plain scalar read through a live handle.
9203        unsafe { ffi::whiteout_m3_M3StandardMaterial_get_hdrEmissiveMultiplier(self.raw.as_ptr()) }
9204    }
9205
9206    pub fn set_hdr_emissive_multiplier(&mut self, value: f32) {
9207        // SAFETY: plain scalar write through a live handle.
9208        unsafe {
9209            ffi::whiteout_m3_M3StandardMaterial_set_hdrEmissiveMultiplier(self.raw.as_ptr(), value)
9210        }
9211    }
9212
9213    /// HDR environment constant (v20)
9214    pub fn hdr_environment_constant(&self) -> f32 {
9215        // SAFETY: plain scalar read through a live handle.
9216        unsafe { ffi::whiteout_m3_M3StandardMaterial_get_hdrEnvironmentConstant(self.raw.as_ptr()) }
9217    }
9218
9219    pub fn set_hdr_environment_constant(&mut self, value: f32) {
9220        // SAFETY: plain scalar write through a live handle.
9221        unsafe {
9222            ffi::whiteout_m3_M3StandardMaterial_set_hdrEnvironmentConstant(self.raw.as_ptr(), value)
9223        }
9224    }
9225
9226    /// HDR environment diffuse (v20)
9227    pub fn hdr_environment_diffuse(&self) -> f32 {
9228        // SAFETY: plain scalar read through a live handle.
9229        unsafe { ffi::whiteout_m3_M3StandardMaterial_get_hdrEnvironmentDiffuse(self.raw.as_ptr()) }
9230    }
9231
9232    pub fn set_hdr_environment_diffuse(&mut self, value: f32) {
9233        // SAFETY: plain scalar write through a live handle.
9234        unsafe {
9235            ffi::whiteout_m3_M3StandardMaterial_set_hdrEnvironmentDiffuse(self.raw.as_ptr(), value)
9236        }
9237    }
9238
9239    /// HDR environment specular (v20)
9240    pub fn hdr_environment_specular(&self) -> f32 {
9241        // SAFETY: plain scalar read through a live handle.
9242        unsafe { ffi::whiteout_m3_M3StandardMaterial_get_hdrEnvironmentSpecular(self.raw.as_ptr()) }
9243    }
9244
9245    pub fn set_hdr_environment_specular(&mut self, value: f32) {
9246        // SAFETY: plain scalar write through a live handle.
9247        unsafe {
9248            ffi::whiteout_m3_M3StandardMaterial_set_hdrEnvironmentSpecular(self.raw.as_ptr(), value)
9249        }
9250    }
9251
9252    /// Material class (unit, building, etc.)
9253    pub fn material_class(&self) -> MaterialClass {
9254        // SAFETY: scalar read; the discriminant is validated below.
9255        unsafe { ffi::whiteout_m3_M3StandardMaterial_get_materialClass(self.raw.as_ptr()) }
9256            .try_into()
9257            .expect("unknown enum discriminant from the native library")
9258    }
9259
9260    pub fn set_material_class(&mut self, value: MaterialClass) {
9261        // SAFETY: scalar write through a live handle.
9262        unsafe {
9263            ffi::whiteout_m3_M3StandardMaterial_set_materialClass(self.raw.as_ptr(), value as i32)
9264        }
9265    }
9266
9267    /// Layer blend operation
9268    pub fn layer_blend_mode(&self) -> LayerBlendOp {
9269        // SAFETY: scalar read; the discriminant is validated below.
9270        unsafe { ffi::whiteout_m3_M3StandardMaterial_get_layerBlendMode(self.raw.as_ptr()) }
9271            .try_into()
9272            .expect("unknown enum discriminant from the native library")
9273    }
9274
9275    pub fn set_layer_blend_mode(&mut self, value: LayerBlendOp) {
9276        // SAFETY: scalar write through a live handle.
9277        unsafe {
9278            ffi::whiteout_m3_M3StandardMaterial_set_layerBlendMode(self.raw.as_ptr(), value as i32)
9279        }
9280    }
9281
9282    /// Emissive layer 1 blend mode
9283    pub fn emissive_blend_mode_1(&self) -> LayerBlendOp {
9284        // SAFETY: scalar read; the discriminant is validated below.
9285        unsafe { ffi::whiteout_m3_M3StandardMaterial_get_emissiveBlendMode1(self.raw.as_ptr()) }
9286            .try_into()
9287            .expect("unknown enum discriminant from the native library")
9288    }
9289
9290    pub fn set_emissive_blend_mode_1(&mut self, value: LayerBlendOp) {
9291        // SAFETY: scalar write through a live handle.
9292        unsafe {
9293            ffi::whiteout_m3_M3StandardMaterial_set_emissiveBlendMode1(
9294                self.raw.as_ptr(),
9295                value as i32,
9296            )
9297        }
9298    }
9299
9300    /// Emissive layer 2 blend mode
9301    pub fn emissive_blend_mode_2(&self) -> LayerBlendOp {
9302        // SAFETY: scalar read; the discriminant is validated below.
9303        unsafe { ffi::whiteout_m3_M3StandardMaterial_get_emissiveBlendMode2(self.raw.as_ptr()) }
9304            .try_into()
9305            .expect("unknown enum discriminant from the native library")
9306    }
9307
9308    pub fn set_emissive_blend_mode_2(&mut self, value: LayerBlendOp) {
9309        // SAFETY: scalar write through a live handle.
9310        unsafe {
9311            ffi::whiteout_m3_M3StandardMaterial_set_emissiveBlendMode2(
9312                self.raw.as_ptr(),
9313                value as i32,
9314            )
9315        }
9316    }
9317
9318    /// Specular computation mode
9319    pub fn specular_mode(&self) -> SpecularMode {
9320        // SAFETY: scalar read; the discriminant is validated below.
9321        unsafe { ffi::whiteout_m3_M3StandardMaterial_get_specularMode(self.raw.as_ptr()) }
9322            .try_into()
9323            .expect("unknown enum discriminant from the native library")
9324    }
9325
9326    pub fn set_specular_mode(&mut self, value: SpecularMode) {
9327        // SAFETY: scalar write through a live handle.
9328        unsafe {
9329            ffi::whiteout_m3_M3StandardMaterial_set_specularMode(self.raw.as_ptr(), value as i32)
9330        }
9331    }
9332
9333    /// Animated parallax height
9334    /// Borrows the field in place — no copy, no allocation.
9335    pub fn parallax_height(&self) -> crate::support::Ref<'_, AnimRefF32> {
9336        // SAFETY: an interior pointer into `self`, valid for this
9337        // borrow and never freed by the `Ref`.
9338        unsafe {
9339            crate::support::Ref::new(AnimRefF32 {
9340                raw: core::ptr::NonNull::new_unchecked(
9341                    ffi::whiteout_m3_M3StandardMaterial_get_parallaxHeight(self.raw.as_ptr()),
9342                ),
9343            })
9344        }
9345    }
9346
9347    pub fn parallax_height_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
9348        // SAFETY: as above; `&mut self` guarantees exclusivity.
9349        unsafe {
9350            crate::support::RefMut::new(AnimRefF32 {
9351                raw: core::ptr::NonNull::new_unchecked(
9352                    ffi::whiteout_m3_M3StandardMaterial_get_parallaxHeight(self.raw.as_ptr()),
9353                ),
9354            })
9355        }
9356    }
9357
9358    /// Animated motion blur amount
9359    /// Borrows the field in place — no copy, no allocation.
9360    pub fn motion_blur_amount(&self) -> crate::support::Ref<'_, AnimRefF32> {
9361        // SAFETY: an interior pointer into `self`, valid for this
9362        // borrow and never freed by the `Ref`.
9363        unsafe {
9364            crate::support::Ref::new(AnimRefF32 {
9365                raw: core::ptr::NonNull::new_unchecked(
9366                    ffi::whiteout_m3_M3StandardMaterial_get_motionBlurAmount(self.raw.as_ptr()),
9367                ),
9368            })
9369        }
9370    }
9371
9372    pub fn motion_blur_amount_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
9373        // SAFETY: as above; `&mut self` guarantees exclusivity.
9374        unsafe {
9375            crate::support::RefMut::new(AnimRefF32 {
9376                raw: core::ptr::NonNull::new_unchecked(
9377                    ffi::whiteout_m3_M3StandardMaterial_get_motionBlurAmount(self.raw.as_ptr()),
9378                ),
9379            })
9380        }
9381    }
9382
9383    /// Normal blend factors (v19+)
9384    pub fn normal_blend_factors_len(&self) -> usize {
9385        // SAFETY: scalar read through a live handle.
9386        unsafe {
9387            ffi::whiteout_m3_M3StandardMaterial_get_normalBlendFactors_count(self.raw.as_ptr())
9388        }
9389    }
9390
9391    /// Borrows element `index` in place. `None` when out of range.
9392    pub fn normal_blend_factors(
9393        &self,
9394        index: usize,
9395    ) -> Option<crate::support::Ref<'_, AnimRefF32>> {
9396        if index >= self.normal_blend_factors_len() {
9397            return None;
9398        }
9399        // SAFETY: index checked above; the pointer is interior to `self`.
9400        unsafe {
9401            Some(crate::support::Ref::new(AnimRefF32 {
9402                raw: core::ptr::NonNull::new_unchecked(
9403                    ffi::whiteout_m3_M3StandardMaterial_get_normalBlendFactors_at(
9404                        self.raw.as_ptr(),
9405                        index,
9406                    ),
9407                ),
9408            }))
9409        }
9410    }
9411
9412    pub fn normal_blend_factors_mut(
9413        &mut self,
9414        index: usize,
9415    ) -> Option<crate::support::RefMut<'_, AnimRefF32>> {
9416        if index >= self.normal_blend_factors_len() {
9417            return None;
9418        }
9419        // SAFETY: as above; `&mut self` guarantees exclusivity.
9420        unsafe {
9421            Some(crate::support::RefMut::new(AnimRefF32 {
9422                raw: core::ptr::NonNull::new_unchecked(
9423                    ffi::whiteout_m3_M3StandardMaterial_get_normalBlendFactors_at(
9424                        self.raw.as_ptr(),
9425                        index,
9426                    ),
9427                ),
9428            }))
9429        }
9430    }
9431
9432    /// Iterate the elements, borrowing each in turn.
9433    pub fn normal_blend_factors_iter(
9434        &self,
9435    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, AnimRefF32>> {
9436        (0..self.normal_blend_factors_len())
9437            .map(move |i| self.normal_blend_factors(i).expect("index below len"))
9438    }
9439
9440    pub fn resize_normal_blend_factors(&mut self, count: usize) {
9441        // SAFETY: exclusive access, so no borrow is outstanding.
9442        unsafe {
9443            ffi::whiteout_m3_M3StandardMaterial_resize_normalBlendFactors(self.raw.as_ptr(), count)
9444        }
9445    }
9446}
9447
9448impl Default for StandardMaterial {
9449    fn default() -> Self {
9450        Self::new()
9451    }
9452}
9453
9454/// DIS_ — Displacement material (v0–v4, 68 bytes)
9455///
9456/// Applies vertex displacement via a normal map and animated strength.
9457pub struct DisplacementMaterial {
9458    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3DisplacementMaterial>,
9459}
9460
9461impl Drop for DisplacementMaterial {
9462    fn drop(&mut self) {
9463        // SAFETY: `raw` came from a native constructor and Drop runs once.
9464        unsafe { ffi::whiteout_m3_M3DisplacementMaterial_delete(self.raw.as_ptr()) }
9465    }
9466}
9467
9468impl DisplacementMaterial {
9469    /// # Safety
9470    /// `raw` must be a live handle this value takes ownership of.
9471    #[allow(dead_code)] // used by whichever methods return this type
9472    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3DisplacementMaterial) -> Option<Self> {
9473        core::ptr::NonNull::new(raw).map(|raw| DisplacementMaterial { raw })
9474    }
9475}
9476
9477// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
9478// is deliberately NOT implemented — the C++ types make no documented
9479// guarantee about concurrent use, and claiming one we haven't verified
9480// would be unsound. See `@bind thread_safe` in the plan.
9481unsafe impl Send for DisplacementMaterial {}
9482
9483impl core::fmt::Debug for DisplacementMaterial {
9484    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
9485        f.debug_struct("DisplacementMaterial")
9486            .finish_non_exhaustive()
9487    }
9488}
9489
9490impl DisplacementMaterial {
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_m3_M3DisplacementMaterial_new();
9498            Self::from_raw(raw).expect("native DisplacementMaterial allocation failed")
9499        }
9500    }
9501
9502    /// Material name (`Ref<CHAR>`)
9503    pub fn name(&self) -> String {
9504        // SAFETY: the native side hands over an owned CString.
9505        unsafe {
9506            crate::support::take_string(ffi::whiteout_m3_M3DisplacementMaterial_get_name(
9507                self.raw.as_ptr(),
9508            ))
9509        }
9510    }
9511
9512    pub fn set_name(&mut self, value: &str) {
9513        let value = std::ffi::CString::new(value).unwrap_or_default();
9514        // SAFETY: the pointer outlives the call.
9515        unsafe {
9516            ffi::whiteout_m3_M3DisplacementMaterial_set_name(self.raw.as_ptr(), value.as_ptr())
9517        }
9518    }
9519
9520    /// Unknown field
9521    pub fn unknown(&self) -> u32 {
9522        // SAFETY: plain scalar read through a live handle.
9523        unsafe { ffi::whiteout_m3_M3DisplacementMaterial_get_unknown(self.raw.as_ptr()) }
9524    }
9525
9526    pub fn set_unknown(&mut self, value: u32) {
9527        // SAFETY: plain scalar write through a live handle.
9528        unsafe { ffi::whiteout_m3_M3DisplacementMaterial_set_unknown(self.raw.as_ptr(), value) }
9529    }
9530
9531    /// Animated displacement strength
9532    /// Borrows the field in place — no copy, no allocation.
9533    pub fn strength(&self) -> crate::support::Ref<'_, AnimRefF32> {
9534        // SAFETY: an interior pointer into `self`, valid for this
9535        // borrow and never freed by the `Ref`.
9536        unsafe {
9537            crate::support::Ref::new(AnimRefF32 {
9538                raw: core::ptr::NonNull::new_unchecked(
9539                    ffi::whiteout_m3_M3DisplacementMaterial_get_strength(self.raw.as_ptr()),
9540                ),
9541            })
9542        }
9543    }
9544
9545    pub fn strength_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
9546        // SAFETY: as above; `&mut self` guarantees exclusivity.
9547        unsafe {
9548            crate::support::RefMut::new(AnimRefF32 {
9549                raw: core::ptr::NonNull::new_unchecked(
9550                    ffi::whiteout_m3_M3DisplacementMaterial_get_strength(self.raw.as_ptr()),
9551                ),
9552            })
9553        }
9554    }
9555
9556    /// Render priority
9557    pub fn priority(&self) -> u32 {
9558        // SAFETY: plain scalar read through a live handle.
9559        unsafe { ffi::whiteout_m3_M3DisplacementMaterial_get_priority(self.raw.as_ptr()) }
9560    }
9561
9562    pub fn set_priority(&mut self, value: u32) {
9563        // SAFETY: plain scalar write through a live handle.
9564        unsafe { ffi::whiteout_m3_M3DisplacementMaterial_set_priority(self.raw.as_ptr(), value) }
9565    }
9566}
9567
9568impl Default for DisplacementMaterial {
9569    fn default() -> Self {
9570        Self::new()
9571    }
9572}
9573
9574/// CMS_ — Composite material section (v0, 24 bytes)
9575///
9576/// A single section within a composite material, referencing another material index with an animated blend multiplier.
9577pub struct CompositeSection {
9578    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3CompositeSection>,
9579}
9580
9581impl Drop for CompositeSection {
9582    fn drop(&mut self) {
9583        // SAFETY: `raw` came from a native constructor and Drop runs once.
9584        unsafe { ffi::whiteout_m3_M3CompositeSection_delete(self.raw.as_ptr()) }
9585    }
9586}
9587
9588impl CompositeSection {
9589    /// # Safety
9590    /// `raw` must be a live handle this value takes ownership of.
9591    #[allow(dead_code)] // used by whichever methods return this type
9592    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3CompositeSection) -> Option<Self> {
9593        core::ptr::NonNull::new(raw).map(|raw| CompositeSection { raw })
9594    }
9595}
9596
9597// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
9598// is deliberately NOT implemented — the C++ types make no documented
9599// guarantee about concurrent use, and claiming one we haven't verified
9600// would be unsound. See `@bind thread_safe` in the plan.
9601unsafe impl Send for CompositeSection {}
9602
9603impl core::fmt::Debug for CompositeSection {
9604    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
9605        f.debug_struct("CompositeSection").finish_non_exhaustive()
9606    }
9607}
9608
9609impl CompositeSection {
9610    /// # Panics
9611    /// Panics if the native allocation fails.
9612    pub fn new() -> Self {
9613        // SAFETY: the native constructor returns a live handle; a null here
9614        // means the library is unusable.
9615        unsafe {
9616            let raw = ffi::whiteout_m3_M3CompositeSection_new();
9617            Self::from_raw(raw).expect("native CompositeSection allocation failed")
9618        }
9619    }
9620
9621    /// Index into MATM array
9622    pub fn material_index(&self) -> u32 {
9623        // SAFETY: plain scalar read through a live handle.
9624        unsafe { ffi::whiteout_m3_M3CompositeSection_get_materialIndex(self.raw.as_ptr()) }
9625    }
9626
9627    pub fn set_material_index(&mut self, value: u32) {
9628        // SAFETY: plain scalar write through a live handle.
9629        unsafe { ffi::whiteout_m3_M3CompositeSection_set_materialIndex(self.raw.as_ptr(), value) }
9630    }
9631
9632    /// Animated blend weight
9633    /// Borrows the field in place — no copy, no allocation.
9634    pub fn map_multiplier(&self) -> crate::support::Ref<'_, AnimRefF32> {
9635        // SAFETY: an interior pointer into `self`, valid for this
9636        // borrow and never freed by the `Ref`.
9637        unsafe {
9638            crate::support::Ref::new(AnimRefF32 {
9639                raw: core::ptr::NonNull::new_unchecked(
9640                    ffi::whiteout_m3_M3CompositeSection_get_mapMultiplier(self.raw.as_ptr()),
9641                ),
9642            })
9643        }
9644    }
9645
9646    pub fn map_multiplier_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
9647        // SAFETY: as above; `&mut self` guarantees exclusivity.
9648        unsafe {
9649            crate::support::RefMut::new(AnimRefF32 {
9650                raw: core::ptr::NonNull::new_unchecked(
9651                    ffi::whiteout_m3_M3CompositeSection_get_mapMultiplier(self.raw.as_ptr()),
9652                ),
9653            })
9654        }
9655    }
9656}
9657
9658impl Default for CompositeSection {
9659    fn default() -> Self {
9660        Self::new()
9661    }
9662}
9663
9664/// CMP_ — Composite material (v0–v2, 28 bytes)
9665///
9666/// Blends multiple sub-materials via CompositeSection entries.
9667pub struct CompositeMaterial {
9668    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3CompositeMaterial>,
9669}
9670
9671impl Drop for CompositeMaterial {
9672    fn drop(&mut self) {
9673        // SAFETY: `raw` came from a native constructor and Drop runs once.
9674        unsafe { ffi::whiteout_m3_M3CompositeMaterial_delete(self.raw.as_ptr()) }
9675    }
9676}
9677
9678impl CompositeMaterial {
9679    /// # Safety
9680    /// `raw` must be a live handle this value takes ownership of.
9681    #[allow(dead_code)] // used by whichever methods return this type
9682    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3CompositeMaterial) -> Option<Self> {
9683        core::ptr::NonNull::new(raw).map(|raw| CompositeMaterial { raw })
9684    }
9685}
9686
9687// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
9688// is deliberately NOT implemented — the C++ types make no documented
9689// guarantee about concurrent use, and claiming one we haven't verified
9690// would be unsound. See `@bind thread_safe` in the plan.
9691unsafe impl Send for CompositeMaterial {}
9692
9693impl core::fmt::Debug for CompositeMaterial {
9694    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
9695        f.debug_struct("CompositeMaterial").finish_non_exhaustive()
9696    }
9697}
9698
9699impl CompositeMaterial {
9700    /// # Panics
9701    /// Panics if the native allocation fails.
9702    pub fn new() -> Self {
9703        // SAFETY: the native constructor returns a live handle; a null here
9704        // means the library is unusable.
9705        unsafe {
9706            let raw = ffi::whiteout_m3_M3CompositeMaterial_new();
9707            Self::from_raw(raw).expect("native CompositeMaterial allocation failed")
9708        }
9709    }
9710
9711    /// Material name (`Ref<CHAR>`)
9712    pub fn name(&self) -> String {
9713        // SAFETY: the native side hands over an owned CString.
9714        unsafe {
9715            crate::support::take_string(ffi::whiteout_m3_M3CompositeMaterial_get_name(
9716                self.raw.as_ptr(),
9717            ))
9718        }
9719    }
9720
9721    pub fn set_name(&mut self, value: &str) {
9722        let value = std::ffi::CString::new(value).unwrap_or_default();
9723        // SAFETY: the pointer outlives the call.
9724        unsafe { ffi::whiteout_m3_M3CompositeMaterial_set_name(self.raw.as_ptr(), value.as_ptr()) }
9725    }
9726
9727    /// Render priority
9728    pub fn priority(&self) -> u32 {
9729        // SAFETY: plain scalar read through a live handle.
9730        unsafe { ffi::whiteout_m3_M3CompositeMaterial_get_priority(self.raw.as_ptr()) }
9731    }
9732
9733    pub fn set_priority(&mut self, value: u32) {
9734        // SAFETY: plain scalar write through a live handle.
9735        unsafe { ffi::whiteout_m3_M3CompositeMaterial_set_priority(self.raw.as_ptr(), value) }
9736    }
9737
9738    /// Sub-material sections (CMS_)
9739    pub fn sections_len(&self) -> usize {
9740        // SAFETY: scalar read through a live handle.
9741        unsafe { ffi::whiteout_m3_M3CompositeMaterial_get_sections_count(self.raw.as_ptr()) }
9742    }
9743
9744    /// Borrows element `index` in place. `None` when out of range.
9745    pub fn sections(&self, index: usize) -> Option<crate::support::Ref<'_, CompositeSection>> {
9746        if index >= self.sections_len() {
9747            return None;
9748        }
9749        // SAFETY: index checked above; the pointer is interior to `self`.
9750        unsafe {
9751            Some(crate::support::Ref::new(CompositeSection {
9752                raw: core::ptr::NonNull::new_unchecked(
9753                    ffi::whiteout_m3_M3CompositeMaterial_get_sections_at(self.raw.as_ptr(), index),
9754                ),
9755            }))
9756        }
9757    }
9758
9759    pub fn sections_mut(
9760        &mut self,
9761        index: usize,
9762    ) -> Option<crate::support::RefMut<'_, CompositeSection>> {
9763        if index >= self.sections_len() {
9764            return None;
9765        }
9766        // SAFETY: as above; `&mut self` guarantees exclusivity.
9767        unsafe {
9768            Some(crate::support::RefMut::new(CompositeSection {
9769                raw: core::ptr::NonNull::new_unchecked(
9770                    ffi::whiteout_m3_M3CompositeMaterial_get_sections_at(self.raw.as_ptr(), index),
9771                ),
9772            }))
9773        }
9774    }
9775
9776    /// Iterate the elements, borrowing each in turn.
9777    pub fn sections_iter(
9778        &self,
9779    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, CompositeSection>> {
9780        (0..self.sections_len()).map(move |i| self.sections(i).expect("index below len"))
9781    }
9782
9783    pub fn resize_sections(&mut self, count: usize) {
9784        // SAFETY: exclusive access, so no borrow is outstanding.
9785        unsafe { ffi::whiteout_m3_M3CompositeMaterial_resize_sections(self.raw.as_ptr(), count) }
9786    }
9787}
9788
9789impl Default for CompositeMaterial {
9790    fn default() -> Self {
9791        Self::new()
9792    }
9793}
9794
9795/// TER_ — Terrain material (v0–v1, 28 bytes)
9796///
9797/// Simple terrain-specific material with a single texture layer.
9798pub struct TerrainMaterial {
9799    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3TerrainMaterial>,
9800}
9801
9802impl Drop for TerrainMaterial {
9803    fn drop(&mut self) {
9804        // SAFETY: `raw` came from a native constructor and Drop runs once.
9805        unsafe { ffi::whiteout_m3_M3TerrainMaterial_delete(self.raw.as_ptr()) }
9806    }
9807}
9808
9809impl TerrainMaterial {
9810    /// # Safety
9811    /// `raw` must be a live handle this value takes ownership of.
9812    #[allow(dead_code)] // used by whichever methods return this type
9813    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3TerrainMaterial) -> Option<Self> {
9814        core::ptr::NonNull::new(raw).map(|raw| TerrainMaterial { raw })
9815    }
9816}
9817
9818// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
9819// is deliberately NOT implemented — the C++ types make no documented
9820// guarantee about concurrent use, and claiming one we haven't verified
9821// would be unsound. See `@bind thread_safe` in the plan.
9822unsafe impl Send for TerrainMaterial {}
9823
9824impl core::fmt::Debug for TerrainMaterial {
9825    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
9826        f.debug_struct("TerrainMaterial").finish_non_exhaustive()
9827    }
9828}
9829
9830impl TerrainMaterial {
9831    /// # Panics
9832    /// Panics if the native allocation fails.
9833    pub fn new() -> Self {
9834        // SAFETY: the native constructor returns a live handle; a null here
9835        // means the library is unusable.
9836        unsafe {
9837            let raw = ffi::whiteout_m3_M3TerrainMaterial_new();
9838            Self::from_raw(raw).expect("native TerrainMaterial allocation failed")
9839        }
9840    }
9841
9842    /// Material name (`Ref<CHAR>`)
9843    pub fn name(&self) -> String {
9844        // SAFETY: the native side hands over an owned CString.
9845        unsafe {
9846            crate::support::take_string(ffi::whiteout_m3_M3TerrainMaterial_get_name(
9847                self.raw.as_ptr(),
9848            ))
9849        }
9850    }
9851
9852    pub fn set_name(&mut self, value: &str) {
9853        let value = std::ffi::CString::new(value).unwrap_or_default();
9854        // SAFETY: the pointer outlives the call.
9855        unsafe { ffi::whiteout_m3_M3TerrainMaterial_set_name(self.raw.as_ptr(), value.as_ptr()) }
9856    }
9857
9858    /// Unknown field
9859    pub fn unknown(&self) -> u32 {
9860        // SAFETY: plain scalar read through a live handle.
9861        unsafe { ffi::whiteout_m3_M3TerrainMaterial_get_unknown(self.raw.as_ptr()) }
9862    }
9863
9864    pub fn set_unknown(&mut self, value: u32) {
9865        // SAFETY: plain scalar write through a live handle.
9866        unsafe { ffi::whiteout_m3_M3TerrainMaterial_set_unknown(self.raw.as_ptr(), value) }
9867    }
9868}
9869
9870impl Default for TerrainMaterial {
9871    fn default() -> Self {
9872        Self::new()
9873    }
9874}
9875
9876/// VOL_ — Volume material (v0, 84 bytes)
9877///
9878/// Volumetric rendering material with density falloff, color map, and two noise maps for procedural volumetric effects.
9879pub struct VolumeMaterial {
9880    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3VolumeMaterial>,
9881}
9882
9883impl Drop for VolumeMaterial {
9884    fn drop(&mut self) {
9885        // SAFETY: `raw` came from a native constructor and Drop runs once.
9886        unsafe { ffi::whiteout_m3_M3VolumeMaterial_delete(self.raw.as_ptr()) }
9887    }
9888}
9889
9890impl VolumeMaterial {
9891    /// # Safety
9892    /// `raw` must be a live handle this value takes ownership of.
9893    #[allow(dead_code)] // used by whichever methods return this type
9894    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3VolumeMaterial) -> Option<Self> {
9895        core::ptr::NonNull::new(raw).map(|raw| VolumeMaterial { raw })
9896    }
9897}
9898
9899// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
9900// is deliberately NOT implemented — the C++ types make no documented
9901// guarantee about concurrent use, and claiming one we haven't verified
9902// would be unsound. See `@bind thread_safe` in the plan.
9903unsafe impl Send for VolumeMaterial {}
9904
9905impl core::fmt::Debug for VolumeMaterial {
9906    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
9907        f.debug_struct("VolumeMaterial").finish_non_exhaustive()
9908    }
9909}
9910
9911impl VolumeMaterial {
9912    /// # Panics
9913    /// Panics if the native allocation fails.
9914    pub fn new() -> Self {
9915        // SAFETY: the native constructor returns a live handle; a null here
9916        // means the library is unusable.
9917        unsafe {
9918            let raw = ffi::whiteout_m3_M3VolumeMaterial_new();
9919            Self::from_raw(raw).expect("native VolumeMaterial allocation failed")
9920        }
9921    }
9922
9923    /// Material name (`Ref<CHAR>`)
9924    pub fn name(&self) -> String {
9925        // SAFETY: the native side hands over an owned CString.
9926        unsafe {
9927            crate::support::take_string(ffi::whiteout_m3_M3VolumeMaterial_get_name(
9928                self.raw.as_ptr(),
9929            ))
9930        }
9931    }
9932
9933    pub fn set_name(&mut self, value: &str) {
9934        let value = std::ffi::CString::new(value).unwrap_or_default();
9935        // SAFETY: the pointer outlives the call.
9936        unsafe { ffi::whiteout_m3_M3VolumeMaterial_set_name(self.raw.as_ptr(), value.as_ptr()) }
9937    }
9938
9939    /// Blend mode
9940    pub fn blend_mode(&self) -> u32 {
9941        // SAFETY: plain scalar read through a live handle.
9942        unsafe { ffi::whiteout_m3_M3VolumeMaterial_get_blendMode(self.raw.as_ptr()) }
9943    }
9944
9945    pub fn set_blend_mode(&mut self, value: u32) {
9946        // SAFETY: plain scalar write through a live handle.
9947        unsafe { ffi::whiteout_m3_M3VolumeMaterial_set_blendMode(self.raw.as_ptr(), value) }
9948    }
9949
9950    /// Density falloff type
9951    pub fn falloff_type(&self) -> VolumeFalloffType {
9952        // SAFETY: scalar read; the discriminant is validated below.
9953        unsafe { ffi::whiteout_m3_M3VolumeMaterial_get_falloffType(self.raw.as_ptr()) }
9954            .try_into()
9955            .expect("unknown enum discriminant from the native library")
9956    }
9957
9958    pub fn set_falloff_type(&mut self, value: VolumeFalloffType) {
9959        // SAFETY: scalar write through a live handle.
9960        unsafe {
9961            ffi::whiteout_m3_M3VolumeMaterial_set_falloffType(self.raw.as_ptr(), value as i32)
9962        }
9963    }
9964
9965    /// Animated density
9966    /// Borrows the field in place — no copy, no allocation.
9967    pub fn density(&self) -> crate::support::Ref<'_, AnimRefF32> {
9968        // SAFETY: an interior pointer into `self`, valid for this
9969        // borrow and never freed by the `Ref`.
9970        unsafe {
9971            crate::support::Ref::new(AnimRefF32 {
9972                raw: core::ptr::NonNull::new_unchecked(
9973                    ffi::whiteout_m3_M3VolumeMaterial_get_density(self.raw.as_ptr()),
9974                ),
9975            })
9976        }
9977    }
9978
9979    pub fn density_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
9980        // SAFETY: as above; `&mut self` guarantees exclusivity.
9981        unsafe {
9982            crate::support::RefMut::new(AnimRefF32 {
9983                raw: core::ptr::NonNull::new_unchecked(
9984                    ffi::whiteout_m3_M3VolumeMaterial_get_density(self.raw.as_ptr()),
9985                ),
9986            })
9987        }
9988    }
9989
9990    /// Alpha test threshold
9991    pub fn alpha_threshold(&self) -> u32 {
9992        // SAFETY: plain scalar read through a live handle.
9993        unsafe { ffi::whiteout_m3_M3VolumeMaterial_get_alphaThreshold(self.raw.as_ptr()) }
9994    }
9995
9996    pub fn set_alpha_threshold(&mut self, value: u32) {
9997        // SAFETY: plain scalar write through a live handle.
9998        unsafe { ffi::whiteout_m3_M3VolumeMaterial_set_alphaThreshold(self.raw.as_ptr(), value) }
9999    }
10000}
10001
10002impl Default for VolumeMaterial {
10003    fn default() -> Self {
10004        Self::new()
10005    }
10006}
10007
10008/// HAI_ — Hair material (defunct, v0, 116 bytes)
10009///
10010/// Anisotropic hair rendering material with specular shift and AO. Always null in observed corpus data.
10011pub struct HairMaterial {
10012    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3HairMaterial>,
10013}
10014
10015impl Drop for HairMaterial {
10016    fn drop(&mut self) {
10017        // SAFETY: `raw` came from a native constructor and Drop runs once.
10018        unsafe { ffi::whiteout_m3_M3HairMaterial_delete(self.raw.as_ptr()) }
10019    }
10020}
10021
10022impl HairMaterial {
10023    /// # Safety
10024    /// `raw` must be a live handle this value takes ownership of.
10025    #[allow(dead_code)] // used by whichever methods return this type
10026    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3HairMaterial) -> Option<Self> {
10027        core::ptr::NonNull::new(raw).map(|raw| HairMaterial { raw })
10028    }
10029}
10030
10031// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
10032// is deliberately NOT implemented — the C++ types make no documented
10033// guarantee about concurrent use, and claiming one we haven't verified
10034// would be unsound. See `@bind thread_safe` in the plan.
10035unsafe impl Send for HairMaterial {}
10036
10037impl core::fmt::Debug for HairMaterial {
10038    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
10039        f.debug_struct("HairMaterial").finish_non_exhaustive()
10040    }
10041}
10042
10043impl HairMaterial {
10044    /// # Panics
10045    /// Panics if the native allocation fails.
10046    pub fn new() -> Self {
10047        // SAFETY: the native constructor returns a live handle; a null here
10048        // means the library is unusable.
10049        unsafe {
10050            let raw = ffi::whiteout_m3_M3HairMaterial_new();
10051            Self::from_raw(raw).expect("native HairMaterial allocation failed")
10052        }
10053    }
10054
10055    /// Material name (`Ref<CHAR>`)
10056    pub fn name(&self) -> String {
10057        // SAFETY: the native side hands over an owned CString.
10058        unsafe {
10059            crate::support::take_string(ffi::whiteout_m3_M3HairMaterial_get_name(self.raw.as_ptr()))
10060        }
10061    }
10062
10063    pub fn set_name(&mut self, value: &str) {
10064        let value = std::ffi::CString::new(value).unwrap_or_default();
10065        // SAFETY: the pointer outlives the call.
10066        unsafe { ffi::whiteout_m3_M3HairMaterial_set_name(self.raw.as_ptr(), value.as_ptr()) }
10067    }
10068
10069    /// Primary specular shift
10070    pub fn shift_primary(&self) -> f32 {
10071        // SAFETY: plain scalar read through a live handle.
10072        unsafe { ffi::whiteout_m3_M3HairMaterial_get_shiftPrimary(self.raw.as_ptr()) }
10073    }
10074
10075    pub fn set_shift_primary(&mut self, value: f32) {
10076        // SAFETY: plain scalar write through a live handle.
10077        unsafe { ffi::whiteout_m3_M3HairMaterial_set_shiftPrimary(self.raw.as_ptr(), value) }
10078    }
10079
10080    /// Secondary specular shift
10081    pub fn shift_secondary(&self) -> f32 {
10082        // SAFETY: plain scalar read through a live handle.
10083        unsafe { ffi::whiteout_m3_M3HairMaterial_get_shiftSecondary(self.raw.as_ptr()) }
10084    }
10085
10086    pub fn set_shift_secondary(&mut self, value: f32) {
10087        // SAFETY: plain scalar write through a live handle.
10088        unsafe { ffi::whiteout_m3_M3HairMaterial_set_shiftSecondary(self.raw.as_ptr(), value) }
10089    }
10090
10091    /// Animated diffuse tint
10092    /// Borrows the field in place — no copy, no allocation.
10093    pub fn color_diffuse(&self) -> crate::support::Ref<'_, AnimRefM3ColorBGRA> {
10094        // SAFETY: an interior pointer into `self`, valid for this
10095        // borrow and never freed by the `Ref`.
10096        unsafe {
10097            crate::support::Ref::new(AnimRefM3ColorBGRA {
10098                raw: core::ptr::NonNull::new_unchecked(
10099                    ffi::whiteout_m3_M3HairMaterial_get_colorDiffuse(self.raw.as_ptr()),
10100                ),
10101            })
10102        }
10103    }
10104
10105    pub fn color_diffuse_mut(&mut self) -> crate::support::RefMut<'_, AnimRefM3ColorBGRA> {
10106        // SAFETY: as above; `&mut self` guarantees exclusivity.
10107        unsafe {
10108            crate::support::RefMut::new(AnimRefM3ColorBGRA {
10109                raw: core::ptr::NonNull::new_unchecked(
10110                    ffi::whiteout_m3_M3HairMaterial_get_colorDiffuse(self.raw.as_ptr()),
10111                ),
10112            })
10113        }
10114    }
10115
10116    /// Animated specular tint
10117    /// Borrows the field in place — no copy, no allocation.
10118    pub fn color_spec(&self) -> crate::support::Ref<'_, AnimRefM3ColorBGRA> {
10119        // SAFETY: an interior pointer into `self`, valid for this
10120        // borrow and never freed by the `Ref`.
10121        unsafe {
10122            crate::support::Ref::new(AnimRefM3ColorBGRA {
10123                raw: core::ptr::NonNull::new_unchecked(
10124                    ffi::whiteout_m3_M3HairMaterial_get_colorSpec(self.raw.as_ptr()),
10125                ),
10126            })
10127        }
10128    }
10129
10130    pub fn color_spec_mut(&mut self) -> crate::support::RefMut<'_, AnimRefM3ColorBGRA> {
10131        // SAFETY: as above; `&mut self` guarantees exclusivity.
10132        unsafe {
10133            crate::support::RefMut::new(AnimRefM3ColorBGRA {
10134                raw: core::ptr::NonNull::new_unchecked(
10135                    ffi::whiteout_m3_M3HairMaterial_get_colorSpec(self.raw.as_ptr()),
10136                ),
10137            })
10138        }
10139    }
10140
10141    /// Primary specular exponent
10142    pub fn spec_exponent_0(&self) -> f32 {
10143        // SAFETY: plain scalar read through a live handle.
10144        unsafe { ffi::whiteout_m3_M3HairMaterial_get_specExponent0(self.raw.as_ptr()) }
10145    }
10146
10147    pub fn set_spec_exponent_0(&mut self, value: f32) {
10148        // SAFETY: plain scalar write through a live handle.
10149        unsafe { ffi::whiteout_m3_M3HairMaterial_set_specExponent0(self.raw.as_ptr(), value) }
10150    }
10151
10152    /// Secondary specular exponent
10153    pub fn spec_exponent_1(&self) -> f32 {
10154        // SAFETY: plain scalar read through a live handle.
10155        unsafe { ffi::whiteout_m3_M3HairMaterial_get_specExponent1(self.raw.as_ptr()) }
10156    }
10157
10158    pub fn set_spec_exponent_1(&mut self, value: f32) {
10159        // SAFETY: plain scalar write through a live handle.
10160        unsafe { ffi::whiteout_m3_M3HairMaterial_set_specExponent1(self.raw.as_ptr(), value) }
10161    }
10162}
10163
10164impl Default for HairMaterial {
10165    fn default() -> Self {
10166        Self::new()
10167    }
10168}
10169
10170/// VON_ — Volume noise material (v0, 268 bytes)
10171///
10172/// Volumetric noise-based rendering material with animated density, falloff, scroll rate, position, scale, and rotation. Used for gas/smoke/cloud effects.
10173pub struct VolumeNoiseMaterial {
10174    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3VolumeNoiseMaterial>,
10175}
10176
10177impl Drop for VolumeNoiseMaterial {
10178    fn drop(&mut self) {
10179        // SAFETY: `raw` came from a native constructor and Drop runs once.
10180        unsafe { ffi::whiteout_m3_M3VolumeNoiseMaterial_delete(self.raw.as_ptr()) }
10181    }
10182}
10183
10184impl VolumeNoiseMaterial {
10185    /// # Safety
10186    /// `raw` must be a live handle this value takes ownership of.
10187    #[allow(dead_code)] // used by whichever methods return this type
10188    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3VolumeNoiseMaterial) -> Option<Self> {
10189        core::ptr::NonNull::new(raw).map(|raw| VolumeNoiseMaterial { raw })
10190    }
10191}
10192
10193// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
10194// is deliberately NOT implemented — the C++ types make no documented
10195// guarantee about concurrent use, and claiming one we haven't verified
10196// would be unsound. See `@bind thread_safe` in the plan.
10197unsafe impl Send for VolumeNoiseMaterial {}
10198
10199impl core::fmt::Debug for VolumeNoiseMaterial {
10200    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
10201        f.debug_struct("VolumeNoiseMaterial")
10202            .finish_non_exhaustive()
10203    }
10204}
10205
10206impl VolumeNoiseMaterial {
10207    /// # Panics
10208    /// Panics if the native allocation fails.
10209    pub fn new() -> Self {
10210        // SAFETY: the native constructor returns a live handle; a null here
10211        // means the library is unusable.
10212        unsafe {
10213            let raw = ffi::whiteout_m3_M3VolumeNoiseMaterial_new();
10214            Self::from_raw(raw).expect("native VolumeNoiseMaterial allocation failed")
10215        }
10216    }
10217
10218    /// Material name (`Ref<CHAR>`)
10219    pub fn name(&self) -> String {
10220        // SAFETY: the native side hands over an owned CString.
10221        unsafe {
10222            crate::support::take_string(ffi::whiteout_m3_M3VolumeNoiseMaterial_get_name(
10223                self.raw.as_ptr(),
10224            ))
10225        }
10226    }
10227
10228    pub fn set_name(&mut self, value: &str) {
10229        let value = std::ffi::CString::new(value).unwrap_or_default();
10230        // SAFETY: the pointer outlives the call.
10231        unsafe {
10232            ffi::whiteout_m3_M3VolumeNoiseMaterial_set_name(self.raw.as_ptr(), value.as_ptr())
10233        }
10234    }
10235
10236    /// Density falloff type
10237    pub fn falloff_type(&self) -> VolumeFalloffType {
10238        // SAFETY: scalar read; the discriminant is validated below.
10239        unsafe { ffi::whiteout_m3_M3VolumeNoiseMaterial_get_falloffType(self.raw.as_ptr()) }
10240            .try_into()
10241            .expect("unknown enum discriminant from the native library")
10242    }
10243
10244    pub fn set_falloff_type(&mut self, value: VolumeFalloffType) {
10245        // SAFETY: scalar write through a live handle.
10246        unsafe {
10247            ffi::whiteout_m3_M3VolumeNoiseMaterial_set_falloffType(self.raw.as_ptr(), value as i32)
10248        }
10249    }
10250
10251    /// Camera position mode (inside/outside)
10252    pub fn draw_transparency(&self) -> VolumeNoiseCameraMode {
10253        // SAFETY: scalar read; the discriminant is validated below.
10254        unsafe { ffi::whiteout_m3_M3VolumeNoiseMaterial_get_drawTransparency(self.raw.as_ptr()) }
10255            .try_into()
10256            .expect("unknown enum discriminant from the native library")
10257    }
10258
10259    pub fn set_draw_transparency(&mut self, value: VolumeNoiseCameraMode) {
10260        // SAFETY: scalar write through a live handle.
10261        unsafe {
10262            ffi::whiteout_m3_M3VolumeNoiseMaterial_set_drawTransparency(
10263                self.raw.as_ptr(),
10264                value as i32,
10265            )
10266        }
10267    }
10268
10269    /// Animated density
10270    /// Borrows the field in place — no copy, no allocation.
10271    pub fn density(&self) -> crate::support::Ref<'_, AnimRefF32> {
10272        // SAFETY: an interior pointer into `self`, valid for this
10273        // borrow and never freed by the `Ref`.
10274        unsafe {
10275            crate::support::Ref::new(AnimRefF32 {
10276                raw: core::ptr::NonNull::new_unchecked(
10277                    ffi::whiteout_m3_M3VolumeNoiseMaterial_get_density(self.raw.as_ptr()),
10278                ),
10279            })
10280        }
10281    }
10282
10283    pub fn density_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
10284        // SAFETY: as above; `&mut self` guarantees exclusivity.
10285        unsafe {
10286            crate::support::RefMut::new(AnimRefF32 {
10287                raw: core::ptr::NonNull::new_unchecked(
10288                    ffi::whiteout_m3_M3VolumeNoiseMaterial_get_density(self.raw.as_ptr()),
10289                ),
10290            })
10291        }
10292    }
10293
10294    /// Animated near-plane clip
10295    /// Borrows the field in place — no copy, no allocation.
10296    pub fn near_plane(&self) -> crate::support::Ref<'_, AnimRefF32> {
10297        // SAFETY: an interior pointer into `self`, valid for this
10298        // borrow and never freed by the `Ref`.
10299        unsafe {
10300            crate::support::Ref::new(AnimRefF32 {
10301                raw: core::ptr::NonNull::new_unchecked(
10302                    ffi::whiteout_m3_M3VolumeNoiseMaterial_get_nearPlane(self.raw.as_ptr()),
10303                ),
10304            })
10305        }
10306    }
10307
10308    pub fn near_plane_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
10309        // SAFETY: as above; `&mut self` guarantees exclusivity.
10310        unsafe {
10311            crate::support::RefMut::new(AnimRefF32 {
10312                raw: core::ptr::NonNull::new_unchecked(
10313                    ffi::whiteout_m3_M3VolumeNoiseMaterial_get_nearPlane(self.raw.as_ptr()),
10314                ),
10315            })
10316        }
10317    }
10318
10319    /// Animated falloff distance
10320    /// Borrows the field in place — no copy, no allocation.
10321    pub fn falloff(&self) -> crate::support::Ref<'_, AnimRefF32> {
10322        // SAFETY: an interior pointer into `self`, valid for this
10323        // borrow and never freed by the `Ref`.
10324        unsafe {
10325            crate::support::Ref::new(AnimRefF32 {
10326                raw: core::ptr::NonNull::new_unchecked(
10327                    ffi::whiteout_m3_M3VolumeNoiseMaterial_get_falloff(self.raw.as_ptr()),
10328                ),
10329            })
10330        }
10331    }
10332
10333    pub fn falloff_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
10334        // SAFETY: as above; `&mut self` guarantees exclusivity.
10335        unsafe {
10336            crate::support::RefMut::new(AnimRefF32 {
10337                raw: core::ptr::NonNull::new_unchecked(
10338                    ffi::whiteout_m3_M3VolumeNoiseMaterial_get_falloff(self.raw.as_ptr()),
10339                ),
10340            })
10341        }
10342    }
10343
10344    /// Animated noise scroll rate
10345    /// Borrows the field in place — no copy, no allocation.
10346    pub fn scroll_rate(&self) -> crate::support::Ref<'_, AnimRefVector3f> {
10347        // SAFETY: an interior pointer into `self`, valid for this
10348        // borrow and never freed by the `Ref`.
10349        unsafe {
10350            crate::support::Ref::new(AnimRefVector3f {
10351                raw: core::ptr::NonNull::new_unchecked(
10352                    ffi::whiteout_m3_M3VolumeNoiseMaterial_get_scrollRate(self.raw.as_ptr()),
10353                ),
10354            })
10355        }
10356    }
10357
10358    pub fn scroll_rate_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector3f> {
10359        // SAFETY: as above; `&mut self` guarantees exclusivity.
10360        unsafe {
10361            crate::support::RefMut::new(AnimRefVector3f {
10362                raw: core::ptr::NonNull::new_unchecked(
10363                    ffi::whiteout_m3_M3VolumeNoiseMaterial_get_scrollRate(self.raw.as_ptr()),
10364                ),
10365            })
10366        }
10367    }
10368
10369    /// Animated volume position
10370    /// Borrows the field in place — no copy, no allocation.
10371    pub fn position(&self) -> crate::support::Ref<'_, AnimRefVector3f> {
10372        // SAFETY: an interior pointer into `self`, valid for this
10373        // borrow and never freed by the `Ref`.
10374        unsafe {
10375            crate::support::Ref::new(AnimRefVector3f {
10376                raw: core::ptr::NonNull::new_unchecked(
10377                    ffi::whiteout_m3_M3VolumeNoiseMaterial_get_position(self.raw.as_ptr()),
10378                ),
10379            })
10380        }
10381    }
10382
10383    pub fn position_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector3f> {
10384        // SAFETY: as above; `&mut self` guarantees exclusivity.
10385        unsafe {
10386            crate::support::RefMut::new(AnimRefVector3f {
10387                raw: core::ptr::NonNull::new_unchecked(
10388                    ffi::whiteout_m3_M3VolumeNoiseMaterial_get_position(self.raw.as_ptr()),
10389                ),
10390            })
10391        }
10392    }
10393
10394    /// Animated volume scale
10395    /// Borrows the field in place — no copy, no allocation.
10396    pub fn scale(&self) -> crate::support::Ref<'_, AnimRefVector3f> {
10397        // SAFETY: an interior pointer into `self`, valid for this
10398        // borrow and never freed by the `Ref`.
10399        unsafe {
10400            crate::support::Ref::new(AnimRefVector3f {
10401                raw: core::ptr::NonNull::new_unchecked(
10402                    ffi::whiteout_m3_M3VolumeNoiseMaterial_get_scale(self.raw.as_ptr()),
10403                ),
10404            })
10405        }
10406    }
10407
10408    pub fn scale_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector3f> {
10409        // SAFETY: as above; `&mut self` guarantees exclusivity.
10410        unsafe {
10411            crate::support::RefMut::new(AnimRefVector3f {
10412                raw: core::ptr::NonNull::new_unchecked(
10413                    ffi::whiteout_m3_M3VolumeNoiseMaterial_get_scale(self.raw.as_ptr()),
10414                ),
10415            })
10416        }
10417    }
10418
10419    /// Animated volume rotation
10420    /// Borrows the field in place — no copy, no allocation.
10421    pub fn rotation(&self) -> crate::support::Ref<'_, AnimRefVector3f> {
10422        // SAFETY: an interior pointer into `self`, valid for this
10423        // borrow and never freed by the `Ref`.
10424        unsafe {
10425            crate::support::Ref::new(AnimRefVector3f {
10426                raw: core::ptr::NonNull::new_unchecked(
10427                    ffi::whiteout_m3_M3VolumeNoiseMaterial_get_rotation(self.raw.as_ptr()),
10428                ),
10429            })
10430        }
10431    }
10432
10433    pub fn rotation_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector3f> {
10434        // SAFETY: as above; `&mut self` guarantees exclusivity.
10435        unsafe {
10436            crate::support::RefMut::new(AnimRefVector3f {
10437                raw: core::ptr::NonNull::new_unchecked(
10438                    ffi::whiteout_m3_M3VolumeNoiseMaterial_get_rotation(self.raw.as_ptr()),
10439                ),
10440            })
10441        }
10442    }
10443
10444    /// Alpha test threshold
10445    pub fn alpha_threshold(&self) -> u32 {
10446        // SAFETY: plain scalar read through a live handle.
10447        unsafe { ffi::whiteout_m3_M3VolumeNoiseMaterial_get_alphaThreshold(self.raw.as_ptr()) }
10448    }
10449
10450    pub fn set_alpha_threshold(&mut self, value: u32) {
10451        // SAFETY: plain scalar write through a live handle.
10452        unsafe {
10453            ffi::whiteout_m3_M3VolumeNoiseMaterial_set_alphaThreshold(self.raw.as_ptr(), value)
10454        }
10455    }
10456
10457    /// Volume noise material flags
10458    pub fn flags(&self) -> VolumeNoiseMaterialFlag {
10459        // SAFETY: scalar read; the discriminant is validated below.
10460        unsafe { ffi::whiteout_m3_M3VolumeNoiseMaterial_get_flags(self.raw.as_ptr()) }
10461            .try_into()
10462            .expect("unknown enum discriminant from the native library")
10463    }
10464
10465    pub fn set_flags(&mut self, value: VolumeNoiseMaterialFlag) {
10466        // SAFETY: scalar write through a live handle.
10467        unsafe { ffi::whiteout_m3_M3VolumeNoiseMaterial_set_flags(self.raw.as_ptr(), value as i32) }
10468    }
10469}
10470
10471impl Default for VolumeNoiseMaterial {
10472    fn default() -> Self {
10473        Self::new()
10474    }
10475}
10476
10477/// CREP — Creep material (v0–v1, 28 bytes)
10478///
10479/// Material for Zerg creep rendering with a mask map and creep-low parameter.
10480pub struct CreepMaterial {
10481    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3CreepMaterial>,
10482}
10483
10484impl Drop for CreepMaterial {
10485    fn drop(&mut self) {
10486        // SAFETY: `raw` came from a native constructor and Drop runs once.
10487        unsafe { ffi::whiteout_m3_M3CreepMaterial_delete(self.raw.as_ptr()) }
10488    }
10489}
10490
10491impl CreepMaterial {
10492    /// # Safety
10493    /// `raw` must be a live handle this value takes ownership of.
10494    #[allow(dead_code)] // used by whichever methods return this type
10495    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3CreepMaterial) -> Option<Self> {
10496        core::ptr::NonNull::new(raw).map(|raw| CreepMaterial { raw })
10497    }
10498}
10499
10500// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
10501// is deliberately NOT implemented — the C++ types make no documented
10502// guarantee about concurrent use, and claiming one we haven't verified
10503// would be unsound. See `@bind thread_safe` in the plan.
10504unsafe impl Send for CreepMaterial {}
10505
10506impl core::fmt::Debug for CreepMaterial {
10507    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
10508        f.debug_struct("CreepMaterial").finish_non_exhaustive()
10509    }
10510}
10511
10512impl CreepMaterial {
10513    /// # Panics
10514    /// Panics if the native allocation fails.
10515    pub fn new() -> Self {
10516        // SAFETY: the native constructor returns a live handle; a null here
10517        // means the library is unusable.
10518        unsafe {
10519            let raw = ffi::whiteout_m3_M3CreepMaterial_new();
10520            Self::from_raw(raw).expect("native CreepMaterial allocation failed")
10521        }
10522    }
10523
10524    /// Material name (`Ref<CHAR>`)
10525    pub fn name(&self) -> String {
10526        // SAFETY: the native side hands over an owned CString.
10527        unsafe {
10528            crate::support::take_string(ffi::whiteout_m3_M3CreepMaterial_get_name(
10529                self.raw.as_ptr(),
10530            ))
10531        }
10532    }
10533
10534    pub fn set_name(&mut self, value: &str) {
10535        let value = std::ffi::CString::new(value).unwrap_or_default();
10536        // SAFETY: the pointer outlives the call.
10537        unsafe { ffi::whiteout_m3_M3CreepMaterial_set_name(self.raw.as_ptr(), value.as_ptr()) }
10538    }
10539
10540    /// Creep low parameter
10541    pub fn creep_low(&self) -> u32 {
10542        // SAFETY: plain scalar read through a live handle.
10543        unsafe { ffi::whiteout_m3_M3CreepMaterial_get_creepLow(self.raw.as_ptr()) }
10544    }
10545
10546    pub fn set_creep_low(&mut self, value: u32) {
10547        // SAFETY: plain scalar write through a live handle.
10548        unsafe { ffi::whiteout_m3_M3CreepMaterial_set_creepLow(self.raw.as_ptr(), value) }
10549    }
10550}
10551
10552impl Default for CreepMaterial {
10553    fn default() -> Self {
10554        Self::new()
10555    }
10556}
10557
10558/// STBM — Splat terrain bake material (v0, 48 bytes)
10559///
10560/// Material for baked terrain splat rendering with diffuse, normal, and specular texture layers.
10561pub struct STBMaterial {
10562    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3STBMaterial>,
10563}
10564
10565impl Drop for STBMaterial {
10566    fn drop(&mut self) {
10567        // SAFETY: `raw` came from a native constructor and Drop runs once.
10568        unsafe { ffi::whiteout_m3_M3STBMaterial_delete(self.raw.as_ptr()) }
10569    }
10570}
10571
10572impl STBMaterial {
10573    /// # Safety
10574    /// `raw` must be a live handle this value takes ownership of.
10575    #[allow(dead_code)] // used by whichever methods return this type
10576    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3STBMaterial) -> Option<Self> {
10577        core::ptr::NonNull::new(raw).map(|raw| STBMaterial { raw })
10578    }
10579}
10580
10581// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
10582// is deliberately NOT implemented — the C++ types make no documented
10583// guarantee about concurrent use, and claiming one we haven't verified
10584// would be unsound. See `@bind thread_safe` in the plan.
10585unsafe impl Send for STBMaterial {}
10586
10587impl core::fmt::Debug for STBMaterial {
10588    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
10589        f.debug_struct("STBMaterial").finish_non_exhaustive()
10590    }
10591}
10592
10593impl STBMaterial {
10594    /// # Panics
10595    /// Panics if the native allocation fails.
10596    pub fn new() -> Self {
10597        // SAFETY: the native constructor returns a live handle; a null here
10598        // means the library is unusable.
10599        unsafe {
10600            let raw = ffi::whiteout_m3_M3STBMaterial_new();
10601            Self::from_raw(raw).expect("native STBMaterial allocation failed")
10602        }
10603    }
10604
10605    /// Material name (`Ref<CHAR>`)
10606    pub fn name(&self) -> String {
10607        // SAFETY: the native side hands over an owned CString.
10608        unsafe {
10609            crate::support::take_string(ffi::whiteout_m3_M3STBMaterial_get_name(self.raw.as_ptr()))
10610        }
10611    }
10612
10613    pub fn set_name(&mut self, value: &str) {
10614        let value = std::ffi::CString::new(value).unwrap_or_default();
10615        // SAFETY: the pointer outlives the call.
10616        unsafe { ffi::whiteout_m3_M3STBMaterial_set_name(self.raw.as_ptr(), value.as_ptr()) }
10617    }
10618}
10619
10620impl Default for STBMaterial {
10621    fn default() -> Self {
10622        Self::new()
10623    }
10624}
10625
10626/// REF_ — Reflection material (v0–v3, 84–160 bytes)
10627///
10628/// Planar or cube-map reflection material with animated reflection/displacement strength, blur, and multiple texture layers.
10629pub struct ReflectionMaterial {
10630    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3ReflectionMaterial>,
10631}
10632
10633impl Drop for ReflectionMaterial {
10634    fn drop(&mut self) {
10635        // SAFETY: `raw` came from a native constructor and Drop runs once.
10636        unsafe { ffi::whiteout_m3_M3ReflectionMaterial_delete(self.raw.as_ptr()) }
10637    }
10638}
10639
10640impl ReflectionMaterial {
10641    /// # Safety
10642    /// `raw` must be a live handle this value takes ownership of.
10643    #[allow(dead_code)] // used by whichever methods return this type
10644    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3ReflectionMaterial) -> Option<Self> {
10645        core::ptr::NonNull::new(raw).map(|raw| ReflectionMaterial { raw })
10646    }
10647}
10648
10649// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
10650// is deliberately NOT implemented — the C++ types make no documented
10651// guarantee about concurrent use, and claiming one we haven't verified
10652// would be unsound. See `@bind thread_safe` in the plan.
10653unsafe impl Send for ReflectionMaterial {}
10654
10655impl core::fmt::Debug for ReflectionMaterial {
10656    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
10657        f.debug_struct("ReflectionMaterial").finish_non_exhaustive()
10658    }
10659}
10660
10661impl ReflectionMaterial {
10662    /// # Panics
10663    /// Panics if the native allocation fails.
10664    pub fn new() -> Self {
10665        // SAFETY: the native constructor returns a live handle; a null here
10666        // means the library is unusable.
10667        unsafe {
10668            let raw = ffi::whiteout_m3_M3ReflectionMaterial_new();
10669            Self::from_raw(raw).expect("native ReflectionMaterial allocation failed")
10670        }
10671    }
10672
10673    /// Material name (`Ref<CHAR>`)
10674    pub fn name(&self) -> String {
10675        // SAFETY: the native side hands over an owned CString.
10676        unsafe {
10677            crate::support::take_string(ffi::whiteout_m3_M3ReflectionMaterial_get_name(
10678                self.raw.as_ptr(),
10679            ))
10680        }
10681    }
10682
10683    pub fn set_name(&mut self, value: &str) {
10684        let value = std::ffi::CString::new(value).unwrap_or_default();
10685        // SAFETY: the pointer outlives the call.
10686        unsafe { ffi::whiteout_m3_M3ReflectionMaterial_set_name(self.raw.as_ptr(), value.as_ptr()) }
10687    }
10688
10689    /// Unknown field
10690    pub fn unknown(&self) -> u32 {
10691        // SAFETY: plain scalar read through a live handle.
10692        unsafe { ffi::whiteout_m3_M3ReflectionMaterial_get_unknown(self.raw.as_ptr()) }
10693    }
10694
10695    pub fn set_unknown(&mut self, value: u32) {
10696        // SAFETY: plain scalar write through a live handle.
10697        unsafe { ffi::whiteout_m3_M3ReflectionMaterial_set_unknown(self.raw.as_ptr(), value) }
10698    }
10699
10700    /// Animated reflection strength (v2+)
10701    /// Borrows the field in place — no copy, no allocation.
10702    pub fn reflection_strength(&self) -> crate::support::Ref<'_, AnimRefF32> {
10703        // SAFETY: an interior pointer into `self`, valid for this
10704        // borrow and never freed by the `Ref`.
10705        unsafe {
10706            crate::support::Ref::new(AnimRefF32 {
10707                raw: core::ptr::NonNull::new_unchecked(
10708                    ffi::whiteout_m3_M3ReflectionMaterial_get_reflectionStrength(self.raw.as_ptr()),
10709                ),
10710            })
10711        }
10712    }
10713
10714    pub fn reflection_strength_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
10715        // SAFETY: as above; `&mut self` guarantees exclusivity.
10716        unsafe {
10717            crate::support::RefMut::new(AnimRefF32 {
10718                raw: core::ptr::NonNull::new_unchecked(
10719                    ffi::whiteout_m3_M3ReflectionMaterial_get_reflectionStrength(self.raw.as_ptr()),
10720                ),
10721            })
10722        }
10723    }
10724
10725    /// Animated displacement strength (v2+)
10726    /// Borrows the field in place — no copy, no allocation.
10727    pub fn displacement_strength(&self) -> crate::support::Ref<'_, AnimRefF32> {
10728        // SAFETY: an interior pointer into `self`, valid for this
10729        // borrow and never freed by the `Ref`.
10730        unsafe {
10731            crate::support::Ref::new(AnimRefF32 {
10732                raw: core::ptr::NonNull::new_unchecked(
10733                    ffi::whiteout_m3_M3ReflectionMaterial_get_displacementStrength(
10734                        self.raw.as_ptr(),
10735                    ),
10736                ),
10737            })
10738        }
10739    }
10740
10741    pub fn displacement_strength_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
10742        // SAFETY: as above; `&mut self` guarantees exclusivity.
10743        unsafe {
10744            crate::support::RefMut::new(AnimRefF32 {
10745                raw: core::ptr::NonNull::new_unchecked(
10746                    ffi::whiteout_m3_M3ReflectionMaterial_get_displacementStrength(
10747                        self.raw.as_ptr(),
10748                    ),
10749                ),
10750            })
10751        }
10752    }
10753
10754    /// Animated reflection offset (v2+)
10755    /// Borrows the field in place — no copy, no allocation.
10756    pub fn reflection_offset(&self) -> crate::support::Ref<'_, AnimRefF32> {
10757        // SAFETY: an interior pointer into `self`, valid for this
10758        // borrow and never freed by the `Ref`.
10759        unsafe {
10760            crate::support::Ref::new(AnimRefF32 {
10761                raw: core::ptr::NonNull::new_unchecked(
10762                    ffi::whiteout_m3_M3ReflectionMaterial_get_reflectionOffset(self.raw.as_ptr()),
10763                ),
10764            })
10765        }
10766    }
10767
10768    pub fn reflection_offset_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
10769        // SAFETY: as above; `&mut self` guarantees exclusivity.
10770        unsafe {
10771            crate::support::RefMut::new(AnimRefF32 {
10772                raw: core::ptr::NonNull::new_unchecked(
10773                    ffi::whiteout_m3_M3ReflectionMaterial_get_reflectionOffset(self.raw.as_ptr()),
10774                ),
10775            })
10776        }
10777    }
10778
10779    /// Animated blur angle (v2+)
10780    /// Borrows the field in place — no copy, no allocation.
10781    pub fn blur_angle(&self) -> crate::support::Ref<'_, AnimRefF32> {
10782        // SAFETY: an interior pointer into `self`, valid for this
10783        // borrow and never freed by the `Ref`.
10784        unsafe {
10785            crate::support::Ref::new(AnimRefF32 {
10786                raw: core::ptr::NonNull::new_unchecked(
10787                    ffi::whiteout_m3_M3ReflectionMaterial_get_blurAngle(self.raw.as_ptr()),
10788                ),
10789            })
10790        }
10791    }
10792
10793    pub fn blur_angle_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
10794        // SAFETY: as above; `&mut self` guarantees exclusivity.
10795        unsafe {
10796            crate::support::RefMut::new(AnimRefF32 {
10797                raw: core::ptr::NonNull::new_unchecked(
10798                    ffi::whiteout_m3_M3ReflectionMaterial_get_blurAngle(self.raw.as_ptr()),
10799                ),
10800            })
10801        }
10802    }
10803
10804    /// Animated max blur distance (v2+)
10805    /// Borrows the field in place — no copy, no allocation.
10806    pub fn blur_distance_max(&self) -> crate::support::Ref<'_, AnimRefF32> {
10807        // SAFETY: an interior pointer into `self`, valid for this
10808        // borrow and never freed by the `Ref`.
10809        unsafe {
10810            crate::support::Ref::new(AnimRefF32 {
10811                raw: core::ptr::NonNull::new_unchecked(
10812                    ffi::whiteout_m3_M3ReflectionMaterial_get_blurDistanceMax(self.raw.as_ptr()),
10813                ),
10814            })
10815        }
10816    }
10817
10818    pub fn blur_distance_max_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
10819        // SAFETY: as above; `&mut self` guarantees exclusivity.
10820        unsafe {
10821            crate::support::RefMut::new(AnimRefF32 {
10822                raw: core::ptr::NonNull::new_unchecked(
10823                    ffi::whiteout_m3_M3ReflectionMaterial_get_blurDistanceMax(self.raw.as_ptr()),
10824                ),
10825            })
10826        }
10827    }
10828
10829    /// Reflection flags (v2+)
10830    pub fn flags(&self) -> ReflectionMaterialFlag {
10831        // SAFETY: scalar read; a flag set accepts any bits.
10832        ReflectionMaterialFlag(unsafe {
10833            ffi::whiteout_m3_M3ReflectionMaterial_get_flags(self.raw.as_ptr())
10834        })
10835    }
10836
10837    pub fn set_flags(&mut self, value: ReflectionMaterialFlag) {
10838        // SAFETY: scalar write through a live handle.
10839        unsafe { ffi::whiteout_m3_M3ReflectionMaterial_set_flags(self.raw.as_ptr(), value.0) }
10840    }
10841
10842    /// Unknown field
10843    pub fn unknown_2(&self) -> u32 {
10844        // SAFETY: plain scalar read through a live handle.
10845        unsafe { ffi::whiteout_m3_M3ReflectionMaterial_get_unknown2(self.raw.as_ptr()) }
10846    }
10847
10848    pub fn set_unknown_2(&mut self, value: u32) {
10849        // SAFETY: plain scalar write through a live handle.
10850        unsafe { ffi::whiteout_m3_M3ReflectionMaterial_set_unknown2(self.raw.as_ptr(), value) }
10851    }
10852}
10853
10854impl Default for ReflectionMaterial {
10855    fn default() -> Self {
10856        Self::new()
10857    }
10858}
10859
10860/// LFSB — Sub-flare element (v0–v2, 56 bytes)
10861///
10862/// A single flare element within a LensFlare material, with position, size, scale, fade, color, and offset parameters.
10863pub struct SubFlare {
10864    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3SubFlare>,
10865}
10866
10867impl Drop for SubFlare {
10868    fn drop(&mut self) {
10869        // SAFETY: `raw` came from a native constructor and Drop runs once.
10870        unsafe { ffi::whiteout_m3_M3SubFlare_delete(self.raw.as_ptr()) }
10871    }
10872}
10873
10874impl SubFlare {
10875    /// # Safety
10876    /// `raw` must be a live handle this value takes ownership of.
10877    #[allow(dead_code)] // used by whichever methods return this type
10878    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3SubFlare) -> Option<Self> {
10879        core::ptr::NonNull::new(raw).map(|raw| SubFlare { raw })
10880    }
10881}
10882
10883// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
10884// is deliberately NOT implemented — the C++ types make no documented
10885// guarantee about concurrent use, and claiming one we haven't verified
10886// would be unsound. See `@bind thread_safe` in the plan.
10887unsafe impl Send for SubFlare {}
10888
10889impl core::fmt::Debug for SubFlare {
10890    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
10891        f.debug_struct("SubFlare").finish_non_exhaustive()
10892    }
10893}
10894
10895impl SubFlare {
10896    /// # Panics
10897    /// Panics if the native allocation fails.
10898    pub fn new() -> Self {
10899        // SAFETY: the native constructor returns a live handle; a null here
10900        // means the library is unusable.
10901        unsafe {
10902            let raw = ffi::whiteout_m3_M3SubFlare_new();
10903            Self::from_raw(raw).expect("native SubFlare allocation failed")
10904        }
10905    }
10906
10907    /// Flare element index
10908    pub fn index(&self) -> u32 {
10909        // SAFETY: plain scalar read through a live handle.
10910        unsafe { ffi::whiteout_m3_M3SubFlare_get_index(self.raw.as_ptr()) }
10911    }
10912
10913    pub fn set_index(&mut self, value: u32) {
10914        // SAFETY: plain scalar write through a live handle.
10915        unsafe { ffi::whiteout_m3_M3SubFlare_set_index(self.raw.as_ptr(), value) }
10916    }
10917
10918    /// Position along the flare axis (0–1)
10919    pub fn position(&self) -> f32 {
10920        // SAFETY: plain scalar read through a live handle.
10921        unsafe { ffi::whiteout_m3_M3SubFlare_get_position(self.raw.as_ptr()) }
10922    }
10923
10924    pub fn set_position(&mut self, value: f32) {
10925        // SAFETY: plain scalar write through a live handle.
10926        unsafe { ffi::whiteout_m3_M3SubFlare_set_position(self.raw.as_ptr(), value) }
10927    }
10928
10929    /// Base size (width, height)
10930    pub fn size_xy(&self) -> crate::math::Vector2f {
10931        // SAFETY: the getter returns an interior pointer to a
10932        // layout-identical POD; we copy it out immediately.
10933        unsafe {
10934            *(ffi::whiteout_m3_M3SubFlare_get_sizeXY(self.raw.as_ptr())
10935                as *const crate::math::Vector2f)
10936        }
10937    }
10938
10939    pub fn set_size_xy(&mut self, value: crate::math::Vector2f) {
10940        // SAFETY: as above, in the other direction.
10941        unsafe {
10942            ffi::whiteout_m3_M3SubFlare_set_sizeXY(
10943                self.raw.as_ptr(),
10944                &value as *const crate::math::Vector2f as *const _,
10945            )
10946        }
10947    }
10948
10949    /// Scale multiplier (width, height)
10950    pub fn scale_xy(&self) -> crate::math::Vector2f {
10951        // SAFETY: the getter returns an interior pointer to a
10952        // layout-identical POD; we copy it out immediately.
10953        unsafe {
10954            *(ffi::whiteout_m3_M3SubFlare_get_scaleXY(self.raw.as_ptr())
10955                as *const crate::math::Vector2f)
10956        }
10957    }
10958
10959    pub fn set_scale_xy(&mut self, value: crate::math::Vector2f) {
10960        // SAFETY: as above, in the other direction.
10961        unsafe {
10962            ffi::whiteout_m3_M3SubFlare_set_scaleXY(
10963                self.raw.as_ptr(),
10964                &value as *const crate::math::Vector2f as *const _,
10965            )
10966        }
10967    }
10968
10969    /// Fade-in range (start, end)
10970    pub fn fade_in(&self) -> crate::math::Vector2f {
10971        // SAFETY: the getter returns an interior pointer to a
10972        // layout-identical POD; we copy it out immediately.
10973        unsafe {
10974            *(ffi::whiteout_m3_M3SubFlare_get_fadeIn(self.raw.as_ptr())
10975                as *const crate::math::Vector2f)
10976        }
10977    }
10978
10979    pub fn set_fade_in(&mut self, value: crate::math::Vector2f) {
10980        // SAFETY: as above, in the other direction.
10981        unsafe {
10982            ffi::whiteout_m3_M3SubFlare_set_fadeIn(
10983                self.raw.as_ptr(),
10984                &value as *const crate::math::Vector2f as *const _,
10985            )
10986        }
10987    }
10988
10989    /// Fade-out range (start, end)
10990    pub fn fade_out(&self) -> crate::math::Vector2f {
10991        // SAFETY: the getter returns an interior pointer to a
10992        // layout-identical POD; we copy it out immediately.
10993        unsafe {
10994            *(ffi::whiteout_m3_M3SubFlare_get_fadeOut(self.raw.as_ptr())
10995                as *const crate::math::Vector2f)
10996        }
10997    }
10998
10999    pub fn set_fade_out(&mut self, value: crate::math::Vector2f) {
11000        // SAFETY: as above, in the other direction.
11001        unsafe {
11002            ffi::whiteout_m3_M3SubFlare_set_fadeOut(
11003                self.raw.as_ptr(),
11004                &value as *const crate::math::Vector2f as *const _,
11005            )
11006        }
11007    }
11008
11009    /// Flare color and alpha
11010    /// Borrows the field in place — no copy, no allocation.
11011    pub fn color_alpha(&self) -> crate::support::Ref<'_, ColorBGRA> {
11012        // SAFETY: an interior pointer into `self`, valid for this
11013        // borrow and never freed by the `Ref`.
11014        unsafe {
11015            crate::support::Ref::new(ColorBGRA {
11016                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3SubFlare_get_colorAlpha(
11017                    self.raw.as_ptr(),
11018                )),
11019            })
11020        }
11021    }
11022
11023    pub fn color_alpha_mut(&mut self) -> crate::support::RefMut<'_, ColorBGRA> {
11024        // SAFETY: as above; `&mut self` guarantees exclusivity.
11025        unsafe {
11026            crate::support::RefMut::new(ColorBGRA {
11027                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3SubFlare_get_colorAlpha(
11028                    self.raw.as_ptr(),
11029                )),
11030            })
11031        }
11032    }
11033
11034    /// Whether to face the flare center
11035    pub fn face_center(&self) -> u32 {
11036        // SAFETY: plain scalar read through a live handle.
11037        unsafe { ffi::whiteout_m3_M3SubFlare_get_faceCenter(self.raw.as_ptr()) }
11038    }
11039
11040    pub fn set_face_center(&mut self, value: u32) {
11041        // SAFETY: plain scalar write through a live handle.
11042        unsafe { ffi::whiteout_m3_M3SubFlare_set_faceCenter(self.raw.as_ptr(), value) }
11043    }
11044
11045    /// Offset from flare center
11046    pub fn offset(&self) -> crate::math::Vector2f {
11047        // SAFETY: the getter returns an interior pointer to a
11048        // layout-identical POD; we copy it out immediately.
11049        unsafe {
11050            *(ffi::whiteout_m3_M3SubFlare_get_offset(self.raw.as_ptr())
11051                as *const crate::math::Vector2f)
11052        }
11053    }
11054
11055    pub fn set_offset(&mut self, value: crate::math::Vector2f) {
11056        // SAFETY: as above, in the other direction.
11057        unsafe {
11058            ffi::whiteout_m3_M3SubFlare_set_offset(
11059                self.raw.as_ptr(),
11060                &value as *const crate::math::Vector2f as *const _,
11061            )
11062        }
11063    }
11064}
11065
11066impl Default for SubFlare {
11067    fn default() -> Self {
11068        Self::new()
11069    }
11070}
11071
11072/// LFLR — Lens flare material (v0–v3, 152 bytes)
11073///
11074/// Lens flare effect with animated intensity, color, HDR, size, sub-flare elements, and flipbook texture grid parameters.
11075pub struct LensFlare {
11076    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3LensFlare>,
11077}
11078
11079impl Drop for LensFlare {
11080    fn drop(&mut self) {
11081        // SAFETY: `raw` came from a native constructor and Drop runs once.
11082        unsafe { ffi::whiteout_m3_M3LensFlare_delete(self.raw.as_ptr()) }
11083    }
11084}
11085
11086impl LensFlare {
11087    /// # Safety
11088    /// `raw` must be a live handle this value takes ownership of.
11089    #[allow(dead_code)] // used by whichever methods return this type
11090    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3LensFlare) -> Option<Self> {
11091        core::ptr::NonNull::new(raw).map(|raw| LensFlare { raw })
11092    }
11093}
11094
11095// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
11096// is deliberately NOT implemented — the C++ types make no documented
11097// guarantee about concurrent use, and claiming one we haven't verified
11098// would be unsound. See `@bind thread_safe` in the plan.
11099unsafe impl Send for LensFlare {}
11100
11101impl core::fmt::Debug for LensFlare {
11102    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
11103        f.debug_struct("LensFlare").finish_non_exhaustive()
11104    }
11105}
11106
11107impl LensFlare {
11108    /// # Panics
11109    /// Panics if the native allocation fails.
11110    pub fn new() -> Self {
11111        // SAFETY: the native constructor returns a live handle; a null here
11112        // means the library is unusable.
11113        unsafe {
11114            let raw = ffi::whiteout_m3_M3LensFlare_new();
11115            Self::from_raw(raw).expect("native LensFlare allocation failed")
11116        }
11117    }
11118
11119    /// Flare name (`Ref<CHAR>`)
11120    pub fn name(&self) -> String {
11121        // SAFETY: the native side hands over an owned CString.
11122        unsafe {
11123            crate::support::take_string(ffi::whiteout_m3_M3LensFlare_get_name(self.raw.as_ptr()))
11124        }
11125    }
11126
11127    pub fn set_name(&mut self, value: &str) {
11128        let value = std::ffi::CString::new(value).unwrap_or_default();
11129        // SAFETY: the pointer outlives the call.
11130        unsafe { ffi::whiteout_m3_M3LensFlare_set_name(self.raw.as_ptr(), value.as_ptr()) }
11131    }
11132
11133    /// Sub-flare elements (LFSB)
11134    pub fn sub_flares_len(&self) -> usize {
11135        // SAFETY: scalar read through a live handle.
11136        unsafe { ffi::whiteout_m3_M3LensFlare_get_subFlares_count(self.raw.as_ptr()) }
11137    }
11138
11139    /// Borrows element `index` in place. `None` when out of range.
11140    pub fn sub_flares(&self, index: usize) -> Option<crate::support::Ref<'_, SubFlare>> {
11141        if index >= self.sub_flares_len() {
11142            return None;
11143        }
11144        // SAFETY: index checked above; the pointer is interior to `self`.
11145        unsafe {
11146            Some(crate::support::Ref::new(SubFlare {
11147                raw: core::ptr::NonNull::new_unchecked(
11148                    ffi::whiteout_m3_M3LensFlare_get_subFlares_at(self.raw.as_ptr(), index),
11149                ),
11150            }))
11151        }
11152    }
11153
11154    pub fn sub_flares_mut(&mut self, index: usize) -> Option<crate::support::RefMut<'_, SubFlare>> {
11155        if index >= self.sub_flares_len() {
11156            return None;
11157        }
11158        // SAFETY: as above; `&mut self` guarantees exclusivity.
11159        unsafe {
11160            Some(crate::support::RefMut::new(SubFlare {
11161                raw: core::ptr::NonNull::new_unchecked(
11162                    ffi::whiteout_m3_M3LensFlare_get_subFlares_at(self.raw.as_ptr(), index),
11163                ),
11164            }))
11165        }
11166    }
11167
11168    /// Iterate the elements, borrowing each in turn.
11169    pub fn sub_flares_iter(
11170        &self,
11171    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, SubFlare>> {
11172        (0..self.sub_flares_len()).map(move |i| self.sub_flares(i).expect("index below len"))
11173    }
11174
11175    pub fn resize_sub_flares(&mut self, count: usize) {
11176        // SAFETY: exclusive access, so no borrow is outstanding.
11177        unsafe { ffi::whiteout_m3_M3LensFlare_resize_subFlares(self.raw.as_ptr(), count) }
11178    }
11179
11180    /// Flipbook grid columns
11181    pub fn columns(&self) -> u32 {
11182        // SAFETY: plain scalar read through a live handle.
11183        unsafe { ffi::whiteout_m3_M3LensFlare_get_columns(self.raw.as_ptr()) }
11184    }
11185
11186    pub fn set_columns(&mut self, value: u32) {
11187        // SAFETY: plain scalar write through a live handle.
11188        unsafe { ffi::whiteout_m3_M3LensFlare_set_columns(self.raw.as_ptr(), value) }
11189    }
11190
11191    /// Flipbook grid rows
11192    pub fn rows(&self) -> u32 {
11193        // SAFETY: plain scalar read through a live handle.
11194        unsafe { ffi::whiteout_m3_M3LensFlare_get_rows(self.raw.as_ptr()) }
11195    }
11196
11197    pub fn set_rows(&mut self, value: u32) {
11198        // SAFETY: plain scalar write through a live handle.
11199        unsafe { ffi::whiteout_m3_M3LensFlare_set_rows(self.raw.as_ptr(), value) }
11200    }
11201
11202    /// Distance fade start
11203    pub fn distance_fade(&self) -> f32 {
11204        // SAFETY: plain scalar read through a live handle.
11205        unsafe { ffi::whiteout_m3_M3LensFlare_get_distanceFade(self.raw.as_ptr()) }
11206    }
11207
11208    pub fn set_distance_fade(&mut self, value: f32) {
11209        // SAFETY: plain scalar write through a live handle.
11210        unsafe { ffi::whiteout_m3_M3LensFlare_set_distanceFade(self.raw.as_ptr(), value) }
11211    }
11212
11213    /// Library name (`Ref<CHAR>`)
11214    pub fn lib_name(&self) -> String {
11215        // SAFETY: the native side hands over an owned CString.
11216        unsafe {
11217            crate::support::take_string(ffi::whiteout_m3_M3LensFlare_get_libName(self.raw.as_ptr()))
11218        }
11219    }
11220
11221    pub fn set_lib_name(&mut self, value: &str) {
11222        let value = std::ffi::CString::new(value).unwrap_or_default();
11223        // SAFETY: the pointer outlives the call.
11224        unsafe { ffi::whiteout_m3_M3LensFlare_set_libName(self.raw.as_ptr(), value.as_ptr()) }
11225    }
11226
11227    /// Animated intensity
11228    /// Borrows the field in place — no copy, no allocation.
11229    pub fn intensity(&self) -> crate::support::Ref<'_, AnimRefF32> {
11230        // SAFETY: an interior pointer into `self`, valid for this
11231        // borrow and never freed by the `Ref`.
11232        unsafe {
11233            crate::support::Ref::new(AnimRefF32 {
11234                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3LensFlare_get_intensity(
11235                    self.raw.as_ptr(),
11236                )),
11237            })
11238        }
11239    }
11240
11241    pub fn intensity_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
11242        // SAFETY: as above; `&mut self` guarantees exclusivity.
11243        unsafe {
11244            crate::support::RefMut::new(AnimRefF32 {
11245                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3LensFlare_get_intensity(
11246                    self.raw.as_ptr(),
11247                )),
11248            })
11249        }
11250    }
11251
11252    /// Animated color
11253    /// Borrows the field in place — no copy, no allocation.
11254    pub fn color(&self) -> crate::support::Ref<'_, AnimRefM3ColorBGRA> {
11255        // SAFETY: an interior pointer into `self`, valid for this
11256        // borrow and never freed by the `Ref`.
11257        unsafe {
11258            crate::support::Ref::new(AnimRefM3ColorBGRA {
11259                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3LensFlare_get_color(
11260                    self.raw.as_ptr(),
11261                )),
11262            })
11263        }
11264    }
11265
11266    pub fn color_mut(&mut self) -> crate::support::RefMut<'_, AnimRefM3ColorBGRA> {
11267        // SAFETY: as above; `&mut self` guarantees exclusivity.
11268        unsafe {
11269            crate::support::RefMut::new(AnimRefM3ColorBGRA {
11270                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3LensFlare_get_color(
11271                    self.raw.as_ptr(),
11272                )),
11273            })
11274        }
11275    }
11276
11277    /// Animated HDR multiplier
11278    /// Borrows the field in place — no copy, no allocation.
11279    pub fn hdr(&self) -> crate::support::Ref<'_, AnimRefF32> {
11280        // SAFETY: an interior pointer into `self`, valid for this
11281        // borrow and never freed by the `Ref`.
11282        unsafe {
11283            crate::support::Ref::new(AnimRefF32 {
11284                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3LensFlare_get_hdr(
11285                    self.raw.as_ptr(),
11286                )),
11287            })
11288        }
11289    }
11290
11291    pub fn hdr_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
11292        // SAFETY: as above; `&mut self` guarantees exclusivity.
11293        unsafe {
11294            crate::support::RefMut::new(AnimRefF32 {
11295                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3LensFlare_get_hdr(
11296                    self.raw.as_ptr(),
11297                )),
11298            })
11299        }
11300    }
11301
11302    /// Animated size
11303    /// Borrows the field in place — no copy, no allocation.
11304    pub fn size(&self) -> crate::support::Ref<'_, AnimRefF32> {
11305        // SAFETY: an interior pointer into `self`, valid for this
11306        // borrow and never freed by the `Ref`.
11307        unsafe {
11308            crate::support::Ref::new(AnimRefF32 {
11309                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3LensFlare_get_size(
11310                    self.raw.as_ptr(),
11311                )),
11312            })
11313        }
11314    }
11315
11316    pub fn size_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
11317        // SAFETY: as above; `&mut self` guarantees exclusivity.
11318        unsafe {
11319            crate::support::RefMut::new(AnimRefF32 {
11320                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3LensFlare_get_size(
11321                    self.raw.as_ptr(),
11322                )),
11323            })
11324        }
11325    }
11326}
11327
11328impl Default for LensFlare {
11329    fn default() -> Self {
11330        Self::new()
11331    }
11332}
11333
11334/// MADD — Material additional data (v0–v3, 140–160 bytes)
11335///
11336/// Buffer-style material extension storing key–value pairs, hashes, and animation parameters. Added in MODL v30.
11337pub struct MaterialAddData {
11338    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3MaterialAddData>,
11339}
11340
11341impl Drop for MaterialAddData {
11342    fn drop(&mut self) {
11343        // SAFETY: `raw` came from a native constructor and Drop runs once.
11344        unsafe { ffi::whiteout_m3_M3MaterialAddData_delete(self.raw.as_ptr()) }
11345    }
11346}
11347
11348impl MaterialAddData {
11349    /// # Safety
11350    /// `raw` must be a live handle this value takes ownership of.
11351    #[allow(dead_code)] // used by whichever methods return this type
11352    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3MaterialAddData) -> Option<Self> {
11353        core::ptr::NonNull::new(raw).map(|raw| MaterialAddData { raw })
11354    }
11355}
11356
11357// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
11358// is deliberately NOT implemented — the C++ types make no documented
11359// guarantee about concurrent use, and claiming one we haven't verified
11360// would be unsound. See `@bind thread_safe` in the plan.
11361unsafe impl Send for MaterialAddData {}
11362
11363impl core::fmt::Debug for MaterialAddData {
11364    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
11365        f.debug_struct("MaterialAddData").finish_non_exhaustive()
11366    }
11367}
11368
11369impl MaterialAddData {
11370    /// # Panics
11371    /// Panics if the native allocation fails.
11372    pub fn new() -> Self {
11373        // SAFETY: the native constructor returns a live handle; a null here
11374        // means the library is unusable.
11375        unsafe {
11376            let raw = ffi::whiteout_m3_M3MaterialAddData_new();
11377            Self::from_raw(raw).expect("native MaterialAddData allocation failed")
11378        }
11379    }
11380
11381    /// Key name (`Ref<CHAR>`)
11382    pub fn key_name(&self) -> String {
11383        // SAFETY: the native side hands over an owned CString.
11384        unsafe {
11385            crate::support::take_string(ffi::whiteout_m3_M3MaterialAddData_get_keyName(
11386                self.raw.as_ptr(),
11387            ))
11388        }
11389    }
11390
11391    pub fn set_key_name(&mut self, value: &str) {
11392        let value = std::ffi::CString::new(value).unwrap_or_default();
11393        // SAFETY: the pointer outlives the call.
11394        unsafe { ffi::whiteout_m3_M3MaterialAddData_set_keyName(self.raw.as_ptr(), value.as_ptr()) }
11395    }
11396
11397    /// Key hash values (U32_)
11398    /// Zero-copy view of the underlying `std::vector`.
11399    pub fn key_hash(&self) -> &[u32] {
11400        // SAFETY: `_data`/`_count` describe one contiguous C++
11401        // allocation, borrowed for as long as `self` is.
11402        unsafe {
11403            let n = ffi::whiteout_m3_M3MaterialAddData_get_keyHash_count(self.raw.as_ptr());
11404            let p = ffi::whiteout_m3_M3MaterialAddData_get_keyHash_data(self.raw.as_ptr());
11405            if p.is_null() || n == 0 {
11406                &[]
11407            } else {
11408                core::slice::from_raw_parts(p, n)
11409            }
11410        }
11411    }
11412
11413    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
11414    pub fn key_hash_mut(&mut self) -> &mut [u32] {
11415        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
11416        unsafe {
11417            let n = ffi::whiteout_m3_M3MaterialAddData_get_keyHash_count(self.raw.as_ptr());
11418            let p =
11419                ffi::whiteout_m3_M3MaterialAddData_get_keyHash_data(self.raw.as_ptr()) as *mut u32;
11420            if p.is_null() || n == 0 {
11421                &mut []
11422            } else {
11423                core::slice::from_raw_parts_mut(p, n)
11424            }
11425        }
11426    }
11427
11428    pub fn set_key_hash(&mut self, values: &[u32]) {
11429        // SAFETY: the native side copies `values` before returning.
11430        unsafe {
11431            ffi::whiteout_m3_M3MaterialAddData_assign_keyHash(
11432                self.raw.as_ptr(),
11433                values.as_ptr() as *const _,
11434                values.len(),
11435            )
11436        }
11437    }
11438
11439    pub fn resize_key_hash(&mut self, count: usize) {
11440        // SAFETY: reallocation is safe here precisely because
11441        // `&mut self` means no slice borrow is outstanding.
11442        unsafe { ffi::whiteout_m3_M3MaterialAddData_resize_keyHash(self.raw.as_ptr(), count) }
11443    }
11444
11445    /// Extra hash values (U32_, v2+)
11446    /// Zero-copy view of the underlying `std::vector`.
11447    pub fn extra_hash(&self) -> &[u32] {
11448        // SAFETY: `_data`/`_count` describe one contiguous C++
11449        // allocation, borrowed for as long as `self` is.
11450        unsafe {
11451            let n = ffi::whiteout_m3_M3MaterialAddData_get_extraHash_count(self.raw.as_ptr());
11452            let p = ffi::whiteout_m3_M3MaterialAddData_get_extraHash_data(self.raw.as_ptr());
11453            if p.is_null() || n == 0 {
11454                &[]
11455            } else {
11456                core::slice::from_raw_parts(p, n)
11457            }
11458        }
11459    }
11460
11461    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
11462    pub fn extra_hash_mut(&mut self) -> &mut [u32] {
11463        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
11464        unsafe {
11465            let n = ffi::whiteout_m3_M3MaterialAddData_get_extraHash_count(self.raw.as_ptr());
11466            let p = ffi::whiteout_m3_M3MaterialAddData_get_extraHash_data(self.raw.as_ptr())
11467                as *mut u32;
11468            if p.is_null() || n == 0 {
11469                &mut []
11470            } else {
11471                core::slice::from_raw_parts_mut(p, n)
11472            }
11473        }
11474    }
11475
11476    pub fn set_extra_hash(&mut self, values: &[u32]) {
11477        // SAFETY: the native side copies `values` before returning.
11478        unsafe {
11479            ffi::whiteout_m3_M3MaterialAddData_assign_extraHash(
11480                self.raw.as_ptr(),
11481                values.as_ptr() as *const _,
11482                values.len(),
11483            )
11484        }
11485    }
11486
11487    pub fn resize_extra_hash(&mut self, count: usize) {
11488        // SAFETY: reallocation is safe here precisely because
11489        // `&mut self` means no slice borrow is outstanding.
11490        unsafe { ffi::whiteout_m3_M3MaterialAddData_resize_extraHash(self.raw.as_ptr(), count) }
11491    }
11492
11493    /// Value file path (`Ref<CHAR>`)
11494    pub fn value_path(&self) -> String {
11495        // SAFETY: the native side hands over an owned CString.
11496        unsafe {
11497            crate::support::take_string(ffi::whiteout_m3_M3MaterialAddData_get_valuePath(
11498                self.raw.as_ptr(),
11499            ))
11500        }
11501    }
11502
11503    pub fn set_value_path(&mut self, value: &str) {
11504        let value = std::ffi::CString::new(value).unwrap_or_default();
11505        // SAFETY: the pointer outlives the call.
11506        unsafe {
11507            ffi::whiteout_m3_M3MaterialAddData_set_valuePath(self.raw.as_ptr(), value.as_ptr())
11508        }
11509    }
11510
11511    /// Animation frequency
11512    pub fn frequency(&self) -> f32 {
11513        // SAFETY: plain scalar read through a live handle.
11514        unsafe { ffi::whiteout_m3_M3MaterialAddData_get_frequency(self.raw.as_ptr()) }
11515    }
11516
11517    pub fn set_frequency(&mut self, value: f32) {
11518        // SAFETY: plain scalar write through a live handle.
11519        unsafe { ffi::whiteout_m3_M3MaterialAddData_set_frequency(self.raw.as_ptr(), value) }
11520    }
11521
11522    /// Effect intensity
11523    pub fn intensity(&self) -> f32 {
11524        // SAFETY: plain scalar read through a live handle.
11525        unsafe { ffi::whiteout_m3_M3MaterialAddData_get_intensity(self.raw.as_ptr()) }
11526    }
11527
11528    pub fn set_intensity(&mut self, value: f32) {
11529        // SAFETY: plain scalar write through a live handle.
11530        unsafe { ffi::whiteout_m3_M3MaterialAddData_set_intensity(self.raw.as_ptr(), value) }
11531    }
11532
11533    /// Hold time duration
11534    pub fn hold_time(&self) -> f32 {
11535        // SAFETY: plain scalar read through a live handle.
11536        unsafe { ffi::whiteout_m3_M3MaterialAddData_get_holdTime(self.raw.as_ptr()) }
11537    }
11538
11539    pub fn set_hold_time(&mut self, value: f32) {
11540        // SAFETY: plain scalar write through a live handle.
11541        unsafe { ffi::whiteout_m3_M3MaterialAddData_set_holdTime(self.raw.as_ptr(), value) }
11542    }
11543
11544    /// Random seed hash
11545    pub fn random_hash(&self) -> u32 {
11546        // SAFETY: plain scalar read through a live handle.
11547        unsafe { ffi::whiteout_m3_M3MaterialAddData_get_randomHash(self.raw.as_ptr()) }
11548    }
11549
11550    pub fn set_random_hash(&mut self, value: u32) {
11551        // SAFETY: plain scalar write through a live handle.
11552        unsafe { ffi::whiteout_m3_M3MaterialAddData_set_randomHash(self.raw.as_ptr(), value) }
11553    }
11554
11555    /// Animation type code
11556    pub fn animation_type(&self) -> u32 {
11557        // SAFETY: plain scalar read through a live handle.
11558        unsafe { ffi::whiteout_m3_M3MaterialAddData_get_animationType(self.raw.as_ptr()) }
11559    }
11560
11561    pub fn set_animation_type(&mut self, value: u32) {
11562        // SAFETY: plain scalar write through a live handle.
11563        unsafe { ffi::whiteout_m3_M3MaterialAddData_set_animationType(self.raw.as_ptr(), value) }
11564    }
11565
11566    /// Alignment padding
11567    pub fn padding_0(&self) -> u32 {
11568        // SAFETY: plain scalar read through a live handle.
11569        unsafe { ffi::whiteout_m3_M3MaterialAddData_get_padding0(self.raw.as_ptr()) }
11570    }
11571
11572    pub fn set_padding_0(&mut self, value: u32) {
11573        // SAFETY: plain scalar write through a live handle.
11574        unsafe { ffi::whiteout_m3_M3MaterialAddData_set_padding0(self.raw.as_ptr(), value) }
11575    }
11576
11577    /// Loop count (-1 = infinite)
11578    pub fn loop_count(&self) -> i32 {
11579        // SAFETY: plain scalar read through a live handle.
11580        unsafe { ffi::whiteout_m3_M3MaterialAddData_get_loopCount(self.raw.as_ptr()) }
11581    }
11582
11583    pub fn set_loop_count(&mut self, value: i32) {
11584        // SAFETY: plain scalar write through a live handle.
11585        unsafe { ffi::whiteout_m3_M3MaterialAddData_set_loopCount(self.raw.as_ptr(), value) }
11586    }
11587
11588    /// Flags
11589    pub fn flags(&self) -> u32 {
11590        // SAFETY: plain scalar read through a live handle.
11591        unsafe { ffi::whiteout_m3_M3MaterialAddData_get_flags(self.raw.as_ptr()) }
11592    }
11593
11594    pub fn set_flags(&mut self, value: u32) {
11595        // SAFETY: plain scalar write through a live handle.
11596        unsafe { ffi::whiteout_m3_M3MaterialAddData_set_flags(self.raw.as_ptr(), value) }
11597    }
11598
11599    /// Sub-type identifier
11600    pub fn sub_type(&self) -> u32 {
11601        // SAFETY: plain scalar read through a live handle.
11602        unsafe { ffi::whiteout_m3_M3MaterialAddData_get_subType(self.raw.as_ptr()) }
11603    }
11604
11605    pub fn set_sub_type(&mut self, value: u32) {
11606        // SAFETY: plain scalar write through a live handle.
11607        unsafe { ffi::whiteout_m3_M3MaterialAddData_set_subType(self.raw.as_ptr(), value) }
11608    }
11609
11610    /// Configuration parameter A
11611    pub fn config_a(&self) -> u32 {
11612        // SAFETY: plain scalar read through a live handle.
11613        unsafe { ffi::whiteout_m3_M3MaterialAddData_get_configA(self.raw.as_ptr()) }
11614    }
11615
11616    pub fn set_config_a(&mut self, value: u32) {
11617        // SAFETY: plain scalar write through a live handle.
11618        unsafe { ffi::whiteout_m3_M3MaterialAddData_set_configA(self.raw.as_ptr(), value) }
11619    }
11620
11621    /// Configuration parameter B
11622    pub fn config_b(&self) -> u32 {
11623        // SAFETY: plain scalar read through a live handle.
11624        unsafe { ffi::whiteout_m3_M3MaterialAddData_get_configB(self.raw.as_ptr()) }
11625    }
11626
11627    pub fn set_config_b(&mut self, value: u32) {
11628        // SAFETY: plain scalar write through a live handle.
11629        unsafe { ffi::whiteout_m3_M3MaterialAddData_set_configB(self.raw.as_ptr(), value) }
11630    }
11631
11632    /// Extra identifier 0 (v3+)
11633    pub fn extra_id_0(&self) -> u32 {
11634        // SAFETY: plain scalar read through a live handle.
11635        unsafe { ffi::whiteout_m3_M3MaterialAddData_get_extraId0(self.raw.as_ptr()) }
11636    }
11637
11638    pub fn set_extra_id_0(&mut self, value: u32) {
11639        // SAFETY: plain scalar write through a live handle.
11640        unsafe { ffi::whiteout_m3_M3MaterialAddData_set_extraId0(self.raw.as_ptr(), value) }
11641    }
11642
11643    /// Extra identifier 1 (v3+)
11644    pub fn extra_id_1(&self) -> u32 {
11645        // SAFETY: plain scalar read through a live handle.
11646        unsafe { ffi::whiteout_m3_M3MaterialAddData_get_extraId1(self.raw.as_ptr()) }
11647    }
11648
11649    pub fn set_extra_id_1(&mut self, value: u32) {
11650        // SAFETY: plain scalar write through a live handle.
11651        unsafe { ffi::whiteout_m3_M3MaterialAddData_set_extraId1(self.raw.as_ptr(), value) }
11652    }
11653}
11654
11655impl Default for MaterialAddData {
11656    fn default() -> Self {
11657        Self::new()
11658    }
11659}
11660
11661/// BONE — Skeleton bone (v0–v1, 160 bytes)
11662///
11663/// Each bone has a parent index, animated position/rotation/scale/visibility, and flags controlling inheritance, billboard mode, and IK.
11664pub struct Bone {
11665    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3Bone>,
11666}
11667
11668impl Drop for Bone {
11669    fn drop(&mut self) {
11670        // SAFETY: `raw` came from a native constructor and Drop runs once.
11671        unsafe { ffi::whiteout_m3_M3Bone_delete(self.raw.as_ptr()) }
11672    }
11673}
11674
11675impl Bone {
11676    /// # Safety
11677    /// `raw` must be a live handle this value takes ownership of.
11678    #[allow(dead_code)] // used by whichever methods return this type
11679    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3Bone) -> Option<Self> {
11680        core::ptr::NonNull::new(raw).map(|raw| Bone { raw })
11681    }
11682}
11683
11684// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
11685// is deliberately NOT implemented — the C++ types make no documented
11686// guarantee about concurrent use, and claiming one we haven't verified
11687// would be unsound. See `@bind thread_safe` in the plan.
11688unsafe impl Send for Bone {}
11689
11690impl core::fmt::Debug for Bone {
11691    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
11692        f.debug_struct("Bone").finish_non_exhaustive()
11693    }
11694}
11695
11696impl Bone {
11697    /// # Panics
11698    /// Panics if the native allocation fails.
11699    pub fn new() -> Self {
11700        // SAFETY: the native constructor returns a live handle; a null here
11701        // means the library is unusable.
11702        unsafe {
11703            let raw = ffi::whiteout_m3_M3Bone_new();
11704            Self::from_raw(raw).expect("native Bone allocation failed")
11705        }
11706    }
11707
11708    /// Unknown field
11709    pub fn unknown(&self) -> u32 {
11710        // SAFETY: plain scalar read through a live handle.
11711        unsafe { ffi::whiteout_m3_M3Bone_get_unknown(self.raw.as_ptr()) }
11712    }
11713
11714    pub fn set_unknown(&mut self, value: u32) {
11715        // SAFETY: plain scalar write through a live handle.
11716        unsafe { ffi::whiteout_m3_M3Bone_set_unknown(self.raw.as_ptr(), value) }
11717    }
11718
11719    /// Bone name (`Ref<CHAR>`)
11720    pub fn name(&self) -> String {
11721        // SAFETY: the native side hands over an owned CString.
11722        unsafe { crate::support::take_string(ffi::whiteout_m3_M3Bone_get_name(self.raw.as_ptr())) }
11723    }
11724
11725    pub fn set_name(&mut self, value: &str) {
11726        let value = std::ffi::CString::new(value).unwrap_or_default();
11727        // SAFETY: the pointer outlives the call.
11728        unsafe { ffi::whiteout_m3_M3Bone_set_name(self.raw.as_ptr(), value.as_ptr()) }
11729    }
11730
11731    /// Bone flags (inherit, billboard, IK, skin)
11732    pub fn flags(&self) -> BoneFlag {
11733        // SAFETY: scalar read; a flag set accepts any bits.
11734        BoneFlag(unsafe { ffi::whiteout_m3_M3Bone_get_flags(self.raw.as_ptr()) })
11735    }
11736
11737    pub fn set_flags(&mut self, value: BoneFlag) {
11738        // SAFETY: scalar write through a live handle.
11739        unsafe { ffi::whiteout_m3_M3Bone_set_flags(self.raw.as_ptr(), value.0) }
11740    }
11741
11742    /// Parent bone index (0xFFFF = root)
11743    pub fn parent_index(&self) -> u16 {
11744        // SAFETY: plain scalar read through a live handle.
11745        unsafe { ffi::whiteout_m3_M3Bone_get_parentIndex(self.raw.as_ptr()) }
11746    }
11747
11748    pub fn set_parent_index(&mut self, value: u16) {
11749        // SAFETY: plain scalar write through a live handle.
11750        unsafe { ffi::whiteout_m3_M3Bone_set_parentIndex(self.raw.as_ptr(), value) }
11751    }
11752
11753    /// Alignment padding
11754    pub fn padding(&self) -> u16 {
11755        // SAFETY: plain scalar read through a live handle.
11756        unsafe { ffi::whiteout_m3_M3Bone_get_padding(self.raw.as_ptr()) }
11757    }
11758
11759    pub fn set_padding(&mut self, value: u16) {
11760        // SAFETY: plain scalar write through a live handle.
11761        unsafe { ffi::whiteout_m3_M3Bone_set_padding(self.raw.as_ptr(), value) }
11762    }
11763
11764    /// Animated translation (36 bytes)
11765    /// Borrows the field in place — no copy, no allocation.
11766    pub fn position(&self) -> crate::support::Ref<'_, AnimRefVector3f> {
11767        // SAFETY: an interior pointer into `self`, valid for this
11768        // borrow and never freed by the `Ref`.
11769        unsafe {
11770            crate::support::Ref::new(AnimRefVector3f {
11771                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Bone_get_position(
11772                    self.raw.as_ptr(),
11773                )),
11774            })
11775        }
11776    }
11777
11778    pub fn position_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector3f> {
11779        // SAFETY: as above; `&mut self` guarantees exclusivity.
11780        unsafe {
11781            crate::support::RefMut::new(AnimRefVector3f {
11782                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Bone_get_position(
11783                    self.raw.as_ptr(),
11784                )),
11785            })
11786        }
11787    }
11788
11789    /// Animated rotation (44 bytes)
11790    /// Borrows the field in place — no copy, no allocation.
11791    pub fn rotation(&self) -> crate::support::Ref<'_, AnimRefQuaternion> {
11792        // SAFETY: an interior pointer into `self`, valid for this
11793        // borrow and never freed by the `Ref`.
11794        unsafe {
11795            crate::support::Ref::new(AnimRefQuaternion {
11796                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Bone_get_rotation(
11797                    self.raw.as_ptr(),
11798                )),
11799            })
11800        }
11801    }
11802
11803    pub fn rotation_mut(&mut self) -> crate::support::RefMut<'_, AnimRefQuaternion> {
11804        // SAFETY: as above; `&mut self` guarantees exclusivity.
11805        unsafe {
11806            crate::support::RefMut::new(AnimRefQuaternion {
11807                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Bone_get_rotation(
11808                    self.raw.as_ptr(),
11809                )),
11810            })
11811        }
11812    }
11813
11814    /// Animated scale (36 bytes)
11815    /// Borrows the field in place — no copy, no allocation.
11816    pub fn scale(&self) -> crate::support::Ref<'_, AnimRefVector3f> {
11817        // SAFETY: an interior pointer into `self`, valid for this
11818        // borrow and never freed by the `Ref`.
11819        unsafe {
11820            crate::support::Ref::new(AnimRefVector3f {
11821                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Bone_get_scale(
11822                    self.raw.as_ptr(),
11823                )),
11824            })
11825        }
11826    }
11827
11828    pub fn scale_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector3f> {
11829        // SAFETY: as above; `&mut self` guarantees exclusivity.
11830        unsafe {
11831            crate::support::RefMut::new(AnimRefVector3f {
11832                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Bone_get_scale(
11833                    self.raw.as_ptr(),
11834                )),
11835            })
11836        }
11837    }
11838
11839    /// Animated visibility flag (20 bytes)
11840    /// Borrows the field in place — no copy, no allocation.
11841    pub fn visibility(&self) -> crate::support::Ref<'_, AnimRefU32> {
11842        // SAFETY: an interior pointer into `self`, valid for this
11843        // borrow and never freed by the `Ref`.
11844        unsafe {
11845            crate::support::Ref::new(AnimRefU32 {
11846                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Bone_get_visibility(
11847                    self.raw.as_ptr(),
11848                )),
11849            })
11850        }
11851    }
11852
11853    pub fn visibility_mut(&mut self) -> crate::support::RefMut<'_, AnimRefU32> {
11854        // SAFETY: as above; `&mut self` guarantees exclusivity.
11855        unsafe {
11856            crate::support::RefMut::new(AnimRefU32 {
11857                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Bone_get_visibility(
11858                    self.raw.as_ptr(),
11859                )),
11860            })
11861        }
11862    }
11863}
11864
11865impl Default for Bone {
11866    fn default() -> Self {
11867        Self::new()
11868    }
11869}
11870
11871/// REGN — Region / submesh (v0–v5, 48 bytes)
11872///
11873/// Describes a contiguous range of vertices and indices forming a submesh, with bone lookup info for skinning and UV scale/offset for texturing.
11874pub struct Region {
11875    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3Region>,
11876}
11877
11878impl Drop for Region {
11879    fn drop(&mut self) {
11880        // SAFETY: `raw` came from a native constructor and Drop runs once.
11881        unsafe { ffi::whiteout_m3_M3Region_delete(self.raw.as_ptr()) }
11882    }
11883}
11884
11885impl Region {
11886    /// # Safety
11887    /// `raw` must be a live handle this value takes ownership of.
11888    #[allow(dead_code)] // used by whichever methods return this type
11889    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3Region) -> Option<Self> {
11890        core::ptr::NonNull::new(raw).map(|raw| Region { raw })
11891    }
11892}
11893
11894// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
11895// is deliberately NOT implemented — the C++ types make no documented
11896// guarantee about concurrent use, and claiming one we haven't verified
11897// would be unsound. See `@bind thread_safe` in the plan.
11898unsafe impl Send for Region {}
11899
11900impl core::fmt::Debug for Region {
11901    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
11902        f.debug_struct("Region").finish_non_exhaustive()
11903    }
11904}
11905
11906impl Region {
11907    /// # Panics
11908    /// Panics if the native allocation fails.
11909    pub fn new() -> Self {
11910        // SAFETY: the native constructor returns a live handle; a null here
11911        // means the library is unusable.
11912        unsafe {
11913            let raw = ffi::whiteout_m3_M3Region_new();
11914            Self::from_raw(raw).expect("native Region allocation failed")
11915        }
11916    }
11917
11918    /// Region index
11919    pub fn index(&self) -> u32 {
11920        // SAFETY: plain scalar read through a live handle.
11921        unsafe { ffi::whiteout_m3_M3Region_get_index(self.raw.as_ptr()) }
11922    }
11923
11924    pub fn set_index(&mut self, value: u32) {
11925        // SAFETY: plain scalar write through a live handle.
11926        unsafe { ffi::whiteout_m3_M3Region_set_index(self.raw.as_ptr(), value) }
11927    }
11928
11929    /// Unknown field
11930    pub fn unknown(&self) -> u32 {
11931        // SAFETY: plain scalar read through a live handle.
11932        unsafe { ffi::whiteout_m3_M3Region_get_unknown(self.raw.as_ptr()) }
11933    }
11934
11935    pub fn set_unknown(&mut self, value: u32) {
11936        // SAFETY: plain scalar write through a live handle.
11937        unsafe { ffi::whiteout_m3_M3Region_set_unknown(self.raw.as_ptr(), value) }
11938    }
11939
11940    /// First vertex in the vertex buffer
11941    pub fn first_vertex(&self) -> u32 {
11942        // SAFETY: plain scalar read through a live handle.
11943        unsafe { ffi::whiteout_m3_M3Region_get_firstVertex(self.raw.as_ptr()) }
11944    }
11945
11946    pub fn set_first_vertex(&mut self, value: u32) {
11947        // SAFETY: plain scalar write through a live handle.
11948        unsafe { ffi::whiteout_m3_M3Region_set_firstVertex(self.raw.as_ptr(), value) }
11949    }
11950
11951    /// Number of vertices
11952    pub fn vertex_count(&self) -> u32 {
11953        // SAFETY: plain scalar read through a live handle.
11954        unsafe { ffi::whiteout_m3_M3Region_get_vertexCount(self.raw.as_ptr()) }
11955    }
11956
11957    pub fn set_vertex_count(&mut self, value: u32) {
11958        // SAFETY: plain scalar write through a live handle.
11959        unsafe { ffi::whiteout_m3_M3Region_set_vertexCount(self.raw.as_ptr(), value) }
11960    }
11961
11962    /// First index in the index buffer
11963    pub fn first_index(&self) -> u32 {
11964        // SAFETY: plain scalar read through a live handle.
11965        unsafe { ffi::whiteout_m3_M3Region_get_firstIndex(self.raw.as_ptr()) }
11966    }
11967
11968    pub fn set_first_index(&mut self, value: u32) {
11969        // SAFETY: plain scalar write through a live handle.
11970        unsafe { ffi::whiteout_m3_M3Region_set_firstIndex(self.raw.as_ptr(), value) }
11971    }
11972
11973    /// Number of indices (triangles × 3)
11974    pub fn index_count(&self) -> u32 {
11975        // SAFETY: plain scalar read through a live handle.
11976        unsafe { ffi::whiteout_m3_M3Region_get_indexCount(self.raw.as_ptr()) }
11977    }
11978
11979    pub fn set_index_count(&mut self, value: u32) {
11980        // SAFETY: plain scalar write through a live handle.
11981        unsafe { ffi::whiteout_m3_M3Region_set_indexCount(self.raw.as_ptr(), value) }
11982    }
11983
11984    /// Unknown field
11985    pub fn unknown_2(&self) -> u16 {
11986        // SAFETY: plain scalar read through a live handle.
11987        unsafe { ffi::whiteout_m3_M3Region_get_unknown2(self.raw.as_ptr()) }
11988    }
11989
11990    pub fn set_unknown_2(&mut self, value: u16) {
11991        // SAFETY: plain scalar write through a live handle.
11992        unsafe { ffi::whiteout_m3_M3Region_set_unknown2(self.raw.as_ptr(), value) }
11993    }
11994
11995    /// First entry in bone lookup table
11996    pub fn first_bone_lookup(&self) -> u16 {
11997        // SAFETY: plain scalar read through a live handle.
11998        unsafe { ffi::whiteout_m3_M3Region_get_firstBoneLookup(self.raw.as_ptr()) }
11999    }
12000
12001    pub fn set_first_bone_lookup(&mut self, value: u16) {
12002        // SAFETY: plain scalar write through a live handle.
12003        unsafe { ffi::whiteout_m3_M3Region_set_firstBoneLookup(self.raw.as_ptr(), value) }
12004    }
12005
12006    /// Number of bone lookup entries
12007    pub fn bone_lookup_count(&self) -> u16 {
12008        // SAFETY: plain scalar read through a live handle.
12009        unsafe { ffi::whiteout_m3_M3Region_get_boneLookupCount(self.raw.as_ptr()) }
12010    }
12011
12012    pub fn set_bone_lookup_count(&mut self, value: u16) {
12013        // SAFETY: plain scalar write through a live handle.
12014        unsafe { ffi::whiteout_m3_M3Region_set_boneLookupCount(self.raw.as_ptr(), value) }
12015    }
12016
12017    /// Alignment padding
12018    pub fn padding(&self) -> u16 {
12019        // SAFETY: plain scalar read through a live handle.
12020        unsafe { ffi::whiteout_m3_M3Region_get_padding(self.raw.as_ptr()) }
12021    }
12022
12023    pub fn set_padding(&mut self, value: u16) {
12024        // SAFETY: plain scalar write through a live handle.
12025        unsafe { ffi::whiteout_m3_M3Region_set_padding(self.raw.as_ptr(), value) }
12026    }
12027
12028    /// Number of bone weight pairs per vertex
12029    pub fn bone_weight_pairs(&self) -> u8 {
12030        // SAFETY: plain scalar read through a live handle.
12031        unsafe { ffi::whiteout_m3_M3Region_get_boneWeightPairs(self.raw.as_ptr()) }
12032    }
12033
12034    pub fn set_bone_weight_pairs(&mut self, value: u8) {
12035        // SAFETY: plain scalar write through a live handle.
12036        unsafe { ffi::whiteout_m3_M3Region_set_boneWeightPairs(self.raw.as_ptr(), value) }
12037    }
12038
12039    /// Number of bone index pairs per vertex
12040    pub fn bone_index_pairs(&self) -> u8 {
12041        // SAFETY: plain scalar read through a live handle.
12042        unsafe { ffi::whiteout_m3_M3Region_get_boneIndexPairs(self.raw.as_ptr()) }
12043    }
12044
12045    pub fn set_bone_index_pairs(&mut self, value: u8) {
12046        // SAFETY: plain scalar write through a live handle.
12047        unsafe { ffi::whiteout_m3_M3Region_set_boneIndexPairs(self.raw.as_ptr(), value) }
12048    }
12049
12050    /// Root bone for this region
12051    pub fn root_bone(&self) -> u16 {
12052        // SAFETY: plain scalar read through a live handle.
12053        unsafe { ffi::whiteout_m3_M3Region_get_rootBone(self.raw.as_ptr()) }
12054    }
12055
12056    pub fn set_root_bone(&mut self, value: u16) {
12057        // SAFETY: plain scalar write through a live handle.
12058        unsafe { ffi::whiteout_m3_M3Region_set_rootBone(self.raw.as_ptr(), value) }
12059    }
12060
12061    /// Region flags (hidden, cloth, etc.)
12062    pub fn flags(&self) -> RegionFlag {
12063        // SAFETY: scalar read; a flag set accepts any bits.
12064        RegionFlag(unsafe { ffi::whiteout_m3_M3Region_get_flags(self.raw.as_ptr()) })
12065    }
12066
12067    pub fn set_flags(&mut self, value: RegionFlag) {
12068        // SAFETY: scalar write through a live handle.
12069        unsafe { ffi::whiteout_m3_M3Region_set_flags(self.raw.as_ptr(), value.0) }
12070    }
12071
12072    /// UV coordinate scale factor
12073    pub fn uv_scale(&self) -> f32 {
12074        // SAFETY: plain scalar read through a live handle.
12075        unsafe { ffi::whiteout_m3_M3Region_get_uvScale(self.raw.as_ptr()) }
12076    }
12077
12078    pub fn set_uv_scale(&mut self, value: f32) {
12079        // SAFETY: plain scalar write through a live handle.
12080        unsafe { ffi::whiteout_m3_M3Region_set_uvScale(self.raw.as_ptr(), value) }
12081    }
12082
12083    /// UV coordinate offset
12084    pub fn uv_offset(&self) -> f32 {
12085        // SAFETY: plain scalar read through a live handle.
12086        unsafe { ffi::whiteout_m3_M3Region_get_uvOffset(self.raw.as_ptr()) }
12087    }
12088
12089    pub fn set_uv_offset(&mut self, value: f32) {
12090        // SAFETY: plain scalar write through a live handle.
12091        unsafe { ffi::whiteout_m3_M3Region_set_uvOffset(self.raw.as_ptr(), value) }
12092    }
12093}
12094
12095impl Default for Region {
12096    fn default() -> Self {
12097        Self::new()
12098    }
12099}
12100
12101/// BAT_ — Batch / draw call (v0–v1, 14 bytes)
12102///
12103/// Associates a Region with a material for rendering. Multiple batches may reference the same region with different materials.
12104pub struct Batch {
12105    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3Batch>,
12106}
12107
12108impl Drop for Batch {
12109    fn drop(&mut self) {
12110        // SAFETY: `raw` came from a native constructor and Drop runs once.
12111        unsafe { ffi::whiteout_m3_M3Batch_delete(self.raw.as_ptr()) }
12112    }
12113}
12114
12115impl Batch {
12116    /// # Safety
12117    /// `raw` must be a live handle this value takes ownership of.
12118    #[allow(dead_code)] // used by whichever methods return this type
12119    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3Batch) -> Option<Self> {
12120        core::ptr::NonNull::new(raw).map(|raw| Batch { raw })
12121    }
12122}
12123
12124// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
12125// is deliberately NOT implemented — the C++ types make no documented
12126// guarantee about concurrent use, and claiming one we haven't verified
12127// would be unsound. See `@bind thread_safe` in the plan.
12128unsafe impl Send for Batch {}
12129
12130impl core::fmt::Debug for Batch {
12131    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
12132        f.debug_struct("Batch").finish_non_exhaustive()
12133    }
12134}
12135
12136impl Batch {
12137    /// # Panics
12138    /// Panics if the native allocation fails.
12139    pub fn new() -> Self {
12140        // SAFETY: the native constructor returns a live handle; a null here
12141        // means the library is unusable.
12142        unsafe {
12143            let raw = ffi::whiteout_m3_M3Batch_new();
12144            Self::from_raw(raw).expect("native Batch allocation failed")
12145        }
12146    }
12147
12148    /// Unknown field
12149    pub fn unknown(&self) -> u32 {
12150        // SAFETY: plain scalar read through a live handle.
12151        unsafe { ffi::whiteout_m3_M3Batch_get_unknown(self.raw.as_ptr()) }
12152    }
12153
12154    pub fn set_unknown(&mut self, value: u32) {
12155        // SAFETY: plain scalar write through a live handle.
12156        unsafe { ffi::whiteout_m3_M3Batch_set_unknown(self.raw.as_ptr(), value) }
12157    }
12158
12159    /// Index into REGN array
12160    pub fn region_index(&self) -> u16 {
12161        // SAFETY: plain scalar read through a live handle.
12162        unsafe { ffi::whiteout_m3_M3Batch_get_regionIndex(self.raw.as_ptr()) }
12163    }
12164
12165    pub fn set_region_index(&mut self, value: u16) {
12166        // SAFETY: plain scalar write through a live handle.
12167        unsafe { ffi::whiteout_m3_M3Batch_set_regionIndex(self.raw.as_ptr(), value) }
12168    }
12169
12170    /// Unknown field
12171    pub fn unknown_2(&self) -> u32 {
12172        // SAFETY: plain scalar read through a live handle.
12173        unsafe { ffi::whiteout_m3_M3Batch_get_unknown2(self.raw.as_ptr()) }
12174    }
12175
12176    pub fn set_unknown_2(&mut self, value: u32) {
12177        // SAFETY: plain scalar write through a live handle.
12178        unsafe { ffi::whiteout_m3_M3Batch_set_unknown2(self.raw.as_ptr(), value) }
12179    }
12180
12181    /// Index into MATM material map array
12182    pub fn material_index(&self) -> u16 {
12183        // SAFETY: plain scalar read through a live handle.
12184        unsafe { ffi::whiteout_m3_M3Batch_get_materialIndex(self.raw.as_ptr()) }
12185    }
12186
12187    pub fn set_material_index(&mut self, value: u16) {
12188        // SAFETY: plain scalar write through a live handle.
12189        unsafe { ffi::whiteout_m3_M3Batch_set_materialIndex(self.raw.as_ptr(), value) }
12190    }
12191
12192    /// Number of bones affecting this batch
12193    pub fn bone_count(&self) -> u16 {
12194        // SAFETY: plain scalar read through a live handle.
12195        unsafe { ffi::whiteout_m3_M3Batch_get_boneCount(self.raw.as_ptr()) }
12196    }
12197
12198    pub fn set_bone_count(&mut self, value: u16) {
12199        // SAFETY: plain scalar write through a live handle.
12200        unsafe { ffi::whiteout_m3_M3Batch_set_boneCount(self.raw.as_ptr(), value) }
12201    }
12202}
12203
12204impl Default for Batch {
12205    fn default() -> Self {
12206        Self::new()
12207    }
12208}
12209
12210/// MSEC — Mesh section bounds (v0–v1, 80 bytes)
12211///
12212/// Per-node animated bounding extent used for culling and LOD.
12213pub struct MeshSection {
12214    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3MeshSection>,
12215}
12216
12217impl Drop for MeshSection {
12218    fn drop(&mut self) {
12219        // SAFETY: `raw` came from a native constructor and Drop runs once.
12220        unsafe { ffi::whiteout_m3_M3MeshSection_delete(self.raw.as_ptr()) }
12221    }
12222}
12223
12224impl MeshSection {
12225    /// # Safety
12226    /// `raw` must be a live handle this value takes ownership of.
12227    #[allow(dead_code)] // used by whichever methods return this type
12228    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3MeshSection) -> Option<Self> {
12229        core::ptr::NonNull::new(raw).map(|raw| MeshSection { raw })
12230    }
12231}
12232
12233// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
12234// is deliberately NOT implemented — the C++ types make no documented
12235// guarantee about concurrent use, and claiming one we haven't verified
12236// would be unsound. See `@bind thread_safe` in the plan.
12237unsafe impl Send for MeshSection {}
12238
12239impl core::fmt::Debug for MeshSection {
12240    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
12241        f.debug_struct("MeshSection").finish_non_exhaustive()
12242    }
12243}
12244
12245impl MeshSection {
12246    /// # Panics
12247    /// Panics if the native allocation fails.
12248    pub fn new() -> Self {
12249        // SAFETY: the native constructor returns a live handle; a null here
12250        // means the library is unusable.
12251        unsafe {
12252            let raw = ffi::whiteout_m3_M3MeshSection_new();
12253            Self::from_raw(raw).expect("native MeshSection allocation failed")
12254        }
12255    }
12256
12257    /// Index into BONE array
12258    pub fn node_index(&self) -> u32 {
12259        // SAFETY: plain scalar read through a live handle.
12260        unsafe { ffi::whiteout_m3_M3MeshSection_get_nodeIndex(self.raw.as_ptr()) }
12261    }
12262
12263    pub fn set_node_index(&mut self, value: u32) {
12264        // SAFETY: plain scalar write through a live handle.
12265        unsafe { ffi::whiteout_m3_M3MeshSection_set_nodeIndex(self.raw.as_ptr(), value) }
12266    }
12267
12268    /// Animated bounding volume (76 bytes)
12269    /// Borrows the field in place — no copy, no allocation.
12270    pub fn bounds(&self) -> crate::support::Ref<'_, AnimRefM3Extent> {
12271        // SAFETY: an interior pointer into `self`, valid for this
12272        // borrow and never freed by the `Ref`.
12273        unsafe {
12274            crate::support::Ref::new(AnimRefM3Extent {
12275                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3MeshSection_get_bounds(
12276                    self.raw.as_ptr(),
12277                )),
12278            })
12279        }
12280    }
12281
12282    pub fn bounds_mut(&mut self) -> crate::support::RefMut<'_, AnimRefM3Extent> {
12283        // SAFETY: as above; `&mut self` guarantees exclusivity.
12284        unsafe {
12285            crate::support::RefMut::new(AnimRefM3Extent {
12286                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3MeshSection_get_bounds(
12287                    self.raw.as_ptr(),
12288                )),
12289            })
12290        }
12291    }
12292}
12293
12294impl Default for MeshSection {
12295    fn default() -> Self {
12296        Self::new()
12297    }
12298}
12299
12300/// DIV_ — Mesh division (v0–v2, 52 bytes)
12301///
12302/// Top-level mesh container grouping face indices, regions, batches, and mesh sections. Most models have a single division.
12303pub struct MeshDivision {
12304    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3MeshDivision>,
12305}
12306
12307impl Drop for MeshDivision {
12308    fn drop(&mut self) {
12309        // SAFETY: `raw` came from a native constructor and Drop runs once.
12310        unsafe { ffi::whiteout_m3_M3MeshDivision_delete(self.raw.as_ptr()) }
12311    }
12312}
12313
12314impl MeshDivision {
12315    /// # Safety
12316    /// `raw` must be a live handle this value takes ownership of.
12317    #[allow(dead_code)] // used by whichever methods return this type
12318    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3MeshDivision) -> Option<Self> {
12319        core::ptr::NonNull::new(raw).map(|raw| MeshDivision { raw })
12320    }
12321}
12322
12323// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
12324// is deliberately NOT implemented — the C++ types make no documented
12325// guarantee about concurrent use, and claiming one we haven't verified
12326// would be unsound. See `@bind thread_safe` in the plan.
12327unsafe impl Send for MeshDivision {}
12328
12329impl core::fmt::Debug for MeshDivision {
12330    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
12331        f.debug_struct("MeshDivision").finish_non_exhaustive()
12332    }
12333}
12334
12335impl MeshDivision {
12336    /// # Panics
12337    /// Panics if the native allocation fails.
12338    pub fn new() -> Self {
12339        // SAFETY: the native constructor returns a live handle; a null here
12340        // means the library is unusable.
12341        unsafe {
12342            let raw = ffi::whiteout_m3_M3MeshDivision_new();
12343            Self::from_raw(raw).expect("native MeshDivision allocation failed")
12344        }
12345    }
12346
12347    /// Triangle indices (U16_)
12348    /// Zero-copy view of the underlying `std::vector`.
12349    pub fn faces(&self) -> &[u16] {
12350        // SAFETY: `_data`/`_count` describe one contiguous C++
12351        // allocation, borrowed for as long as `self` is.
12352        unsafe {
12353            let n = ffi::whiteout_m3_M3MeshDivision_get_faces_count(self.raw.as_ptr());
12354            let p = ffi::whiteout_m3_M3MeshDivision_get_faces_data(self.raw.as_ptr());
12355            if p.is_null() || n == 0 {
12356                &[]
12357            } else {
12358                core::slice::from_raw_parts(p, n)
12359            }
12360        }
12361    }
12362
12363    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
12364    pub fn faces_mut(&mut self) -> &mut [u16] {
12365        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
12366        unsafe {
12367            let n = ffi::whiteout_m3_M3MeshDivision_get_faces_count(self.raw.as_ptr());
12368            let p = ffi::whiteout_m3_M3MeshDivision_get_faces_data(self.raw.as_ptr()) as *mut u16;
12369            if p.is_null() || n == 0 {
12370                &mut []
12371            } else {
12372                core::slice::from_raw_parts_mut(p, n)
12373            }
12374        }
12375    }
12376
12377    pub fn set_faces(&mut self, values: &[u16]) {
12378        // SAFETY: the native side copies `values` before returning.
12379        unsafe {
12380            ffi::whiteout_m3_M3MeshDivision_assign_faces(
12381                self.raw.as_ptr(),
12382                values.as_ptr() as *const _,
12383                values.len(),
12384            )
12385        }
12386    }
12387
12388    pub fn resize_faces(&mut self, count: usize) {
12389        // SAFETY: reallocation is safe here precisely because
12390        // `&mut self` means no slice borrow is outstanding.
12391        unsafe { ffi::whiteout_m3_M3MeshDivision_resize_faces(self.raw.as_ptr(), count) }
12392    }
12393
12394    /// Regions / submeshes (REGN)
12395    pub fn regions_len(&self) -> usize {
12396        // SAFETY: scalar read through a live handle.
12397        unsafe { ffi::whiteout_m3_M3MeshDivision_get_regions_count(self.raw.as_ptr()) }
12398    }
12399
12400    /// Borrows element `index` in place. `None` when out of range.
12401    pub fn regions(&self, index: usize) -> Option<crate::support::Ref<'_, Region>> {
12402        if index >= self.regions_len() {
12403            return None;
12404        }
12405        // SAFETY: index checked above; the pointer is interior to `self`.
12406        unsafe {
12407            Some(crate::support::Ref::new(Region {
12408                raw: core::ptr::NonNull::new_unchecked(
12409                    ffi::whiteout_m3_M3MeshDivision_get_regions_at(self.raw.as_ptr(), index),
12410                ),
12411            }))
12412        }
12413    }
12414
12415    pub fn regions_mut(&mut self, index: usize) -> Option<crate::support::RefMut<'_, Region>> {
12416        if index >= self.regions_len() {
12417            return None;
12418        }
12419        // SAFETY: as above; `&mut self` guarantees exclusivity.
12420        unsafe {
12421            Some(crate::support::RefMut::new(Region {
12422                raw: core::ptr::NonNull::new_unchecked(
12423                    ffi::whiteout_m3_M3MeshDivision_get_regions_at(self.raw.as_ptr(), index),
12424                ),
12425            }))
12426        }
12427    }
12428
12429    /// Iterate the elements, borrowing each in turn.
12430    pub fn regions_iter(&self) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, Region>> {
12431        (0..self.regions_len()).map(move |i| self.regions(i).expect("index below len"))
12432    }
12433
12434    pub fn resize_regions(&mut self, count: usize) {
12435        // SAFETY: exclusive access, so no borrow is outstanding.
12436        unsafe { ffi::whiteout_m3_M3MeshDivision_resize_regions(self.raw.as_ptr(), count) }
12437    }
12438
12439    /// Draw call batches (BAT_)
12440    pub fn batches_len(&self) -> usize {
12441        // SAFETY: scalar read through a live handle.
12442        unsafe { ffi::whiteout_m3_M3MeshDivision_get_batches_count(self.raw.as_ptr()) }
12443    }
12444
12445    /// Borrows element `index` in place. `None` when out of range.
12446    pub fn batches(&self, index: usize) -> Option<crate::support::Ref<'_, Batch>> {
12447        if index >= self.batches_len() {
12448            return None;
12449        }
12450        // SAFETY: index checked above; the pointer is interior to `self`.
12451        unsafe {
12452            Some(crate::support::Ref::new(Batch {
12453                raw: core::ptr::NonNull::new_unchecked(
12454                    ffi::whiteout_m3_M3MeshDivision_get_batches_at(self.raw.as_ptr(), index),
12455                ),
12456            }))
12457        }
12458    }
12459
12460    pub fn batches_mut(&mut self, index: usize) -> Option<crate::support::RefMut<'_, Batch>> {
12461        if index >= self.batches_len() {
12462            return None;
12463        }
12464        // SAFETY: as above; `&mut self` guarantees exclusivity.
12465        unsafe {
12466            Some(crate::support::RefMut::new(Batch {
12467                raw: core::ptr::NonNull::new_unchecked(
12468                    ffi::whiteout_m3_M3MeshDivision_get_batches_at(self.raw.as_ptr(), index),
12469                ),
12470            }))
12471        }
12472    }
12473
12474    /// Iterate the elements, borrowing each in turn.
12475    pub fn batches_iter(&self) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, Batch>> {
12476        (0..self.batches_len()).map(move |i| self.batches(i).expect("index below len"))
12477    }
12478
12479    pub fn resize_batches(&mut self, count: usize) {
12480        // SAFETY: exclusive access, so no borrow is outstanding.
12481        unsafe { ffi::whiteout_m3_M3MeshDivision_resize_batches(self.raw.as_ptr(), count) }
12482    }
12483
12484    /// Per-node mesh section bounds (MSEC)
12485    pub fn msec_len(&self) -> usize {
12486        // SAFETY: scalar read through a live handle.
12487        unsafe { ffi::whiteout_m3_M3MeshDivision_get_msec_count(self.raw.as_ptr()) }
12488    }
12489
12490    /// Borrows element `index` in place. `None` when out of range.
12491    pub fn msec(&self, index: usize) -> Option<crate::support::Ref<'_, MeshSection>> {
12492        if index >= self.msec_len() {
12493            return None;
12494        }
12495        // SAFETY: index checked above; the pointer is interior to `self`.
12496        unsafe {
12497            Some(crate::support::Ref::new(MeshSection {
12498                raw: core::ptr::NonNull::new_unchecked(
12499                    ffi::whiteout_m3_M3MeshDivision_get_msec_at(self.raw.as_ptr(), index),
12500                ),
12501            }))
12502        }
12503    }
12504
12505    pub fn msec_mut(&mut self, index: usize) -> Option<crate::support::RefMut<'_, MeshSection>> {
12506        if index >= self.msec_len() {
12507            return None;
12508        }
12509        // SAFETY: as above; `&mut self` guarantees exclusivity.
12510        unsafe {
12511            Some(crate::support::RefMut::new(MeshSection {
12512                raw: core::ptr::NonNull::new_unchecked(
12513                    ffi::whiteout_m3_M3MeshDivision_get_msec_at(self.raw.as_ptr(), index),
12514                ),
12515            }))
12516        }
12517    }
12518
12519    /// Iterate the elements, borrowing each in turn.
12520    pub fn msec_iter(&self) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, MeshSection>> {
12521        (0..self.msec_len()).map(move |i| self.msec(i).expect("index below len"))
12522    }
12523
12524    pub fn resize_msec(&mut self, count: usize) {
12525        // SAFETY: exclusive access, so no borrow is outstanding.
12526        unsafe { ffi::whiteout_m3_M3MeshDivision_resize_msec(self.raw.as_ptr(), count) }
12527    }
12528
12529    /// Instance count
12530    pub fn instances(&self) -> u32 {
12531        // SAFETY: plain scalar read through a live handle.
12532        unsafe { ffi::whiteout_m3_M3MeshDivision_get_instances(self.raw.as_ptr()) }
12533    }
12534
12535    pub fn set_instances(&mut self, value: u32) {
12536        // SAFETY: plain scalar write through a live handle.
12537        unsafe { ffi::whiteout_m3_M3MeshDivision_set_instances(self.raw.as_ptr(), value) }
12538    }
12539}
12540
12541impl Default for MeshDivision {
12542    fn default() -> Self {
12543        Self::new()
12544    }
12545}
12546
12547/// IREF — Initial reference / inverse bind-pose (v0, 64 bytes)
12548///
12549/// Stores the 4×4 inverse bind-pose matrix for a bone, used to transform vertices from model space into bone-local space for skinning.
12550pub struct InitialReference {
12551    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3InitialReference>,
12552}
12553
12554impl Drop for InitialReference {
12555    fn drop(&mut self) {
12556        // SAFETY: `raw` came from a native constructor and Drop runs once.
12557        unsafe { ffi::whiteout_m3_M3InitialReference_delete(self.raw.as_ptr()) }
12558    }
12559}
12560
12561impl InitialReference {
12562    /// # Safety
12563    /// `raw` must be a live handle this value takes ownership of.
12564    #[allow(dead_code)] // used by whichever methods return this type
12565    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3InitialReference) -> Option<Self> {
12566        core::ptr::NonNull::new(raw).map(|raw| InitialReference { raw })
12567    }
12568}
12569
12570// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
12571// is deliberately NOT implemented — the C++ types make no documented
12572// guarantee about concurrent use, and claiming one we haven't verified
12573// would be unsound. See `@bind thread_safe` in the plan.
12574unsafe impl Send for InitialReference {}
12575
12576impl core::fmt::Debug for InitialReference {
12577    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
12578        f.debug_struct("InitialReference").finish_non_exhaustive()
12579    }
12580}
12581
12582impl InitialReference {
12583    /// # Panics
12584    /// Panics if the native allocation fails.
12585    pub fn new() -> Self {
12586        // SAFETY: the native constructor returns a live handle; a null here
12587        // means the library is unusable.
12588        unsafe {
12589            let raw = ffi::whiteout_m3_M3InitialReference_new();
12590            Self::from_raw(raw).expect("native InitialReference allocation failed")
12591        }
12592    }
12593}
12594
12595impl Default for InitialReference {
12596    fn default() -> Self {
12597        Self::new()
12598    }
12599}
12600
12601/// ATT_ — Attachment point (v0–v1, 20 bytes)
12602///
12603/// Named bone location used by the engine to attach effects, weapons, or other models to specific skeleton bones.
12604pub struct AttachmentPoint {
12605    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3AttachmentPoint>,
12606}
12607
12608impl Drop for AttachmentPoint {
12609    fn drop(&mut self) {
12610        // SAFETY: `raw` came from a native constructor and Drop runs once.
12611        unsafe { ffi::whiteout_m3_M3AttachmentPoint_delete(self.raw.as_ptr()) }
12612    }
12613}
12614
12615impl AttachmentPoint {
12616    /// # Safety
12617    /// `raw` must be a live handle this value takes ownership of.
12618    #[allow(dead_code)] // used by whichever methods return this type
12619    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3AttachmentPoint) -> Option<Self> {
12620        core::ptr::NonNull::new(raw).map(|raw| AttachmentPoint { raw })
12621    }
12622}
12623
12624// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
12625// is deliberately NOT implemented — the C++ types make no documented
12626// guarantee about concurrent use, and claiming one we haven't verified
12627// would be unsound. See `@bind thread_safe` in the plan.
12628unsafe impl Send for AttachmentPoint {}
12629
12630impl core::fmt::Debug for AttachmentPoint {
12631    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
12632        f.debug_struct("AttachmentPoint").finish_non_exhaustive()
12633    }
12634}
12635
12636impl AttachmentPoint {
12637    /// # Panics
12638    /// Panics if the native allocation fails.
12639    pub fn new() -> Self {
12640        // SAFETY: the native constructor returns a live handle; a null here
12641        // means the library is unusable.
12642        unsafe {
12643            let raw = ffi::whiteout_m3_M3AttachmentPoint_new();
12644            Self::from_raw(raw).expect("native AttachmentPoint allocation failed")
12645        }
12646    }
12647
12648    /// Unknown field
12649    pub fn unknown(&self) -> u32 {
12650        // SAFETY: plain scalar read through a live handle.
12651        unsafe { ffi::whiteout_m3_M3AttachmentPoint_get_unknown(self.raw.as_ptr()) }
12652    }
12653
12654    pub fn set_unknown(&mut self, value: u32) {
12655        // SAFETY: plain scalar write through a live handle.
12656        unsafe { ffi::whiteout_m3_M3AttachmentPoint_set_unknown(self.raw.as_ptr(), value) }
12657    }
12658
12659    /// Attachment point name (`Ref<CHAR>`)
12660    pub fn name(&self) -> String {
12661        // SAFETY: the native side hands over an owned CString.
12662        unsafe {
12663            crate::support::take_string(ffi::whiteout_m3_M3AttachmentPoint_get_name(
12664                self.raw.as_ptr(),
12665            ))
12666        }
12667    }
12668
12669    pub fn set_name(&mut self, value: &str) {
12670        let value = std::ffi::CString::new(value).unwrap_or_default();
12671        // SAFETY: the pointer outlives the call.
12672        unsafe { ffi::whiteout_m3_M3AttachmentPoint_set_name(self.raw.as_ptr(), value.as_ptr()) }
12673    }
12674
12675    /// Index into BONE array
12676    pub fn bone_index(&self) -> u32 {
12677        // SAFETY: plain scalar read through a live handle.
12678        unsafe { ffi::whiteout_m3_M3AttachmentPoint_get_boneIndex(self.raw.as_ptr()) }
12679    }
12680
12681    pub fn set_bone_index(&mut self, value: u32) {
12682        // SAFETY: plain scalar write through a live handle.
12683        unsafe { ffi::whiteout_m3_M3AttachmentPoint_set_boneIndex(self.raw.as_ptr(), value) }
12684    }
12685}
12686
12687impl Default for AttachmentPoint {
12688    fn default() -> Self {
12689        Self::new()
12690    }
12691}
12692
12693/// SSGS — Hit-test shape (v0–v1, 108 bytes)
12694///
12695/// Defines a collision / selection volume (box, sphere, capsule, cylinder, or mesh) attached to a bone. Used for both tight and fuzzy hit testing.
12696pub struct HitTestShape {
12697    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3HitTestShape>,
12698}
12699
12700impl Drop for HitTestShape {
12701    fn drop(&mut self) {
12702        // SAFETY: `raw` came from a native constructor and Drop runs once.
12703        unsafe { ffi::whiteout_m3_M3HitTestShape_delete(self.raw.as_ptr()) }
12704    }
12705}
12706
12707impl HitTestShape {
12708    /// # Safety
12709    /// `raw` must be a live handle this value takes ownership of.
12710    #[allow(dead_code)] // used by whichever methods return this type
12711    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3HitTestShape) -> Option<Self> {
12712        core::ptr::NonNull::new(raw).map(|raw| HitTestShape { raw })
12713    }
12714}
12715
12716// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
12717// is deliberately NOT implemented — the C++ types make no documented
12718// guarantee about concurrent use, and claiming one we haven't verified
12719// would be unsound. See `@bind thread_safe` in the plan.
12720unsafe impl Send for HitTestShape {}
12721
12722impl core::fmt::Debug for HitTestShape {
12723    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
12724        f.debug_struct("HitTestShape").finish_non_exhaustive()
12725    }
12726}
12727
12728impl HitTestShape {
12729    /// # Panics
12730    /// Panics if the native allocation fails.
12731    pub fn new() -> Self {
12732        // SAFETY: the native constructor returns a live handle; a null here
12733        // means the library is unusable.
12734        unsafe {
12735            let raw = ffi::whiteout_m3_M3HitTestShape_new();
12736            Self::from_raw(raw).expect("native HitTestShape allocation failed")
12737        }
12738    }
12739
12740    /// Shape type (box/sphere/capsule/cylinder/mesh)
12741    pub fn shape_type(&self) -> HitTestShapeType {
12742        // SAFETY: scalar read; the discriminant is validated below.
12743        unsafe { ffi::whiteout_m3_M3HitTestShape_get_shapeType(self.raw.as_ptr()) }
12744            .try_into()
12745            .expect("unknown enum discriminant from the native library")
12746    }
12747
12748    pub fn set_shape_type(&mut self, value: HitTestShapeType) {
12749        // SAFETY: scalar write through a live handle.
12750        unsafe { ffi::whiteout_m3_M3HitTestShape_set_shapeType(self.raw.as_ptr(), value as i32) }
12751    }
12752
12753    /// Index into BONE array
12754    pub fn bone_index(&self) -> u16 {
12755        // SAFETY: plain scalar read through a live handle.
12756        unsafe { ffi::whiteout_m3_M3HitTestShape_get_boneIndex(self.raw.as_ptr()) }
12757    }
12758
12759    pub fn set_bone_index(&mut self, value: u16) {
12760        // SAFETY: plain scalar write through a live handle.
12761        unsafe { ffi::whiteout_m3_M3HitTestShape_set_boneIndex(self.raw.as_ptr(), value) }
12762    }
12763
12764    /// Alignment padding
12765    pub fn padding(&self) -> u16 {
12766        // SAFETY: plain scalar read through a live handle.
12767        unsafe { ffi::whiteout_m3_M3HitTestShape_get_padding(self.raw.as_ptr()) }
12768    }
12769
12770    pub fn set_padding(&mut self, value: u16) {
12771        // SAFETY: plain scalar write through a live handle.
12772        unsafe { ffi::whiteout_m3_M3HitTestShape_set_padding(self.raw.as_ptr(), value) }
12773    }
12774
12775    /// Mesh vertex positions (VEC3, mesh type only)
12776    /// Zero-copy view of the underlying `std::vector`.
12777    pub fn vertex_positions(&self) -> &[crate::math::Vector3f] {
12778        // SAFETY: `_data`/`_count` describe one contiguous C++
12779        // allocation, borrowed for as long as `self` is.
12780        unsafe {
12781            let n = ffi::whiteout_m3_M3HitTestShape_get_vertexPositions_count(self.raw.as_ptr());
12782            let p = ffi::whiteout_m3_M3HitTestShape_get_vertexPositions_data(self.raw.as_ptr())
12783                as *const crate::math::Vector3f;
12784            if p.is_null() || n == 0 {
12785                &[]
12786            } else {
12787                core::slice::from_raw_parts(p, n)
12788            }
12789        }
12790    }
12791
12792    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
12793    pub fn vertex_positions_mut(&mut self) -> &mut [crate::math::Vector3f] {
12794        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
12795        unsafe {
12796            let n = ffi::whiteout_m3_M3HitTestShape_get_vertexPositions_count(self.raw.as_ptr());
12797            let p = ffi::whiteout_m3_M3HitTestShape_get_vertexPositions_data(self.raw.as_ptr())
12798                as *const crate::math::Vector3f as *mut crate::math::Vector3f;
12799            if p.is_null() || n == 0 {
12800                &mut []
12801            } else {
12802                core::slice::from_raw_parts_mut(p, n)
12803            }
12804        }
12805    }
12806
12807    pub fn set_vertex_positions(&mut self, values: &[crate::math::Vector3f]) {
12808        // SAFETY: the native side copies `values` before returning.
12809        unsafe {
12810            ffi::whiteout_m3_M3HitTestShape_assign_vertexPositions(
12811                self.raw.as_ptr(),
12812                values.as_ptr() as *const _,
12813                values.len(),
12814            )
12815        }
12816    }
12817
12818    pub fn resize_vertex_positions(&mut self, count: usize) {
12819        // SAFETY: reallocation is safe here precisely because
12820        // `&mut self` means no slice borrow is outstanding.
12821        unsafe { ffi::whiteout_m3_M3HitTestShape_resize_vertexPositions(self.raw.as_ptr(), count) }
12822    }
12823
12824    /// Mesh triangle indices (U16_, mesh type only)
12825    /// Zero-copy view of the underlying `std::vector`.
12826    pub fn face_indices(&self) -> &[u16] {
12827        // SAFETY: `_data`/`_count` describe one contiguous C++
12828        // allocation, borrowed for as long as `self` is.
12829        unsafe {
12830            let n = ffi::whiteout_m3_M3HitTestShape_get_faceIndices_count(self.raw.as_ptr());
12831            let p = ffi::whiteout_m3_M3HitTestShape_get_faceIndices_data(self.raw.as_ptr());
12832            if p.is_null() || n == 0 {
12833                &[]
12834            } else {
12835                core::slice::from_raw_parts(p, n)
12836            }
12837        }
12838    }
12839
12840    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
12841    pub fn face_indices_mut(&mut self) -> &mut [u16] {
12842        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
12843        unsafe {
12844            let n = ffi::whiteout_m3_M3HitTestShape_get_faceIndices_count(self.raw.as_ptr());
12845            let p =
12846                ffi::whiteout_m3_M3HitTestShape_get_faceIndices_data(self.raw.as_ptr()) as *mut u16;
12847            if p.is_null() || n == 0 {
12848                &mut []
12849            } else {
12850                core::slice::from_raw_parts_mut(p, n)
12851            }
12852        }
12853    }
12854
12855    pub fn set_face_indices(&mut self, values: &[u16]) {
12856        // SAFETY: the native side copies `values` before returning.
12857        unsafe {
12858            ffi::whiteout_m3_M3HitTestShape_assign_faceIndices(
12859                self.raw.as_ptr(),
12860                values.as_ptr() as *const _,
12861                values.len(),
12862            )
12863        }
12864    }
12865
12866    pub fn resize_face_indices(&mut self, count: usize) {
12867        // SAFETY: reallocation is safe here precisely because
12868        // `&mut self` means no slice borrow is outstanding.
12869        unsafe { ffi::whiteout_m3_M3HitTestShape_resize_faceIndices(self.raw.as_ptr(), count) }
12870    }
12871
12872    /// X dimension (radius for sphere/capsule)
12873    pub fn size_x(&self) -> f32 {
12874        // SAFETY: plain scalar read through a live handle.
12875        unsafe { ffi::whiteout_m3_M3HitTestShape_get_sizeX(self.raw.as_ptr()) }
12876    }
12877
12878    pub fn set_size_x(&mut self, value: f32) {
12879        // SAFETY: plain scalar write through a live handle.
12880        unsafe { ffi::whiteout_m3_M3HitTestShape_set_sizeX(self.raw.as_ptr(), value) }
12881    }
12882
12883    /// Y dimension (height for capsule/cylinder)
12884    pub fn size_y(&self) -> f32 {
12885        // SAFETY: plain scalar read through a live handle.
12886        unsafe { ffi::whiteout_m3_M3HitTestShape_get_sizeY(self.raw.as_ptr()) }
12887    }
12888
12889    pub fn set_size_y(&mut self, value: f32) {
12890        // SAFETY: plain scalar write through a live handle.
12891        unsafe { ffi::whiteout_m3_M3HitTestShape_set_sizeY(self.raw.as_ptr(), value) }
12892    }
12893
12894    /// Z dimension
12895    pub fn size_z(&self) -> f32 {
12896        // SAFETY: plain scalar read through a live handle.
12897        unsafe { ffi::whiteout_m3_M3HitTestShape_get_sizeZ(self.raw.as_ptr()) }
12898    }
12899
12900    pub fn set_size_z(&mut self, value: f32) {
12901        // SAFETY: plain scalar write through a live handle.
12902        unsafe { ffi::whiteout_m3_M3HitTestShape_set_sizeZ(self.raw.as_ptr(), value) }
12903    }
12904}
12905
12906impl Default for HitTestShape {
12907    fn default() -> Self {
12908        Self::new()
12909    }
12910}
12911
12912/// ATVL — Attachment volume (v0, 116 bytes)
12913///
12914/// Like HitTestShape but with two bone indices for attachment-point volumes.
12915pub struct AttachmentVolume {
12916    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3AttachmentVolume>,
12917}
12918
12919impl Drop for AttachmentVolume {
12920    fn drop(&mut self) {
12921        // SAFETY: `raw` came from a native constructor and Drop runs once.
12922        unsafe { ffi::whiteout_m3_M3AttachmentVolume_delete(self.raw.as_ptr()) }
12923    }
12924}
12925
12926impl AttachmentVolume {
12927    /// # Safety
12928    /// `raw` must be a live handle this value takes ownership of.
12929    #[allow(dead_code)] // used by whichever methods return this type
12930    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3AttachmentVolume) -> Option<Self> {
12931        core::ptr::NonNull::new(raw).map(|raw| AttachmentVolume { raw })
12932    }
12933}
12934
12935// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
12936// is deliberately NOT implemented — the C++ types make no documented
12937// guarantee about concurrent use, and claiming one we haven't verified
12938// would be unsound. See `@bind thread_safe` in the plan.
12939unsafe impl Send for AttachmentVolume {}
12940
12941impl core::fmt::Debug for AttachmentVolume {
12942    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
12943        f.debug_struct("AttachmentVolume").finish_non_exhaustive()
12944    }
12945}
12946
12947impl AttachmentVolume {
12948    /// # Panics
12949    /// Panics if the native allocation fails.
12950    pub fn new() -> Self {
12951        // SAFETY: the native constructor returns a live handle; a null here
12952        // means the library is unusable.
12953        unsafe {
12954            let raw = ffi::whiteout_m3_M3AttachmentVolume_new();
12955            Self::from_raw(raw).expect("native AttachmentVolume allocation failed")
12956        }
12957    }
12958
12959    /// First bone index
12960    pub fn bone_1(&self) -> u32 {
12961        // SAFETY: plain scalar read through a live handle.
12962        unsafe { ffi::whiteout_m3_M3AttachmentVolume_get_bone1(self.raw.as_ptr()) }
12963    }
12964
12965    pub fn set_bone_1(&mut self, value: u32) {
12966        // SAFETY: plain scalar write through a live handle.
12967        unsafe { ffi::whiteout_m3_M3AttachmentVolume_set_bone1(self.raw.as_ptr(), value) }
12968    }
12969
12970    /// Second bone index
12971    pub fn bone_2(&self) -> u32 {
12972        // SAFETY: plain scalar read through a live handle.
12973        unsafe { ffi::whiteout_m3_M3AttachmentVolume_get_bone2(self.raw.as_ptr()) }
12974    }
12975
12976    pub fn set_bone_2(&mut self, value: u32) {
12977        // SAFETY: plain scalar write through a live handle.
12978        unsafe { ffi::whiteout_m3_M3AttachmentVolume_set_bone2(self.raw.as_ptr(), value) }
12979    }
12980
12981    /// Shape type
12982    pub fn shape_type(&self) -> HitTestShapeType {
12983        // SAFETY: scalar read; the discriminant is validated below.
12984        unsafe { ffi::whiteout_m3_M3AttachmentVolume_get_shapeType(self.raw.as_ptr()) }
12985            .try_into()
12986            .expect("unknown enum discriminant from the native library")
12987    }
12988
12989    pub fn set_shape_type(&mut self, value: HitTestShapeType) {
12990        // SAFETY: scalar write through a live handle.
12991        unsafe {
12992            ffi::whiteout_m3_M3AttachmentVolume_set_shapeType(self.raw.as_ptr(), value as i32)
12993        }
12994    }
12995
12996    /// Primary bone index
12997    pub fn bone_index(&self) -> u16 {
12998        // SAFETY: plain scalar read through a live handle.
12999        unsafe { ffi::whiteout_m3_M3AttachmentVolume_get_boneIndex(self.raw.as_ptr()) }
13000    }
13001
13002    pub fn set_bone_index(&mut self, value: u16) {
13003        // SAFETY: plain scalar write through a live handle.
13004        unsafe { ffi::whiteout_m3_M3AttachmentVolume_set_boneIndex(self.raw.as_ptr(), value) }
13005    }
13006
13007    /// Alignment padding
13008    pub fn padding(&self) -> u16 {
13009        // SAFETY: plain scalar read through a live handle.
13010        unsafe { ffi::whiteout_m3_M3AttachmentVolume_get_padding(self.raw.as_ptr()) }
13011    }
13012
13013    pub fn set_padding(&mut self, value: u16) {
13014        // SAFETY: plain scalar write through a live handle.
13015        unsafe { ffi::whiteout_m3_M3AttachmentVolume_set_padding(self.raw.as_ptr(), value) }
13016    }
13017
13018    /// Mesh vertex positions (VEC3)
13019    /// Zero-copy view of the underlying `std::vector`.
13020    pub fn vertex_positions(&self) -> &[crate::math::Vector3f] {
13021        // SAFETY: `_data`/`_count` describe one contiguous C++
13022        // allocation, borrowed for as long as `self` is.
13023        unsafe {
13024            let n =
13025                ffi::whiteout_m3_M3AttachmentVolume_get_vertexPositions_count(self.raw.as_ptr());
13026            let p = ffi::whiteout_m3_M3AttachmentVolume_get_vertexPositions_data(self.raw.as_ptr())
13027                as *const crate::math::Vector3f;
13028            if p.is_null() || n == 0 {
13029                &[]
13030            } else {
13031                core::slice::from_raw_parts(p, n)
13032            }
13033        }
13034    }
13035
13036    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
13037    pub fn vertex_positions_mut(&mut self) -> &mut [crate::math::Vector3f] {
13038        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
13039        unsafe {
13040            let n =
13041                ffi::whiteout_m3_M3AttachmentVolume_get_vertexPositions_count(self.raw.as_ptr());
13042            let p = ffi::whiteout_m3_M3AttachmentVolume_get_vertexPositions_data(self.raw.as_ptr())
13043                as *const crate::math::Vector3f as *mut crate::math::Vector3f;
13044            if p.is_null() || n == 0 {
13045                &mut []
13046            } else {
13047                core::slice::from_raw_parts_mut(p, n)
13048            }
13049        }
13050    }
13051
13052    pub fn set_vertex_positions(&mut self, values: &[crate::math::Vector3f]) {
13053        // SAFETY: the native side copies `values` before returning.
13054        unsafe {
13055            ffi::whiteout_m3_M3AttachmentVolume_assign_vertexPositions(
13056                self.raw.as_ptr(),
13057                values.as_ptr() as *const _,
13058                values.len(),
13059            )
13060        }
13061    }
13062
13063    pub fn resize_vertex_positions(&mut self, count: usize) {
13064        // SAFETY: reallocation is safe here precisely because
13065        // `&mut self` means no slice borrow is outstanding.
13066        unsafe {
13067            ffi::whiteout_m3_M3AttachmentVolume_resize_vertexPositions(self.raw.as_ptr(), count)
13068        }
13069    }
13070
13071    /// Mesh triangle indices (U16_)
13072    /// Zero-copy view of the underlying `std::vector`.
13073    pub fn face_indices(&self) -> &[u16] {
13074        // SAFETY: `_data`/`_count` describe one contiguous C++
13075        // allocation, borrowed for as long as `self` is.
13076        unsafe {
13077            let n = ffi::whiteout_m3_M3AttachmentVolume_get_faceIndices_count(self.raw.as_ptr());
13078            let p = ffi::whiteout_m3_M3AttachmentVolume_get_faceIndices_data(self.raw.as_ptr());
13079            if p.is_null() || n == 0 {
13080                &[]
13081            } else {
13082                core::slice::from_raw_parts(p, n)
13083            }
13084        }
13085    }
13086
13087    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
13088    pub fn face_indices_mut(&mut self) -> &mut [u16] {
13089        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
13090        unsafe {
13091            let n = ffi::whiteout_m3_M3AttachmentVolume_get_faceIndices_count(self.raw.as_ptr());
13092            let p = ffi::whiteout_m3_M3AttachmentVolume_get_faceIndices_data(self.raw.as_ptr())
13093                as *mut u16;
13094            if p.is_null() || n == 0 {
13095                &mut []
13096            } else {
13097                core::slice::from_raw_parts_mut(p, n)
13098            }
13099        }
13100    }
13101
13102    pub fn set_face_indices(&mut self, values: &[u16]) {
13103        // SAFETY: the native side copies `values` before returning.
13104        unsafe {
13105            ffi::whiteout_m3_M3AttachmentVolume_assign_faceIndices(
13106                self.raw.as_ptr(),
13107                values.as_ptr() as *const _,
13108                values.len(),
13109            )
13110        }
13111    }
13112
13113    pub fn resize_face_indices(&mut self, count: usize) {
13114        // SAFETY: reallocation is safe here precisely because
13115        // `&mut self` means no slice borrow is outstanding.
13116        unsafe { ffi::whiteout_m3_M3AttachmentVolume_resize_faceIndices(self.raw.as_ptr(), count) }
13117    }
13118
13119    /// X dimension
13120    pub fn size_x(&self) -> f32 {
13121        // SAFETY: plain scalar read through a live handle.
13122        unsafe { ffi::whiteout_m3_M3AttachmentVolume_get_sizeX(self.raw.as_ptr()) }
13123    }
13124
13125    pub fn set_size_x(&mut self, value: f32) {
13126        // SAFETY: plain scalar write through a live handle.
13127        unsafe { ffi::whiteout_m3_M3AttachmentVolume_set_sizeX(self.raw.as_ptr(), value) }
13128    }
13129
13130    /// Y dimension
13131    pub fn size_y(&self) -> f32 {
13132        // SAFETY: plain scalar read through a live handle.
13133        unsafe { ffi::whiteout_m3_M3AttachmentVolume_get_sizeY(self.raw.as_ptr()) }
13134    }
13135
13136    pub fn set_size_y(&mut self, value: f32) {
13137        // SAFETY: plain scalar write through a live handle.
13138        unsafe { ffi::whiteout_m3_M3AttachmentVolume_set_sizeY(self.raw.as_ptr(), value) }
13139    }
13140
13141    /// Z dimension
13142    pub fn size_z(&self) -> f32 {
13143        // SAFETY: plain scalar read through a live handle.
13144        unsafe { ffi::whiteout_m3_M3AttachmentVolume_get_sizeZ(self.raw.as_ptr()) }
13145    }
13146
13147    pub fn set_size_z(&mut self, value: f32) {
13148        // SAFETY: plain scalar write through a live handle.
13149        unsafe { ffi::whiteout_m3_M3AttachmentVolume_set_sizeZ(self.raw.as_ptr(), value) }
13150    }
13151}
13152
13153impl Default for AttachmentVolume {
13154    fn default() -> Self {
13155        Self::new()
13156    }
13157}
13158
13159/// TRGD — Trigger data (v0, 24 bytes)
13160///
13161/// Named trigger with associated data indices for gameplay events.
13162pub struct TriggerData {
13163    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3TriggerData>,
13164}
13165
13166impl Drop for TriggerData {
13167    fn drop(&mut self) {
13168        // SAFETY: `raw` came from a native constructor and Drop runs once.
13169        unsafe { ffi::whiteout_m3_M3TriggerData_delete(self.raw.as_ptr()) }
13170    }
13171}
13172
13173impl TriggerData {
13174    /// # Safety
13175    /// `raw` must be a live handle this value takes ownership of.
13176    #[allow(dead_code)] // used by whichever methods return this type
13177    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3TriggerData) -> Option<Self> {
13178        core::ptr::NonNull::new(raw).map(|raw| TriggerData { raw })
13179    }
13180}
13181
13182// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
13183// is deliberately NOT implemented — the C++ types make no documented
13184// guarantee about concurrent use, and claiming one we haven't verified
13185// would be unsound. See `@bind thread_safe` in the plan.
13186unsafe impl Send for TriggerData {}
13187
13188impl core::fmt::Debug for TriggerData {
13189    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
13190        f.debug_struct("TriggerData").finish_non_exhaustive()
13191    }
13192}
13193
13194impl TriggerData {
13195    /// # Panics
13196    /// Panics if the native allocation fails.
13197    pub fn new() -> Self {
13198        // SAFETY: the native constructor returns a live handle; a null here
13199        // means the library is unusable.
13200        unsafe {
13201            let raw = ffi::whiteout_m3_M3TriggerData_new();
13202            Self::from_raw(raw).expect("native TriggerData allocation failed")
13203        }
13204    }
13205
13206    /// Data index array (U32_)
13207    /// Zero-copy view of the underlying `std::vector`.
13208    pub fn data_indices(&self) -> &[u32] {
13209        // SAFETY: `_data`/`_count` describe one contiguous C++
13210        // allocation, borrowed for as long as `self` is.
13211        unsafe {
13212            let n = ffi::whiteout_m3_M3TriggerData_get_dataIndices_count(self.raw.as_ptr());
13213            let p = ffi::whiteout_m3_M3TriggerData_get_dataIndices_data(self.raw.as_ptr());
13214            if p.is_null() || n == 0 {
13215                &[]
13216            } else {
13217                core::slice::from_raw_parts(p, n)
13218            }
13219        }
13220    }
13221
13222    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
13223    pub fn data_indices_mut(&mut self) -> &mut [u32] {
13224        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
13225        unsafe {
13226            let n = ffi::whiteout_m3_M3TriggerData_get_dataIndices_count(self.raw.as_ptr());
13227            let p =
13228                ffi::whiteout_m3_M3TriggerData_get_dataIndices_data(self.raw.as_ptr()) as *mut u32;
13229            if p.is_null() || n == 0 {
13230                &mut []
13231            } else {
13232                core::slice::from_raw_parts_mut(p, n)
13233            }
13234        }
13235    }
13236
13237    pub fn set_data_indices(&mut self, values: &[u32]) {
13238        // SAFETY: the native side copies `values` before returning.
13239        unsafe {
13240            ffi::whiteout_m3_M3TriggerData_assign_dataIndices(
13241                self.raw.as_ptr(),
13242                values.as_ptr() as *const _,
13243                values.len(),
13244            )
13245        }
13246    }
13247
13248    pub fn resize_data_indices(&mut self, count: usize) {
13249        // SAFETY: reallocation is safe here precisely because
13250        // `&mut self` means no slice borrow is outstanding.
13251        unsafe { ffi::whiteout_m3_M3TriggerData_resize_dataIndices(self.raw.as_ptr(), count) }
13252    }
13253
13254    /// Trigger name (`Ref<CHAR>`)
13255    pub fn name(&self) -> String {
13256        // SAFETY: the native side hands over an owned CString.
13257        unsafe {
13258            crate::support::take_string(ffi::whiteout_m3_M3TriggerData_get_name(self.raw.as_ptr()))
13259        }
13260    }
13261
13262    pub fn set_name(&mut self, value: &str) {
13263        let value = std::ffi::CString::new(value).unwrap_or_default();
13264        // SAFETY: the pointer outlives the call.
13265        unsafe { ffi::whiteout_m3_M3TriggerData_set_name(self.raw.as_ptr(), value.as_ptr()) }
13266    }
13267}
13268
13269impl Default for TriggerData {
13270    fn default() -> Self {
13271        Self::new()
13272    }
13273}
13274
13275/// PATU — Turret behavior (v0–v4, 152 bytes)
13276///
13277/// Configures turret rotation constraints for a bone with yaw/pitch limits, weights, and an optional main-turret flag.
13278pub struct TurretBehavior {
13279    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3TurretBehavior>,
13280}
13281
13282impl Drop for TurretBehavior {
13283    fn drop(&mut self) {
13284        // SAFETY: `raw` came from a native constructor and Drop runs once.
13285        unsafe { ffi::whiteout_m3_M3TurretBehavior_delete(self.raw.as_ptr()) }
13286    }
13287}
13288
13289impl TurretBehavior {
13290    /// # Safety
13291    /// `raw` must be a live handle this value takes ownership of.
13292    #[allow(dead_code)] // used by whichever methods return this type
13293    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3TurretBehavior) -> Option<Self> {
13294        core::ptr::NonNull::new(raw).map(|raw| TurretBehavior { raw })
13295    }
13296}
13297
13298// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
13299// is deliberately NOT implemented — the C++ types make no documented
13300// guarantee about concurrent use, and claiming one we haven't verified
13301// would be unsound. See `@bind thread_safe` in the plan.
13302unsafe impl Send for TurretBehavior {}
13303
13304impl core::fmt::Debug for TurretBehavior {
13305    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
13306        f.debug_struct("TurretBehavior").finish_non_exhaustive()
13307    }
13308}
13309
13310impl TurretBehavior {
13311    /// # Panics
13312    /// Panics if the native allocation fails.
13313    pub fn new() -> Self {
13314        // SAFETY: the native constructor returns a live handle; a null here
13315        // means the library is unusable.
13316        unsafe {
13317            let raw = ffi::whiteout_m3_M3TurretBehavior_new();
13318            Self::from_raw(raw).expect("native TurretBehavior allocation failed")
13319        }
13320    }
13321
13322    /// Unknown vector 1
13323    pub fn unknown_1(&self) -> crate::math::Vector4f {
13324        // SAFETY: the getter returns an interior pointer to a
13325        // layout-identical POD; we copy it out immediately.
13326        unsafe {
13327            *(ffi::whiteout_m3_M3TurretBehavior_get_unknown1(self.raw.as_ptr())
13328                as *const crate::math::Vector4f)
13329        }
13330    }
13331
13332    pub fn set_unknown_1(&mut self, value: crate::math::Vector4f) {
13333        // SAFETY: as above, in the other direction.
13334        unsafe {
13335            ffi::whiteout_m3_M3TurretBehavior_set_unknown1(
13336                self.raw.as_ptr(),
13337                &value as *const crate::math::Vector4f as *const _,
13338            )
13339        }
13340    }
13341
13342    /// Unknown vector 2
13343    pub fn unknown_2(&self) -> crate::math::Vector4f {
13344        // SAFETY: the getter returns an interior pointer to a
13345        // layout-identical POD; we copy it out immediately.
13346        unsafe {
13347            *(ffi::whiteout_m3_M3TurretBehavior_get_unknown2(self.raw.as_ptr())
13348                as *const crate::math::Vector4f)
13349        }
13350    }
13351
13352    pub fn set_unknown_2(&mut self, value: crate::math::Vector4f) {
13353        // SAFETY: as above, in the other direction.
13354        unsafe {
13355            ffi::whiteout_m3_M3TurretBehavior_set_unknown2(
13356                self.raw.as_ptr(),
13357                &value as *const crate::math::Vector4f as *const _,
13358            )
13359        }
13360    }
13361
13362    /// Index into BONE array
13363    pub fn bone_index(&self) -> u16 {
13364        // SAFETY: plain scalar read through a live handle.
13365        unsafe { ffi::whiteout_m3_M3TurretBehavior_get_boneIndex(self.raw.as_ptr()) }
13366    }
13367
13368    pub fn set_bone_index(&mut self, value: u16) {
13369        // SAFETY: plain scalar write through a live handle.
13370        unsafe { ffi::whiteout_m3_M3TurretBehavior_set_boneIndex(self.raw.as_ptr(), value) }
13371    }
13372
13373    /// Non-zero if this is the main turret
13374    pub fn use_as_main_turret(&self) -> u8 {
13375        // SAFETY: plain scalar read through a live handle.
13376        unsafe { ffi::whiteout_m3_M3TurretBehavior_get_useAsMainTurret(self.raw.as_ptr()) }
13377    }
13378
13379    pub fn set_use_as_main_turret(&mut self, value: u8) {
13380        // SAFETY: plain scalar write through a live handle.
13381        unsafe { ffi::whiteout_m3_M3TurretBehavior_set_useAsMainTurret(self.raw.as_ptr(), value) }
13382    }
13383
13384    /// Turret group identifier
13385    pub fn turret_group_id(&self) -> u8 {
13386        // SAFETY: plain scalar read through a live handle.
13387        unsafe { ffi::whiteout_m3_M3TurretBehavior_get_turretGroupId(self.raw.as_ptr()) }
13388    }
13389
13390    pub fn set_turret_group_id(&mut self, value: u8) {
13391        // SAFETY: plain scalar write through a live handle.
13392        unsafe { ffi::whiteout_m3_M3TurretBehavior_set_turretGroupId(self.raw.as_ptr(), value) }
13393    }
13394
13395    /// Enable yaw limits
13396    pub fn yaw_limited(&self) -> u32 {
13397        // SAFETY: plain scalar read through a live handle.
13398        unsafe { ffi::whiteout_m3_M3TurretBehavior_get_yawLimited(self.raw.as_ptr()) }
13399    }
13400
13401    pub fn set_yaw_limited(&mut self, value: u32) {
13402        // SAFETY: plain scalar write through a live handle.
13403        unsafe { ffi::whiteout_m3_M3TurretBehavior_set_yawLimited(self.raw.as_ptr(), value) }
13404    }
13405
13406    /// Minimum yaw angle (radians)
13407    pub fn yaw_min(&self) -> f32 {
13408        // SAFETY: plain scalar read through a live handle.
13409        unsafe { ffi::whiteout_m3_M3TurretBehavior_get_yawMin(self.raw.as_ptr()) }
13410    }
13411
13412    pub fn set_yaw_min(&mut self, value: f32) {
13413        // SAFETY: plain scalar write through a live handle.
13414        unsafe { ffi::whiteout_m3_M3TurretBehavior_set_yawMin(self.raw.as_ptr(), value) }
13415    }
13416
13417    /// Maximum yaw angle (radians)
13418    pub fn yaw_max(&self) -> f32 {
13419        // SAFETY: plain scalar read through a live handle.
13420        unsafe { ffi::whiteout_m3_M3TurretBehavior_get_yawMax(self.raw.as_ptr()) }
13421    }
13422
13423    pub fn set_yaw_max(&mut self, value: f32) {
13424        // SAFETY: plain scalar write through a live handle.
13425        unsafe { ffi::whiteout_m3_M3TurretBehavior_set_yawMax(self.raw.as_ptr(), value) }
13426    }
13427
13428    /// Yaw rotation weight
13429    pub fn yaw_weight(&self) -> f32 {
13430        // SAFETY: plain scalar read through a live handle.
13431        unsafe { ffi::whiteout_m3_M3TurretBehavior_get_yawWeight(self.raw.as_ptr()) }
13432    }
13433
13434    pub fn set_yaw_weight(&mut self, value: f32) {
13435        // SAFETY: plain scalar write through a live handle.
13436        unsafe { ffi::whiteout_m3_M3TurretBehavior_set_yawWeight(self.raw.as_ptr(), value) }
13437    }
13438
13439    /// Enable pitch limits
13440    pub fn pitch_limited(&self) -> u32 {
13441        // SAFETY: plain scalar read through a live handle.
13442        unsafe { ffi::whiteout_m3_M3TurretBehavior_get_pitchLimited(self.raw.as_ptr()) }
13443    }
13444
13445    pub fn set_pitch_limited(&mut self, value: u32) {
13446        // SAFETY: plain scalar write through a live handle.
13447        unsafe { ffi::whiteout_m3_M3TurretBehavior_set_pitchLimited(self.raw.as_ptr(), value) }
13448    }
13449
13450    /// Minimum pitch angle (radians)
13451    pub fn pitch_min(&self) -> f32 {
13452        // SAFETY: plain scalar read through a live handle.
13453        unsafe { ffi::whiteout_m3_M3TurretBehavior_get_pitchMin(self.raw.as_ptr()) }
13454    }
13455
13456    pub fn set_pitch_min(&mut self, value: f32) {
13457        // SAFETY: plain scalar write through a live handle.
13458        unsafe { ffi::whiteout_m3_M3TurretBehavior_set_pitchMin(self.raw.as_ptr(), value) }
13459    }
13460
13461    /// Maximum pitch angle (radians)
13462    pub fn pitch_max(&self) -> f32 {
13463        // SAFETY: plain scalar read through a live handle.
13464        unsafe { ffi::whiteout_m3_M3TurretBehavior_get_pitchMax(self.raw.as_ptr()) }
13465    }
13466
13467    pub fn set_pitch_max(&mut self, value: f32) {
13468        // SAFETY: plain scalar write through a live handle.
13469        unsafe { ffi::whiteout_m3_M3TurretBehavior_set_pitchMax(self.raw.as_ptr(), value) }
13470    }
13471
13472    /// Pitch rotation weight
13473    pub fn pitch_weight(&self) -> f32 {
13474        // SAFETY: plain scalar read through a live handle.
13475        unsafe { ffi::whiteout_m3_M3TurretBehavior_get_pitchWeight(self.raw.as_ptr()) }
13476    }
13477
13478    pub fn set_pitch_weight(&mut self, value: f32) {
13479        // SAFETY: plain scalar write through a live handle.
13480        unsafe { ffi::whiteout_m3_M3TurretBehavior_set_pitchWeight(self.raw.as_ptr(), value) }
13481    }
13482
13483    /// Unknown field
13484    pub fn unknown_3(&self) -> f32 {
13485        // SAFETY: plain scalar read through a live handle.
13486        unsafe { ffi::whiteout_m3_M3TurretBehavior_get_unknown3(self.raw.as_ptr()) }
13487    }
13488
13489    pub fn set_unknown_3(&mut self, value: f32) {
13490        // SAFETY: plain scalar write through a live handle.
13491        unsafe { ffi::whiteout_m3_M3TurretBehavior_set_unknown3(self.raw.as_ptr(), value) }
13492    }
13493
13494    /// Unknown field
13495    pub fn unknown_4(&self) -> f32 {
13496        // SAFETY: plain scalar read through a live handle.
13497        unsafe { ffi::whiteout_m3_M3TurretBehavior_get_unknown4(self.raw.as_ptr()) }
13498    }
13499
13500    pub fn set_unknown_4(&mut self, value: f32) {
13501        // SAFETY: plain scalar write through a live handle.
13502        unsafe { ffi::whiteout_m3_M3TurretBehavior_set_unknown4(self.raw.as_ptr(), value) }
13503    }
13504
13505    /// Offset from main bone
13506    pub fn main_bone_offset(&self) -> crate::math::Vector3f {
13507        // SAFETY: the getter returns an interior pointer to a
13508        // layout-identical POD; we copy it out immediately.
13509        unsafe {
13510            *(ffi::whiteout_m3_M3TurretBehavior_get_mainBoneOffset(self.raw.as_ptr())
13511                as *const crate::math::Vector3f)
13512        }
13513    }
13514
13515    pub fn set_main_bone_offset(&mut self, value: crate::math::Vector3f) {
13516        // SAFETY: as above, in the other direction.
13517        unsafe {
13518            ffi::whiteout_m3_M3TurretBehavior_set_mainBoneOffset(
13519                self.raw.as_ptr(),
13520                &value as *const crate::math::Vector3f as *const _,
13521            )
13522        }
13523    }
13524}
13525
13526impl Default for TurretBehavior {
13527    fn default() -> Self {
13528        Self::new()
13529    }
13530}
13531
13532/// BBSC — Billboard behavior (v0, 48 bytes)
13533///
13534/// Makes a bone always face the camera or a specified direction.
13535pub struct BillboardBehavior {
13536    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3BillboardBehavior>,
13537}
13538
13539impl Drop for BillboardBehavior {
13540    fn drop(&mut self) {
13541        // SAFETY: `raw` came from a native constructor and Drop runs once.
13542        unsafe { ffi::whiteout_m3_M3BillboardBehavior_delete(self.raw.as_ptr()) }
13543    }
13544}
13545
13546impl BillboardBehavior {
13547    /// # Safety
13548    /// `raw` must be a live handle this value takes ownership of.
13549    #[allow(dead_code)] // used by whichever methods return this type
13550    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3BillboardBehavior) -> Option<Self> {
13551        core::ptr::NonNull::new(raw).map(|raw| BillboardBehavior { raw })
13552    }
13553}
13554
13555// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
13556// is deliberately NOT implemented — the C++ types make no documented
13557// guarantee about concurrent use, and claiming one we haven't verified
13558// would be unsound. See `@bind thread_safe` in the plan.
13559unsafe impl Send for BillboardBehavior {}
13560
13561impl core::fmt::Debug for BillboardBehavior {
13562    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
13563        f.debug_struct("BillboardBehavior").finish_non_exhaustive()
13564    }
13565}
13566
13567impl BillboardBehavior {
13568    /// # Panics
13569    /// Panics if the native allocation fails.
13570    pub fn new() -> Self {
13571        // SAFETY: the native constructor returns a live handle; a null here
13572        // means the library is unusable.
13573        unsafe {
13574            let raw = ffi::whiteout_m3_M3BillboardBehavior_new();
13575            Self::from_raw(raw).expect("native BillboardBehavior allocation failed")
13576        }
13577    }
13578
13579    /// Dependent bone indices (U16_)
13580    /// Zero-copy view of the underlying `std::vector`.
13581    pub fn dependents(&self) -> &[u16] {
13582        // SAFETY: `_data`/`_count` describe one contiguous C++
13583        // allocation, borrowed for as long as `self` is.
13584        unsafe {
13585            let n = ffi::whiteout_m3_M3BillboardBehavior_get_dependents_count(self.raw.as_ptr());
13586            let p = ffi::whiteout_m3_M3BillboardBehavior_get_dependents_data(self.raw.as_ptr());
13587            if p.is_null() || n == 0 {
13588                &[]
13589            } else {
13590                core::slice::from_raw_parts(p, n)
13591            }
13592        }
13593    }
13594
13595    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
13596    pub fn dependents_mut(&mut self) -> &mut [u16] {
13597        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
13598        unsafe {
13599            let n = ffi::whiteout_m3_M3BillboardBehavior_get_dependents_count(self.raw.as_ptr());
13600            let p = ffi::whiteout_m3_M3BillboardBehavior_get_dependents_data(self.raw.as_ptr())
13601                as *mut u16;
13602            if p.is_null() || n == 0 {
13603                &mut []
13604            } else {
13605                core::slice::from_raw_parts_mut(p, n)
13606            }
13607        }
13608    }
13609
13610    pub fn set_dependents(&mut self, values: &[u16]) {
13611        // SAFETY: the native side copies `values` before returning.
13612        unsafe {
13613            ffi::whiteout_m3_M3BillboardBehavior_assign_dependents(
13614                self.raw.as_ptr(),
13615                values.as_ptr() as *const _,
13616                values.len(),
13617            )
13618        }
13619    }
13620
13621    pub fn resize_dependents(&mut self, count: usize) {
13622        // SAFETY: reallocation is safe here precisely because
13623        // `&mut self` means no slice borrow is outstanding.
13624        unsafe { ffi::whiteout_m3_M3BillboardBehavior_resize_dependents(self.raw.as_ptr(), count) }
13625    }
13626
13627    /// Index into BONE array
13628    pub fn bone_index(&self) -> u16 {
13629        // SAFETY: plain scalar read through a live handle.
13630        unsafe { ffi::whiteout_m3_M3BillboardBehavior_get_boneIndex(self.raw.as_ptr()) }
13631    }
13632
13633    pub fn set_bone_index(&mut self, value: u16) {
13634        // SAFETY: plain scalar write through a live handle.
13635        unsafe { ffi::whiteout_m3_M3BillboardBehavior_set_boneIndex(self.raw.as_ptr(), value) }
13636    }
13637
13638    /// Billboard mode type
13639    pub fn billboard_type(&self) -> u8 {
13640        // SAFETY: plain scalar read through a live handle.
13641        unsafe { ffi::whiteout_m3_M3BillboardBehavior_get_billboardType(self.raw.as_ptr()) }
13642    }
13643
13644    pub fn set_billboard_type(&mut self, value: u8) {
13645        // SAFETY: plain scalar write through a live handle.
13646        unsafe { ffi::whiteout_m3_M3BillboardBehavior_set_billboardType(self.raw.as_ptr(), value) }
13647    }
13648
13649    /// Camera look-at flag (default: enabled)
13650    pub fn camera_look_at(&self) -> u8 {
13651        // SAFETY: plain scalar read through a live handle.
13652        unsafe { ffi::whiteout_m3_M3BillboardBehavior_get_cameraLookAt(self.raw.as_ptr()) }
13653    }
13654
13655    pub fn set_camera_look_at(&mut self, value: u8) {
13656        // SAFETY: plain scalar write through a live handle.
13657        unsafe { ffi::whiteout_m3_M3BillboardBehavior_set_cameraLookAt(self.raw.as_ptr(), value) }
13658    }
13659
13660    /// Up direction quaternion
13661    pub fn up(&self) -> crate::math::Quaternion {
13662        // SAFETY: the getter returns an interior pointer to a
13663        // layout-identical POD; we copy it out immediately.
13664        unsafe {
13665            *(ffi::whiteout_m3_M3BillboardBehavior_get_up(self.raw.as_ptr())
13666                as *const crate::math::Quaternion)
13667        }
13668    }
13669
13670    pub fn set_up(&mut self, value: crate::math::Quaternion) {
13671        // SAFETY: as above, in the other direction.
13672        unsafe {
13673            ffi::whiteout_m3_M3BillboardBehavior_set_up(
13674                self.raw.as_ptr(),
13675                &value as *const crate::math::Quaternion as *const _,
13676            )
13677        }
13678    }
13679
13680    /// Forward direction quaternion
13681    pub fn forward(&self) -> crate::math::Quaternion {
13682        // SAFETY: the getter returns an interior pointer to a
13683        // layout-identical POD; we copy it out immediately.
13684        unsafe {
13685            *(ffi::whiteout_m3_M3BillboardBehavior_get_forward(self.raw.as_ptr())
13686                as *const crate::math::Quaternion)
13687        }
13688    }
13689
13690    pub fn set_forward(&mut self, value: crate::math::Quaternion) {
13691        // SAFETY: as above, in the other direction.
13692        unsafe {
13693            ffi::whiteout_m3_M3BillboardBehavior_set_forward(
13694                self.raw.as_ptr(),
13695                &value as *const crate::math::Quaternion as *const _,
13696            )
13697        }
13698    }
13699}
13700
13701impl Default for BillboardBehavior {
13702    fn default() -> Self {
13703        Self::new()
13704    }
13705}
13706
13707/// IKJT — IK joint (v0, 32 bytes)
13708///
13709/// Inverse kinematics joint with raycast up/down range, max speed, and goal threshold for terrain-following or foot-planting.
13710pub struct IKJoint {
13711    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3IKJoint>,
13712}
13713
13714impl Drop for IKJoint {
13715    fn drop(&mut self) {
13716        // SAFETY: `raw` came from a native constructor and Drop runs once.
13717        unsafe { ffi::whiteout_m3_M3IKJoint_delete(self.raw.as_ptr()) }
13718    }
13719}
13720
13721impl IKJoint {
13722    /// # Safety
13723    /// `raw` must be a live handle this value takes ownership of.
13724    #[allow(dead_code)] // used by whichever methods return this type
13725    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3IKJoint) -> Option<Self> {
13726        core::ptr::NonNull::new(raw).map(|raw| IKJoint { raw })
13727    }
13728}
13729
13730// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
13731// is deliberately NOT implemented — the C++ types make no documented
13732// guarantee about concurrent use, and claiming one we haven't verified
13733// would be unsound. See `@bind thread_safe` in the plan.
13734unsafe impl Send for IKJoint {}
13735
13736impl core::fmt::Debug for IKJoint {
13737    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
13738        f.debug_struct("IKJoint").finish_non_exhaustive()
13739    }
13740}
13741
13742impl IKJoint {
13743    /// # Panics
13744    /// Panics if the native allocation fails.
13745    pub fn new() -> Self {
13746        // SAFETY: the native constructor returns a live handle; a null here
13747        // means the library is unusable.
13748        unsafe {
13749            let raw = ffi::whiteout_m3_M3IKJoint_new();
13750            Self::from_raw(raw).expect("native IKJoint allocation failed")
13751        }
13752    }
13753
13754    /// Dependent bone indices (U16_)
13755    /// Zero-copy view of the underlying `std::vector`.
13756    pub fn dependents(&self) -> &[u16] {
13757        // SAFETY: `_data`/`_count` describe one contiguous C++
13758        // allocation, borrowed for as long as `self` is.
13759        unsafe {
13760            let n = ffi::whiteout_m3_M3IKJoint_get_dependents_count(self.raw.as_ptr());
13761            let p = ffi::whiteout_m3_M3IKJoint_get_dependents_data(self.raw.as_ptr());
13762            if p.is_null() || n == 0 {
13763                &[]
13764            } else {
13765                core::slice::from_raw_parts(p, n)
13766            }
13767        }
13768    }
13769
13770    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
13771    pub fn dependents_mut(&mut self) -> &mut [u16] {
13772        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
13773        unsafe {
13774            let n = ffi::whiteout_m3_M3IKJoint_get_dependents_count(self.raw.as_ptr());
13775            let p = ffi::whiteout_m3_M3IKJoint_get_dependents_data(self.raw.as_ptr()) as *mut u16;
13776            if p.is_null() || n == 0 {
13777                &mut []
13778            } else {
13779                core::slice::from_raw_parts_mut(p, n)
13780            }
13781        }
13782    }
13783
13784    pub fn set_dependents(&mut self, values: &[u16]) {
13785        // SAFETY: the native side copies `values` before returning.
13786        unsafe {
13787            ffi::whiteout_m3_M3IKJoint_assign_dependents(
13788                self.raw.as_ptr(),
13789                values.as_ptr() as *const _,
13790                values.len(),
13791            )
13792        }
13793    }
13794
13795    pub fn resize_dependents(&mut self, count: usize) {
13796        // SAFETY: reallocation is safe here precisely because
13797        // `&mut self` means no slice borrow is outstanding.
13798        unsafe { ffi::whiteout_m3_M3IKJoint_resize_dependents(self.raw.as_ptr(), count) }
13799    }
13800
13801    /// First bone index
13802    pub fn bone_index_1(&self) -> u16 {
13803        // SAFETY: plain scalar read through a live handle.
13804        unsafe { ffi::whiteout_m3_M3IKJoint_get_boneIndex1(self.raw.as_ptr()) }
13805    }
13806
13807    pub fn set_bone_index_1(&mut self, value: u16) {
13808        // SAFETY: plain scalar write through a live handle.
13809        unsafe { ffi::whiteout_m3_M3IKJoint_set_boneIndex1(self.raw.as_ptr(), value) }
13810    }
13811
13812    /// Second bone index
13813    pub fn bone_index_2(&self) -> u16 {
13814        // SAFETY: plain scalar read through a live handle.
13815        unsafe { ffi::whiteout_m3_M3IKJoint_get_boneIndex2(self.raw.as_ptr()) }
13816    }
13817
13818    pub fn set_bone_index_2(&mut self, value: u16) {
13819        // SAFETY: plain scalar write through a live handle.
13820        unsafe { ffi::whiteout_m3_M3IKJoint_set_boneIndex2(self.raw.as_ptr(), value) }
13821    }
13822
13823    /// Raycast upward distance
13824    pub fn raycast_up(&self) -> f32 {
13825        // SAFETY: plain scalar read through a live handle.
13826        unsafe { ffi::whiteout_m3_M3IKJoint_get_raycastUp(self.raw.as_ptr()) }
13827    }
13828
13829    pub fn set_raycast_up(&mut self, value: f32) {
13830        // SAFETY: plain scalar write through a live handle.
13831        unsafe { ffi::whiteout_m3_M3IKJoint_set_raycastUp(self.raw.as_ptr(), value) }
13832    }
13833
13834    /// Raycast downward distance
13835    pub fn raycast_down(&self) -> f32 {
13836        // SAFETY: plain scalar read through a live handle.
13837        unsafe { ffi::whiteout_m3_M3IKJoint_get_raycastDown(self.raw.as_ptr()) }
13838    }
13839
13840    pub fn set_raycast_down(&mut self, value: f32) {
13841        // SAFETY: plain scalar write through a live handle.
13842        unsafe { ffi::whiteout_m3_M3IKJoint_set_raycastDown(self.raw.as_ptr(), value) }
13843    }
13844
13845    /// Maximum IK solving speed
13846    pub fn max_speed(&self) -> f32 {
13847        // SAFETY: plain scalar read through a live handle.
13848        unsafe { ffi::whiteout_m3_M3IKJoint_get_maxSpeed(self.raw.as_ptr()) }
13849    }
13850
13851    pub fn set_max_speed(&mut self, value: f32) {
13852        // SAFETY: plain scalar write through a live handle.
13853        unsafe { ffi::whiteout_m3_M3IKJoint_set_maxSpeed(self.raw.as_ptr(), value) }
13854    }
13855
13856    /// Goal distance threshold
13857    pub fn goal_threshold(&self) -> f32 {
13858        // SAFETY: plain scalar read through a live handle.
13859        unsafe { ffi::whiteout_m3_M3IKJoint_get_goalThreshold(self.raw.as_ptr()) }
13860    }
13861
13862    pub fn set_goal_threshold(&mut self, value: f32) {
13863        // SAFETY: plain scalar write through a live handle.
13864        unsafe { ffi::whiteout_m3_M3IKJoint_set_goalThreshold(self.raw.as_ptr(), value) }
13865    }
13866}
13867
13868impl Default for IKJoint {
13869    fn default() -> Self {
13870        Self::new()
13871    }
13872}
13873
13874/// IK2J — Two-joint IK solver (v0, 48 bytes)
13875///
13876/// Classic two-bone IK (e.g. elbow/knee) with hinge axis, angle limits, and search range for target acquisition.
13877pub struct IKTwoJoint {
13878    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3IKTwoJoint>,
13879}
13880
13881impl Drop for IKTwoJoint {
13882    fn drop(&mut self) {
13883        // SAFETY: `raw` came from a native constructor and Drop runs once.
13884        unsafe { ffi::whiteout_m3_M3IKTwoJoint_delete(self.raw.as_ptr()) }
13885    }
13886}
13887
13888impl IKTwoJoint {
13889    /// # Safety
13890    /// `raw` must be a live handle this value takes ownership of.
13891    #[allow(dead_code)] // used by whichever methods return this type
13892    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3IKTwoJoint) -> Option<Self> {
13893        core::ptr::NonNull::new(raw).map(|raw| IKTwoJoint { raw })
13894    }
13895}
13896
13897// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
13898// is deliberately NOT implemented — the C++ types make no documented
13899// guarantee about concurrent use, and claiming one we haven't verified
13900// would be unsound. See `@bind thread_safe` in the plan.
13901unsafe impl Send for IKTwoJoint {}
13902
13903impl core::fmt::Debug for IKTwoJoint {
13904    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
13905        f.debug_struct("IKTwoJoint").finish_non_exhaustive()
13906    }
13907}
13908
13909impl IKTwoJoint {
13910    /// # Panics
13911    /// Panics if the native allocation fails.
13912    pub fn new() -> Self {
13913        // SAFETY: the native constructor returns a live handle; a null here
13914        // means the library is unusable.
13915        unsafe {
13916            let raw = ffi::whiteout_m3_M3IKTwoJoint_new();
13917            Self::from_raw(raw).expect("native IKTwoJoint allocation failed")
13918        }
13919    }
13920
13921    /// Dependent bone indices (U16_)
13922    /// Zero-copy view of the underlying `std::vector`.
13923    pub fn dependents(&self) -> &[u16] {
13924        // SAFETY: `_data`/`_count` describe one contiguous C++
13925        // allocation, borrowed for as long as `self` is.
13926        unsafe {
13927            let n = ffi::whiteout_m3_M3IKTwoJoint_get_dependents_count(self.raw.as_ptr());
13928            let p = ffi::whiteout_m3_M3IKTwoJoint_get_dependents_data(self.raw.as_ptr());
13929            if p.is_null() || n == 0 {
13930                &[]
13931            } else {
13932                core::slice::from_raw_parts(p, n)
13933            }
13934        }
13935    }
13936
13937    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
13938    pub fn dependents_mut(&mut self) -> &mut [u16] {
13939        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
13940        unsafe {
13941            let n = ffi::whiteout_m3_M3IKTwoJoint_get_dependents_count(self.raw.as_ptr());
13942            let p =
13943                ffi::whiteout_m3_M3IKTwoJoint_get_dependents_data(self.raw.as_ptr()) as *mut u16;
13944            if p.is_null() || n == 0 {
13945                &mut []
13946            } else {
13947                core::slice::from_raw_parts_mut(p, n)
13948            }
13949        }
13950    }
13951
13952    pub fn set_dependents(&mut self, values: &[u16]) {
13953        // SAFETY: the native side copies `values` before returning.
13954        unsafe {
13955            ffi::whiteout_m3_M3IKTwoJoint_assign_dependents(
13956                self.raw.as_ptr(),
13957                values.as_ptr() as *const _,
13958                values.len(),
13959            )
13960        }
13961    }
13962
13963    pub fn resize_dependents(&mut self, count: usize) {
13964        // SAFETY: reallocation is safe here precisely because
13965        // `&mut self` means no slice borrow is outstanding.
13966        unsafe { ffi::whiteout_m3_M3IKTwoJoint_resize_dependents(self.raw.as_ptr(), count) }
13967    }
13968
13969    /// Base bone (e.g. upper arm/thigh)
13970    pub fn bone_base(&self) -> u16 {
13971        // SAFETY: plain scalar read through a live handle.
13972        unsafe { ffi::whiteout_m3_M3IKTwoJoint_get_boneBase(self.raw.as_ptr()) }
13973    }
13974
13975    pub fn set_bone_base(&mut self, value: u16) {
13976        // SAFETY: plain scalar write through a live handle.
13977        unsafe { ffi::whiteout_m3_M3IKTwoJoint_set_boneBase(self.raw.as_ptr(), value) }
13978    }
13979
13980    /// Target bone (e.g. forearm/shin)
13981    pub fn bone_target(&self) -> u16 {
13982        // SAFETY: plain scalar read through a live handle.
13983        unsafe { ffi::whiteout_m3_M3IKTwoJoint_get_boneTarget(self.raw.as_ptr()) }
13984    }
13985
13986    pub fn set_bone_target(&mut self, value: u16) {
13987        // SAFETY: plain scalar write through a live handle.
13988        unsafe { ffi::whiteout_m3_M3IKTwoJoint_set_boneTarget(self.raw.as_ptr(), value) }
13989    }
13990
13991    /// End effector bone (e.g. hand/foot)
13992    pub fn bone_end(&self) -> u16 {
13993        // SAFETY: plain scalar read through a live handle.
13994        unsafe { ffi::whiteout_m3_M3IKTwoJoint_get_boneEnd(self.raw.as_ptr()) }
13995    }
13996
13997    pub fn set_bone_end(&mut self, value: u16) {
13998        // SAFETY: plain scalar write through a live handle.
13999        unsafe { ffi::whiteout_m3_M3IKTwoJoint_set_boneEnd(self.raw.as_ptr(), value) }
14000    }
14001
14002    /// Alignment padding
14003    pub fn padding(&self) -> u16 {
14004        // SAFETY: plain scalar read through a live handle.
14005        unsafe { ffi::whiteout_m3_M3IKTwoJoint_get_padding(self.raw.as_ptr()) }
14006    }
14007
14008    pub fn set_padding(&mut self, value: u16) {
14009        // SAFETY: plain scalar write through a live handle.
14010        unsafe { ffi::whiteout_m3_M3IKTwoJoint_set_padding(self.raw.as_ptr(), value) }
14011    }
14012
14013    /// Hinge rotation axis
14014    pub fn hinge_axis(&self) -> crate::math::Vector3f {
14015        // SAFETY: the getter returns an interior pointer to a
14016        // layout-identical POD; we copy it out immediately.
14017        unsafe {
14018            *(ffi::whiteout_m3_M3IKTwoJoint_get_hingeAxis(self.raw.as_ptr())
14019                as *const crate::math::Vector3f)
14020        }
14021    }
14022
14023    pub fn set_hinge_axis(&mut self, value: crate::math::Vector3f) {
14024        // SAFETY: as above, in the other direction.
14025        unsafe {
14026            ffi::whiteout_m3_M3IKTwoJoint_set_hingeAxis(
14027                self.raw.as_ptr(),
14028                &value as *const crate::math::Vector3f as *const _,
14029            )
14030        }
14031    }
14032
14033    /// Maximum inner angle
14034    pub fn max_angle_inner(&self) -> f32 {
14035        // SAFETY: plain scalar read through a live handle.
14036        unsafe { ffi::whiteout_m3_M3IKTwoJoint_get_maxAngleInner(self.raw.as_ptr()) }
14037    }
14038
14039    pub fn set_max_angle_inner(&mut self, value: f32) {
14040        // SAFETY: plain scalar write through a live handle.
14041        unsafe { ffi::whiteout_m3_M3IKTwoJoint_set_maxAngleInner(self.raw.as_ptr(), value) }
14042    }
14043
14044    /// Maximum outer angle
14045    pub fn max_angle_outer(&self) -> f32 {
14046        // SAFETY: plain scalar read through a live handle.
14047        unsafe { ffi::whiteout_m3_M3IKTwoJoint_get_maxAngleOuter(self.raw.as_ptr()) }
14048    }
14049
14050    pub fn set_max_angle_outer(&mut self, value: f32) {
14051        // SAFETY: plain scalar write through a live handle.
14052        unsafe { ffi::whiteout_m3_M3IKTwoJoint_set_maxAngleOuter(self.raw.as_ptr(), value) }
14053    }
14054
14055    /// Search range upward
14056    pub fn search_up(&self) -> f32 {
14057        // SAFETY: plain scalar read through a live handle.
14058        unsafe { ffi::whiteout_m3_M3IKTwoJoint_get_searchUp(self.raw.as_ptr()) }
14059    }
14060
14061    pub fn set_search_up(&mut self, value: f32) {
14062        // SAFETY: plain scalar write through a live handle.
14063        unsafe { ffi::whiteout_m3_M3IKTwoJoint_set_searchUp(self.raw.as_ptr(), value) }
14064    }
14065
14066    /// Search range downward
14067    pub fn search_down(&self) -> f32 {
14068        // SAFETY: plain scalar read through a live handle.
14069        unsafe { ffi::whiteout_m3_M3IKTwoJoint_get_searchDown(self.raw.as_ptr()) }
14070    }
14071
14072    pub fn set_search_down(&mut self, value: f32) {
14073        // SAFETY: plain scalar write through a live handle.
14074        unsafe { ffi::whiteout_m3_M3IKTwoJoint_set_searchDown(self.raw.as_ptr(), value) }
14075    }
14076}
14077
14078impl Default for IKTwoJoint {
14079    fn default() -> Self {
14080        Self::new()
14081    }
14082}
14083
14084/// IKCC — CCD IK solver (v0, 24 bytes)
14085///
14086/// Cyclic Coordinate Descent IK solver with base/target bones and vertical search range.
14087pub struct IKCCD {
14088    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3IKCCD>,
14089}
14090
14091impl Drop for IKCCD {
14092    fn drop(&mut self) {
14093        // SAFETY: `raw` came from a native constructor and Drop runs once.
14094        unsafe { ffi::whiteout_m3_M3IKCCD_delete(self.raw.as_ptr()) }
14095    }
14096}
14097
14098impl IKCCD {
14099    /// # Safety
14100    /// `raw` must be a live handle this value takes ownership of.
14101    #[allow(dead_code)] // used by whichever methods return this type
14102    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3IKCCD) -> Option<Self> {
14103        core::ptr::NonNull::new(raw).map(|raw| IKCCD { raw })
14104    }
14105}
14106
14107// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
14108// is deliberately NOT implemented — the C++ types make no documented
14109// guarantee about concurrent use, and claiming one we haven't verified
14110// would be unsound. See `@bind thread_safe` in the plan.
14111unsafe impl Send for IKCCD {}
14112
14113impl core::fmt::Debug for IKCCD {
14114    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
14115        f.debug_struct("IKCCD").finish_non_exhaustive()
14116    }
14117}
14118
14119impl IKCCD {
14120    /// # Panics
14121    /// Panics if the native allocation fails.
14122    pub fn new() -> Self {
14123        // SAFETY: the native constructor returns a live handle; a null here
14124        // means the library is unusable.
14125        unsafe {
14126            let raw = ffi::whiteout_m3_M3IKCCD_new();
14127            Self::from_raw(raw).expect("native IKCCD allocation failed")
14128        }
14129    }
14130
14131    /// Dependent bone indices (U16_)
14132    /// Zero-copy view of the underlying `std::vector`.
14133    pub fn dependents(&self) -> &[u16] {
14134        // SAFETY: `_data`/`_count` describe one contiguous C++
14135        // allocation, borrowed for as long as `self` is.
14136        unsafe {
14137            let n = ffi::whiteout_m3_M3IKCCD_get_dependents_count(self.raw.as_ptr());
14138            let p = ffi::whiteout_m3_M3IKCCD_get_dependents_data(self.raw.as_ptr());
14139            if p.is_null() || n == 0 {
14140                &[]
14141            } else {
14142                core::slice::from_raw_parts(p, n)
14143            }
14144        }
14145    }
14146
14147    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
14148    pub fn dependents_mut(&mut self) -> &mut [u16] {
14149        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
14150        unsafe {
14151            let n = ffi::whiteout_m3_M3IKCCD_get_dependents_count(self.raw.as_ptr());
14152            let p = ffi::whiteout_m3_M3IKCCD_get_dependents_data(self.raw.as_ptr()) as *mut u16;
14153            if p.is_null() || n == 0 {
14154                &mut []
14155            } else {
14156                core::slice::from_raw_parts_mut(p, n)
14157            }
14158        }
14159    }
14160
14161    pub fn set_dependents(&mut self, values: &[u16]) {
14162        // SAFETY: the native side copies `values` before returning.
14163        unsafe {
14164            ffi::whiteout_m3_M3IKCCD_assign_dependents(
14165                self.raw.as_ptr(),
14166                values.as_ptr() as *const _,
14167                values.len(),
14168            )
14169        }
14170    }
14171
14172    pub fn resize_dependents(&mut self, count: usize) {
14173        // SAFETY: reallocation is safe here precisely because
14174        // `&mut self` means no slice borrow is outstanding.
14175        unsafe { ffi::whiteout_m3_M3IKCCD_resize_dependents(self.raw.as_ptr(), count) }
14176    }
14177
14178    /// Base bone index
14179    pub fn bone_base(&self) -> u16 {
14180        // SAFETY: plain scalar read through a live handle.
14181        unsafe { ffi::whiteout_m3_M3IKCCD_get_boneBase(self.raw.as_ptr()) }
14182    }
14183
14184    pub fn set_bone_base(&mut self, value: u16) {
14185        // SAFETY: plain scalar write through a live handle.
14186        unsafe { ffi::whiteout_m3_M3IKCCD_set_boneBase(self.raw.as_ptr(), value) }
14187    }
14188
14189    /// Target bone index
14190    pub fn bone_target(&self) -> u16 {
14191        // SAFETY: plain scalar read through a live handle.
14192        unsafe { ffi::whiteout_m3_M3IKCCD_get_boneTarget(self.raw.as_ptr()) }
14193    }
14194
14195    pub fn set_bone_target(&mut self, value: u16) {
14196        // SAFETY: plain scalar write through a live handle.
14197        unsafe { ffi::whiteout_m3_M3IKCCD_set_boneTarget(self.raw.as_ptr(), value) }
14198    }
14199
14200    /// Search range upward
14201    pub fn search_up(&self) -> f32 {
14202        // SAFETY: plain scalar read through a live handle.
14203        unsafe { ffi::whiteout_m3_M3IKCCD_get_searchUp(self.raw.as_ptr()) }
14204    }
14205
14206    pub fn set_search_up(&mut self, value: f32) {
14207        // SAFETY: plain scalar write through a live handle.
14208        unsafe { ffi::whiteout_m3_M3IKCCD_set_searchUp(self.raw.as_ptr(), value) }
14209    }
14210
14211    /// Search range downward
14212    pub fn search_down(&self) -> f32 {
14213        // SAFETY: plain scalar read through a live handle.
14214        unsafe { ffi::whiteout_m3_M3IKCCD_get_searchDown(self.raw.as_ptr()) }
14215    }
14216
14217    pub fn set_search_down(&mut self, value: f32) {
14218        // SAFETY: plain scalar write through a live handle.
14219        unsafe { ffi::whiteout_m3_M3IKCCD_set_searchDown(self.raw.as_ptr(), value) }
14220    }
14221}
14222
14223impl Default for IKCCD {
14224    fn default() -> Self {
14225        Self::new()
14226    }
14227}
14228
14229/// PAOB — One-bone IK solver (v0, 24 bytes)
14230///
14231/// Simple single-bone orientation solver with angle limit and fallback bone.
14232pub struct OneBoneSolver {
14233    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3OneBoneSolver>,
14234}
14235
14236impl Drop for OneBoneSolver {
14237    fn drop(&mut self) {
14238        // SAFETY: `raw` came from a native constructor and Drop runs once.
14239        unsafe { ffi::whiteout_m3_M3OneBoneSolver_delete(self.raw.as_ptr()) }
14240    }
14241}
14242
14243impl OneBoneSolver {
14244    /// # Safety
14245    /// `raw` must be a live handle this value takes ownership of.
14246    #[allow(dead_code)] // used by whichever methods return this type
14247    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3OneBoneSolver) -> Option<Self> {
14248        core::ptr::NonNull::new(raw).map(|raw| OneBoneSolver { raw })
14249    }
14250}
14251
14252// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
14253// is deliberately NOT implemented — the C++ types make no documented
14254// guarantee about concurrent use, and claiming one we haven't verified
14255// would be unsound. See `@bind thread_safe` in the plan.
14256unsafe impl Send for OneBoneSolver {}
14257
14258impl core::fmt::Debug for OneBoneSolver {
14259    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
14260        f.debug_struct("OneBoneSolver").finish_non_exhaustive()
14261    }
14262}
14263
14264impl OneBoneSolver {
14265    /// # Panics
14266    /// Panics if the native allocation fails.
14267    pub fn new() -> Self {
14268        // SAFETY: the native constructor returns a live handle; a null here
14269        // means the library is unusable.
14270        unsafe {
14271            let raw = ffi::whiteout_m3_M3OneBoneSolver_new();
14272            Self::from_raw(raw).expect("native OneBoneSolver allocation failed")
14273        }
14274    }
14275
14276    /// Dependent bone indices (U16_)
14277    /// Zero-copy view of the underlying `std::vector`.
14278    pub fn dependents(&self) -> &[u16] {
14279        // SAFETY: `_data`/`_count` describe one contiguous C++
14280        // allocation, borrowed for as long as `self` is.
14281        unsafe {
14282            let n = ffi::whiteout_m3_M3OneBoneSolver_get_dependents_count(self.raw.as_ptr());
14283            let p = ffi::whiteout_m3_M3OneBoneSolver_get_dependents_data(self.raw.as_ptr());
14284            if p.is_null() || n == 0 {
14285                &[]
14286            } else {
14287                core::slice::from_raw_parts(p, n)
14288            }
14289        }
14290    }
14291
14292    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
14293    pub fn dependents_mut(&mut self) -> &mut [u16] {
14294        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
14295        unsafe {
14296            let n = ffi::whiteout_m3_M3OneBoneSolver_get_dependents_count(self.raw.as_ptr());
14297            let p =
14298                ffi::whiteout_m3_M3OneBoneSolver_get_dependents_data(self.raw.as_ptr()) as *mut u16;
14299            if p.is_null() || n == 0 {
14300                &mut []
14301            } else {
14302                core::slice::from_raw_parts_mut(p, n)
14303            }
14304        }
14305    }
14306
14307    pub fn set_dependents(&mut self, values: &[u16]) {
14308        // SAFETY: the native side copies `values` before returning.
14309        unsafe {
14310            ffi::whiteout_m3_M3OneBoneSolver_assign_dependents(
14311                self.raw.as_ptr(),
14312                values.as_ptr() as *const _,
14313                values.len(),
14314            )
14315        }
14316    }
14317
14318    pub fn resize_dependents(&mut self, count: usize) {
14319        // SAFETY: reallocation is safe here precisely because
14320        // `&mut self` means no slice borrow is outstanding.
14321        unsafe { ffi::whiteout_m3_M3OneBoneSolver_resize_dependents(self.raw.as_ptr(), count) }
14322    }
14323
14324    /// Primary bone index
14325    pub fn bone(&self) -> u16 {
14326        // SAFETY: plain scalar read through a live handle.
14327        unsafe { ffi::whiteout_m3_M3OneBoneSolver_get_bone(self.raw.as_ptr()) }
14328    }
14329
14330    pub fn set_bone(&mut self, value: u16) {
14331        // SAFETY: plain scalar write through a live handle.
14332        unsafe { ffi::whiteout_m3_M3OneBoneSolver_set_bone(self.raw.as_ptr(), value) }
14333    }
14334
14335    /// Fallback bone index
14336    pub fn bone_fallback(&self) -> u16 {
14337        // SAFETY: plain scalar read through a live handle.
14338        unsafe { ffi::whiteout_m3_M3OneBoneSolver_get_boneFallback(self.raw.as_ptr()) }
14339    }
14340
14341    pub fn set_bone_fallback(&mut self, value: u16) {
14342        // SAFETY: plain scalar write through a live handle.
14343        unsafe { ffi::whiteout_m3_M3OneBoneSolver_set_boneFallback(self.raw.as_ptr(), value) }
14344    }
14345
14346    /// Maximum rotation angle
14347    pub fn max_angle(&self) -> f32 {
14348        // SAFETY: plain scalar read through a live handle.
14349        unsafe { ffi::whiteout_m3_M3OneBoneSolver_get_maxAngle(self.raw.as_ptr()) }
14350    }
14351
14352    pub fn set_max_angle(&mut self, value: f32) {
14353        // SAFETY: plain scalar write through a live handle.
14354        unsafe { ffi::whiteout_m3_M3OneBoneSolver_set_maxAngle(self.raw.as_ptr(), value) }
14355    }
14356}
14357
14358impl Default for OneBoneSolver {
14359    fn default() -> Self {
14360        Self::new()
14361    }
14362}
14363
14364/// SHBX — Shadow box (v0, 64 bytes)
14365///
14366/// Axis-aligned shadow volume defined by a 4×4 transform matrix.
14367pub struct ShadowBox {
14368    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3ShadowBox>,
14369}
14370
14371impl Drop for ShadowBox {
14372    fn drop(&mut self) {
14373        // SAFETY: `raw` came from a native constructor and Drop runs once.
14374        unsafe { ffi::whiteout_m3_M3ShadowBox_delete(self.raw.as_ptr()) }
14375    }
14376}
14377
14378impl ShadowBox {
14379    /// # Safety
14380    /// `raw` must be a live handle this value takes ownership of.
14381    #[allow(dead_code)] // used by whichever methods return this type
14382    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3ShadowBox) -> Option<Self> {
14383        core::ptr::NonNull::new(raw).map(|raw| ShadowBox { raw })
14384    }
14385}
14386
14387// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
14388// is deliberately NOT implemented — the C++ types make no documented
14389// guarantee about concurrent use, and claiming one we haven't verified
14390// would be unsound. See `@bind thread_safe` in the plan.
14391unsafe impl Send for ShadowBox {}
14392
14393impl core::fmt::Debug for ShadowBox {
14394    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
14395        f.debug_struct("ShadowBox").finish_non_exhaustive()
14396    }
14397}
14398
14399impl ShadowBox {
14400    /// # Panics
14401    /// Panics if the native allocation fails.
14402    pub fn new() -> Self {
14403        // SAFETY: the native constructor returns a live handle; a null here
14404        // means the library is unusable.
14405        unsafe {
14406            let raw = ffi::whiteout_m3_M3ShadowBox_new();
14407            Self::from_raw(raw).expect("native ShadowBox allocation failed")
14408        }
14409    }
14410}
14411
14412impl Default for ShadowBox {
14413    fn default() -> Self {
14414        Self::new()
14415    }
14416}
14417
14418/// VVOL — View volume (v0, 40 bytes)
14419///
14420/// Animated visibility volume bound to a bone, used for culling decisions.
14421pub struct ViewVolume {
14422    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3ViewVolume>,
14423}
14424
14425impl Drop for ViewVolume {
14426    fn drop(&mut self) {
14427        // SAFETY: `raw` came from a native constructor and Drop runs once.
14428        unsafe { ffi::whiteout_m3_M3ViewVolume_delete(self.raw.as_ptr()) }
14429    }
14430}
14431
14432impl ViewVolume {
14433    /// # Safety
14434    /// `raw` must be a live handle this value takes ownership of.
14435    #[allow(dead_code)] // used by whichever methods return this type
14436    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3ViewVolume) -> Option<Self> {
14437        core::ptr::NonNull::new(raw).map(|raw| ViewVolume { raw })
14438    }
14439}
14440
14441// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
14442// is deliberately NOT implemented — the C++ types make no documented
14443// guarantee about concurrent use, and claiming one we haven't verified
14444// would be unsound. See `@bind thread_safe` in the plan.
14445unsafe impl Send for ViewVolume {}
14446
14447impl core::fmt::Debug for ViewVolume {
14448    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
14449        f.debug_struct("ViewVolume").finish_non_exhaustive()
14450    }
14451}
14452
14453impl ViewVolume {
14454    /// # Panics
14455    /// Panics if the native allocation fails.
14456    pub fn new() -> Self {
14457        // SAFETY: the native constructor returns a live handle; a null here
14458        // means the library is unusable.
14459        unsafe {
14460            let raw = ffi::whiteout_m3_M3ViewVolume_new();
14461            Self::from_raw(raw).expect("native ViewVolume allocation failed")
14462        }
14463    }
14464
14465    /// Index into BONE array
14466    pub fn node_index(&self) -> u32 {
14467        // SAFETY: plain scalar read through a live handle.
14468        unsafe { ffi::whiteout_m3_M3ViewVolume_get_nodeIndex(self.raw.as_ptr()) }
14469    }
14470
14471    pub fn set_node_index(&mut self, value: u32) {
14472        // SAFETY: plain scalar write through a live handle.
14473        unsafe { ffi::whiteout_m3_M3ViewVolume_set_nodeIndex(self.raw.as_ptr(), value) }
14474    }
14475
14476    /// Animated half-extents (36 bytes)
14477    /// Borrows the field in place — no copy, no allocation.
14478    pub fn size(&self) -> crate::support::Ref<'_, AnimRefVector3f> {
14479        // SAFETY: an interior pointer into `self`, valid for this
14480        // borrow and never freed by the `Ref`.
14481        unsafe {
14482            crate::support::Ref::new(AnimRefVector3f {
14483                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3ViewVolume_get_size(
14484                    self.raw.as_ptr(),
14485                )),
14486            })
14487        }
14488    }
14489
14490    pub fn size_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector3f> {
14491        // SAFETY: as above; `&mut self` guarantees exclusivity.
14492        unsafe {
14493            crate::support::RefMut::new(AnimRefVector3f {
14494                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3ViewVolume_get_size(
14495                    self.raw.as_ptr(),
14496                )),
14497            })
14498        }
14499    }
14500}
14501
14502impl Default for ViewVolume {
14503    fn default() -> Self {
14504        Self::new()
14505    }
14506}
14507
14508/// TMD_ — Trailing model (v0–v1, defunct)
14509///
14510/// Legacy trailing model data. Observed in older files but no longer actively used by the engine.
14511pub struct TrailingModel {
14512    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3TrailingModel>,
14513}
14514
14515impl Drop for TrailingModel {
14516    fn drop(&mut self) {
14517        // SAFETY: `raw` came from a native constructor and Drop runs once.
14518        unsafe { ffi::whiteout_m3_M3TrailingModel_delete(self.raw.as_ptr()) }
14519    }
14520}
14521
14522impl TrailingModel {
14523    /// # Safety
14524    /// `raw` must be a live handle this value takes ownership of.
14525    #[allow(dead_code)] // used by whichever methods return this type
14526    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3TrailingModel) -> Option<Self> {
14527        core::ptr::NonNull::new(raw).map(|raw| TrailingModel { raw })
14528    }
14529}
14530
14531// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
14532// is deliberately NOT implemented — the C++ types make no documented
14533// guarantee about concurrent use, and claiming one we haven't verified
14534// would be unsound. See `@bind thread_safe` in the plan.
14535unsafe impl Send for TrailingModel {}
14536
14537impl core::fmt::Debug for TrailingModel {
14538    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
14539        f.debug_struct("TrailingModel").finish_non_exhaustive()
14540    }
14541}
14542
14543impl TrailingModel {
14544    /// # Panics
14545    /// Panics if the native allocation fails.
14546    pub fn new() -> Self {
14547        // SAFETY: the native constructor returns a live handle; a null here
14548        // means the library is unusable.
14549        unsafe {
14550            let raw = ffi::whiteout_m3_M3TrailingModel_new();
14551            Self::from_raw(raw).expect("native TrailingModel allocation failed")
14552        }
14553    }
14554
14555    /// Control vectors (VEC3)
14556    /// Zero-copy view of the underlying `std::vector`.
14557    pub fn vectors(&self) -> &[crate::math::Vector3f] {
14558        // SAFETY: `_data`/`_count` describe one contiguous C++
14559        // allocation, borrowed for as long as `self` is.
14560        unsafe {
14561            let n = ffi::whiteout_m3_M3TrailingModel_get_vectors_count(self.raw.as_ptr());
14562            let p = ffi::whiteout_m3_M3TrailingModel_get_vectors_data(self.raw.as_ptr())
14563                as *const crate::math::Vector3f;
14564            if p.is_null() || n == 0 {
14565                &[]
14566            } else {
14567                core::slice::from_raw_parts(p, n)
14568            }
14569        }
14570    }
14571
14572    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
14573    pub fn vectors_mut(&mut self) -> &mut [crate::math::Vector3f] {
14574        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
14575        unsafe {
14576            let n = ffi::whiteout_m3_M3TrailingModel_get_vectors_count(self.raw.as_ptr());
14577            let p = ffi::whiteout_m3_M3TrailingModel_get_vectors_data(self.raw.as_ptr())
14578                as *const crate::math::Vector3f as *mut crate::math::Vector3f;
14579            if p.is_null() || n == 0 {
14580                &mut []
14581            } else {
14582                core::slice::from_raw_parts_mut(p, n)
14583            }
14584        }
14585    }
14586
14587    pub fn set_vectors(&mut self, values: &[crate::math::Vector3f]) {
14588        // SAFETY: the native side copies `values` before returning.
14589        unsafe {
14590            ffi::whiteout_m3_M3TrailingModel_assign_vectors(
14591                self.raw.as_ptr(),
14592                values.as_ptr() as *const _,
14593                values.len(),
14594            )
14595        }
14596    }
14597
14598    pub fn resize_vectors(&mut self, count: usize) {
14599        // SAFETY: reallocation is safe here precisely because
14600        // `&mut self` means no slice borrow is outstanding.
14601        unsafe { ffi::whiteout_m3_M3TrailingModel_resize_vectors(self.raw.as_ptr(), count) }
14602    }
14603
14604    /// Parameter 0 (observed: 5.0)
14605    pub fn param_0(&self) -> f32 {
14606        // SAFETY: plain scalar read through a live handle.
14607        unsafe { ffi::whiteout_m3_M3TrailingModel_get_param0(self.raw.as_ptr()) }
14608    }
14609
14610    pub fn set_param_0(&mut self, value: f32) {
14611        // SAFETY: plain scalar write through a live handle.
14612        unsafe { ffi::whiteout_m3_M3TrailingModel_set_param0(self.raw.as_ptr(), value) }
14613    }
14614
14615    /// Parameter 1 (observed: 1.0)
14616    pub fn param_1(&self) -> f32 {
14617        // SAFETY: plain scalar read through a live handle.
14618        unsafe { ffi::whiteout_m3_M3TrailingModel_get_param1(self.raw.as_ptr()) }
14619    }
14620
14621    pub fn set_param_1(&mut self, value: f32) {
14622        // SAFETY: plain scalar write through a live handle.
14623        unsafe { ffi::whiteout_m3_M3TrailingModel_set_param1(self.raw.as_ptr(), value) }
14624    }
14625
14626    /// Animated float 0 (init 0.5)
14627    /// Borrows the field in place — no copy, no allocation.
14628    pub fn anim_float_0(&self) -> crate::support::Ref<'_, AnimRefF32> {
14629        // SAFETY: an interior pointer into `self`, valid for this
14630        // borrow and never freed by the `Ref`.
14631        unsafe {
14632            crate::support::Ref::new(AnimRefF32 {
14633                raw: core::ptr::NonNull::new_unchecked(
14634                    ffi::whiteout_m3_M3TrailingModel_get_animFloat0(self.raw.as_ptr()),
14635                ),
14636            })
14637        }
14638    }
14639
14640    pub fn anim_float_0_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
14641        // SAFETY: as above; `&mut self` guarantees exclusivity.
14642        unsafe {
14643            crate::support::RefMut::new(AnimRefF32 {
14644                raw: core::ptr::NonNull::new_unchecked(
14645                    ffi::whiteout_m3_M3TrailingModel_get_animFloat0(self.raw.as_ptr()),
14646                ),
14647            })
14648        }
14649    }
14650
14651    /// Animated float 1 (init 1.0)
14652    /// Borrows the field in place — no copy, no allocation.
14653    pub fn anim_float_1(&self) -> crate::support::Ref<'_, AnimRefF32> {
14654        // SAFETY: an interior pointer into `self`, valid for this
14655        // borrow and never freed by the `Ref`.
14656        unsafe {
14657            crate::support::Ref::new(AnimRefF32 {
14658                raw: core::ptr::NonNull::new_unchecked(
14659                    ffi::whiteout_m3_M3TrailingModel_get_animFloat1(self.raw.as_ptr()),
14660                ),
14661            })
14662        }
14663    }
14664
14665    pub fn anim_float_1_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
14666        // SAFETY: as above; `&mut self` guarantees exclusivity.
14667        unsafe {
14668            crate::support::RefMut::new(AnimRefF32 {
14669                raw: core::ptr::NonNull::new_unchecked(
14670                    ffi::whiteout_m3_M3TrailingModel_get_animFloat1(self.raw.as_ptr()),
14671                ),
14672            })
14673        }
14674    }
14675
14676    /// Flag (observed: 1)
14677    pub fn flag(&self) -> u32 {
14678        // SAFETY: plain scalar read through a live handle.
14679        unsafe { ffi::whiteout_m3_M3TrailingModel_get_flag(self.raw.as_ptr()) }
14680    }
14681
14682    pub fn set_flag(&mut self, value: u32) {
14683        // SAFETY: plain scalar write through a live handle.
14684        unsafe { ffi::whiteout_m3_M3TrailingModel_set_flag(self.raw.as_ptr(), value) }
14685    }
14686
14687    /// Reserved
14688    pub fn reserved_0(&self) -> u32 {
14689        // SAFETY: plain scalar read through a live handle.
14690        unsafe { ffi::whiteout_m3_M3TrailingModel_get_reserved0(self.raw.as_ptr()) }
14691    }
14692
14693    pub fn set_reserved_0(&mut self, value: u32) {
14694        // SAFETY: plain scalar write through a live handle.
14695        unsafe { ffi::whiteout_m3_M3TrailingModel_set_reserved0(self.raw.as_ptr(), value) }
14696    }
14697
14698    /// Reserved
14699    pub fn reserved_1(&self) -> u32 {
14700        // SAFETY: plain scalar read through a live handle.
14701        unsafe { ffi::whiteout_m3_M3TrailingModel_get_reserved1(self.raw.as_ptr()) }
14702    }
14703
14704    pub fn set_reserved_1(&mut self, value: u32) {
14705        // SAFETY: plain scalar write through a live handle.
14706        unsafe { ffi::whiteout_m3_M3TrailingModel_set_reserved1(self.raw.as_ptr(), value) }
14707    }
14708}
14709
14710impl Default for TrailingModel {
14711    fn default() -> Self {
14712        Self::new()
14713    }
14714}
14715
14716/// FOR_ — Force field (v0–v2, 104 bytes)
14717///
14718/// Applies radial, wind, or explosion forces to particles and ribbons within an influence volume shape (sphere, cylinder, box, hemisphere).
14719pub struct Force {
14720    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3Force>,
14721}
14722
14723impl Drop for Force {
14724    fn drop(&mut self) {
14725        // SAFETY: `raw` came from a native constructor and Drop runs once.
14726        unsafe { ffi::whiteout_m3_M3Force_delete(self.raw.as_ptr()) }
14727    }
14728}
14729
14730impl Force {
14731    /// # Safety
14732    /// `raw` must be a live handle this value takes ownership of.
14733    #[allow(dead_code)] // used by whichever methods return this type
14734    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3Force) -> Option<Self> {
14735        core::ptr::NonNull::new(raw).map(|raw| Force { raw })
14736    }
14737}
14738
14739// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
14740// is deliberately NOT implemented — the C++ types make no documented
14741// guarantee about concurrent use, and claiming one we haven't verified
14742// would be unsound. See `@bind thread_safe` in the plan.
14743unsafe impl Send for Force {}
14744
14745impl core::fmt::Debug for Force {
14746    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
14747        f.debug_struct("Force").finish_non_exhaustive()
14748    }
14749}
14750
14751impl Force {
14752    /// # Panics
14753    /// Panics if the native allocation fails.
14754    pub fn new() -> Self {
14755        // SAFETY: the native constructor returns a live handle; a null here
14756        // means the library is unusable.
14757        unsafe {
14758            let raw = ffi::whiteout_m3_M3Force_new();
14759            Self::from_raw(raw).expect("native Force allocation failed")
14760        }
14761    }
14762
14763    /// Force influence type (radial/wind/explosion)
14764    pub fn force_type(&self) -> ForceType {
14765        // SAFETY: scalar read; the discriminant is validated below.
14766        unsafe { ffi::whiteout_m3_M3Force_get_forceType(self.raw.as_ptr()) }
14767            .try_into()
14768            .expect("unknown enum discriminant from the native library")
14769    }
14770
14771    pub fn set_force_type(&mut self, value: ForceType) {
14772        // SAFETY: scalar write through a live handle.
14773        unsafe { ffi::whiteout_m3_M3Force_set_forceType(self.raw.as_ptr(), value as i32) }
14774    }
14775
14776    /// Influence volume shape
14777    pub fn force_shape(&self) -> ForceShape {
14778        // SAFETY: scalar read; the discriminant is validated below.
14779        unsafe { ffi::whiteout_m3_M3Force_get_forceShape(self.raw.as_ptr()) }
14780            .try_into()
14781            .expect("unknown enum discriminant from the native library")
14782    }
14783
14784    pub fn set_force_shape(&mut self, value: ForceShape) {
14785        // SAFETY: scalar write through a live handle.
14786        unsafe { ffi::whiteout_m3_M3Force_set_forceShape(self.raw.as_ptr(), value as i32) }
14787    }
14788
14789    /// Unknown field
14790    pub fn unknown(&self) -> u32 {
14791        // SAFETY: plain scalar read through a live handle.
14792        unsafe { ffi::whiteout_m3_M3Force_get_unknown(self.raw.as_ptr()) }
14793    }
14794
14795    pub fn set_unknown(&mut self, value: u32) {
14796        // SAFETY: plain scalar write through a live handle.
14797        unsafe { ffi::whiteout_m3_M3Force_set_unknown(self.raw.as_ptr(), value) }
14798    }
14799
14800    /// Index into BONE array
14801    pub fn bone_index(&self) -> u32 {
14802        // SAFETY: plain scalar read through a live handle.
14803        unsafe { ffi::whiteout_m3_M3Force_get_boneIndex(self.raw.as_ptr()) }
14804    }
14805
14806    pub fn set_bone_index(&mut self, value: u32) {
14807        // SAFETY: plain scalar write through a live handle.
14808        unsafe { ffi::whiteout_m3_M3Force_set_boneIndex(self.raw.as_ptr(), value) }
14809    }
14810
14811    /// Force flags (falloff, height gradient, unbounded)
14812    pub fn flags(&self) -> ForceFlag {
14813        // SAFETY: scalar read; a flag set accepts any bits.
14814        ForceFlag(unsafe { ffi::whiteout_m3_M3Force_get_flags(self.raw.as_ptr()) })
14815    }
14816
14817    pub fn set_flags(&mut self, value: ForceFlag) {
14818        // SAFETY: scalar write through a live handle.
14819        unsafe { ffi::whiteout_m3_M3Force_set_flags(self.raw.as_ptr(), value.0) }
14820    }
14821
14822    /// Local channel bitmask
14823    pub fn local_channels(&self) -> u32 {
14824        // SAFETY: plain scalar read through a live handle.
14825        unsafe { ffi::whiteout_m3_M3Force_get_localChannels(self.raw.as_ptr()) }
14826    }
14827
14828    pub fn set_local_channels(&mut self, value: u32) {
14829        // SAFETY: plain scalar write through a live handle.
14830        unsafe { ffi::whiteout_m3_M3Force_set_localChannels(self.raw.as_ptr(), value) }
14831    }
14832
14833    /// Animated force strength
14834    /// Borrows the field in place — no copy, no allocation.
14835    pub fn strength(&self) -> crate::support::Ref<'_, AnimRefF32> {
14836        // SAFETY: an interior pointer into `self`, valid for this
14837        // borrow and never freed by the `Ref`.
14838        unsafe {
14839            crate::support::Ref::new(AnimRefF32 {
14840                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Force_get_strength(
14841                    self.raw.as_ptr(),
14842                )),
14843            })
14844        }
14845    }
14846
14847    pub fn strength_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
14848        // SAFETY: as above; `&mut self` guarantees exclusivity.
14849        unsafe {
14850            crate::support::RefMut::new(AnimRefF32 {
14851                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Force_get_strength(
14852                    self.raw.as_ptr(),
14853                )),
14854            })
14855        }
14856    }
14857
14858    /// Animated influence width
14859    /// Borrows the field in place — no copy, no allocation.
14860    pub fn width(&self) -> crate::support::Ref<'_, AnimRefF32> {
14861        // SAFETY: an interior pointer into `self`, valid for this
14862        // borrow and never freed by the `Ref`.
14863        unsafe {
14864            crate::support::Ref::new(AnimRefF32 {
14865                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Force_get_width(
14866                    self.raw.as_ptr(),
14867                )),
14868            })
14869        }
14870    }
14871
14872    pub fn width_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
14873        // SAFETY: as above; `&mut self` guarantees exclusivity.
14874        unsafe {
14875            crate::support::RefMut::new(AnimRefF32 {
14876                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Force_get_width(
14877                    self.raw.as_ptr(),
14878                )),
14879            })
14880        }
14881    }
14882
14883    /// Animated influence height
14884    /// Borrows the field in place — no copy, no allocation.
14885    pub fn height(&self) -> crate::support::Ref<'_, AnimRefF32> {
14886        // SAFETY: an interior pointer into `self`, valid for this
14887        // borrow and never freed by the `Ref`.
14888        unsafe {
14889            crate::support::Ref::new(AnimRefF32 {
14890                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Force_get_height(
14891                    self.raw.as_ptr(),
14892                )),
14893            })
14894        }
14895    }
14896
14897    pub fn height_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
14898        // SAFETY: as above; `&mut self` guarantees exclusivity.
14899        unsafe {
14900            crate::support::RefMut::new(AnimRefF32 {
14901                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Force_get_height(
14902                    self.raw.as_ptr(),
14903                )),
14904            })
14905        }
14906    }
14907
14908    /// Animated influence length
14909    /// Borrows the field in place — no copy, no allocation.
14910    pub fn length(&self) -> crate::support::Ref<'_, AnimRefF32> {
14911        // SAFETY: an interior pointer into `self`, valid for this
14912        // borrow and never freed by the `Ref`.
14913        unsafe {
14914            crate::support::Ref::new(AnimRefF32 {
14915                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Force_get_length(
14916                    self.raw.as_ptr(),
14917                )),
14918            })
14919        }
14920    }
14921
14922    pub fn length_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
14923        // SAFETY: as above; `&mut self` guarantees exclusivity.
14924        unsafe {
14925            crate::support::RefMut::new(AnimRefF32 {
14926                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Force_get_length(
14927                    self.raw.as_ptr(),
14928                )),
14929            })
14930        }
14931    }
14932}
14933
14934impl Default for Force {
14935    fn default() -> Self {
14936        Self::new()
14937    }
14938}
14939
14940/// WRP_ — Warp field (v0–v1, 132 bytes)
14941///
14942/// Warps particle/ribbon trajectories with animated radius, height, and angular/axial/radial strength components.
14943pub struct Warp {
14944    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3Warp>,
14945}
14946
14947impl Drop for Warp {
14948    fn drop(&mut self) {
14949        // SAFETY: `raw` came from a native constructor and Drop runs once.
14950        unsafe { ffi::whiteout_m3_M3Warp_delete(self.raw.as_ptr()) }
14951    }
14952}
14953
14954impl Warp {
14955    /// # Safety
14956    /// `raw` must be a live handle this value takes ownership of.
14957    #[allow(dead_code)] // used by whichever methods return this type
14958    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3Warp) -> Option<Self> {
14959        core::ptr::NonNull::new(raw).map(|raw| Warp { raw })
14960    }
14961}
14962
14963// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
14964// is deliberately NOT implemented — the C++ types make no documented
14965// guarantee about concurrent use, and claiming one we haven't verified
14966// would be unsound. See `@bind thread_safe` in the plan.
14967unsafe impl Send for Warp {}
14968
14969impl core::fmt::Debug for Warp {
14970    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
14971        f.debug_struct("Warp").finish_non_exhaustive()
14972    }
14973}
14974
14975impl Warp {
14976    /// # Panics
14977    /// Panics if the native allocation fails.
14978    pub fn new() -> Self {
14979        // SAFETY: the native constructor returns a live handle; a null here
14980        // means the library is unusable.
14981        unsafe {
14982            let raw = ffi::whiteout_m3_M3Warp_new();
14983            Self::from_raw(raw).expect("native Warp allocation failed")
14984        }
14985    }
14986
14987    /// Warp type
14988    pub fn warp_type(&self) -> u32 {
14989        // SAFETY: plain scalar read through a live handle.
14990        unsafe { ffi::whiteout_m3_M3Warp_get_warpType(self.raw.as_ptr()) }
14991    }
14992
14993    pub fn set_warp_type(&mut self, value: u32) {
14994        // SAFETY: plain scalar write through a live handle.
14995        unsafe { ffi::whiteout_m3_M3Warp_set_warpType(self.raw.as_ptr(), value) }
14996    }
14997
14998    /// Index into BONE array
14999    pub fn bone_index(&self) -> u32 {
15000        // SAFETY: plain scalar read through a live handle.
15001        unsafe { ffi::whiteout_m3_M3Warp_get_boneIndex(self.raw.as_ptr()) }
15002    }
15003
15004    pub fn set_bone_index(&mut self, value: u32) {
15005        // SAFETY: plain scalar write through a live handle.
15006        unsafe { ffi::whiteout_m3_M3Warp_set_boneIndex(self.raw.as_ptr(), value) }
15007    }
15008
15009    /// Unknown field
15010    pub fn unknown(&self) -> u32 {
15011        // SAFETY: plain scalar read through a live handle.
15012        unsafe { ffi::whiteout_m3_M3Warp_get_unknown(self.raw.as_ptr()) }
15013    }
15014
15015    pub fn set_unknown(&mut self, value: u32) {
15016        // SAFETY: plain scalar write through a live handle.
15017        unsafe { ffi::whiteout_m3_M3Warp_set_unknown(self.raw.as_ptr(), value) }
15018    }
15019
15020    /// Animated warp radius
15021    /// Borrows the field in place — no copy, no allocation.
15022    pub fn radius(&self) -> crate::support::Ref<'_, AnimRefF32> {
15023        // SAFETY: an interior pointer into `self`, valid for this
15024        // borrow and never freed by the `Ref`.
15025        unsafe {
15026            crate::support::Ref::new(AnimRefF32 {
15027                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Warp_get_radius(
15028                    self.raw.as_ptr(),
15029                )),
15030            })
15031        }
15032    }
15033
15034    pub fn radius_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
15035        // SAFETY: as above; `&mut self` guarantees exclusivity.
15036        unsafe {
15037            crate::support::RefMut::new(AnimRefF32 {
15038                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Warp_get_radius(
15039                    self.raw.as_ptr(),
15040                )),
15041            })
15042        }
15043    }
15044
15045    /// Animated warp height
15046    /// Borrows the field in place — no copy, no allocation.
15047    pub fn height(&self) -> crate::support::Ref<'_, AnimRefF32> {
15048        // SAFETY: an interior pointer into `self`, valid for this
15049        // borrow and never freed by the `Ref`.
15050        unsafe {
15051            crate::support::Ref::new(AnimRefF32 {
15052                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Warp_get_height(
15053                    self.raw.as_ptr(),
15054                )),
15055            })
15056        }
15057    }
15058
15059    pub fn height_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
15060        // SAFETY: as above; `&mut self` guarantees exclusivity.
15061        unsafe {
15062            crate::support::RefMut::new(AnimRefF32 {
15063                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Warp_get_height(
15064                    self.raw.as_ptr(),
15065                )),
15066            })
15067        }
15068    }
15069
15070    /// Animated warp strength
15071    /// Borrows the field in place — no copy, no allocation.
15072    pub fn strength(&self) -> crate::support::Ref<'_, AnimRefF32> {
15073        // SAFETY: an interior pointer into `self`, valid for this
15074        // borrow and never freed by the `Ref`.
15075        unsafe {
15076            crate::support::Ref::new(AnimRefF32 {
15077                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Warp_get_strength(
15078                    self.raw.as_ptr(),
15079                )),
15080            })
15081        }
15082    }
15083
15084    pub fn strength_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
15085        // SAFETY: as above; `&mut self` guarantees exclusivity.
15086        unsafe {
15087            crate::support::RefMut::new(AnimRefF32 {
15088                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Warp_get_strength(
15089                    self.raw.as_ptr(),
15090                )),
15091            })
15092        }
15093    }
15094
15095    /// Animated angular component
15096    /// Borrows the field in place — no copy, no allocation.
15097    pub fn angular(&self) -> crate::support::Ref<'_, AnimRefF32> {
15098        // SAFETY: an interior pointer into `self`, valid for this
15099        // borrow and never freed by the `Ref`.
15100        unsafe {
15101            crate::support::Ref::new(AnimRefF32 {
15102                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Warp_get_angular(
15103                    self.raw.as_ptr(),
15104                )),
15105            })
15106        }
15107    }
15108
15109    pub fn angular_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
15110        // SAFETY: as above; `&mut self` guarantees exclusivity.
15111        unsafe {
15112            crate::support::RefMut::new(AnimRefF32 {
15113                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Warp_get_angular(
15114                    self.raw.as_ptr(),
15115                )),
15116            })
15117        }
15118    }
15119
15120    /// Animated axial component
15121    /// Borrows the field in place — no copy, no allocation.
15122    pub fn axial(&self) -> crate::support::Ref<'_, AnimRefF32> {
15123        // SAFETY: an interior pointer into `self`, valid for this
15124        // borrow and never freed by the `Ref`.
15125        unsafe {
15126            crate::support::Ref::new(AnimRefF32 {
15127                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Warp_get_axial(
15128                    self.raw.as_ptr(),
15129                )),
15130            })
15131        }
15132    }
15133
15134    pub fn axial_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
15135        // SAFETY: as above; `&mut self` guarantees exclusivity.
15136        unsafe {
15137            crate::support::RefMut::new(AnimRefF32 {
15138                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Warp_get_axial(
15139                    self.raw.as_ptr(),
15140                )),
15141            })
15142        }
15143    }
15144
15145    /// Animated radial component
15146    /// Borrows the field in place — no copy, no allocation.
15147    pub fn radial(&self) -> crate::support::Ref<'_, AnimRefF32> {
15148        // SAFETY: an interior pointer into `self`, valid for this
15149        // borrow and never freed by the `Ref`.
15150        unsafe {
15151            crate::support::Ref::new(AnimRefF32 {
15152                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Warp_get_radial(
15153                    self.raw.as_ptr(),
15154                )),
15155            })
15156        }
15157    }
15158
15159    pub fn radial_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
15160        // SAFETY: as above; `&mut self` guarantees exclusivity.
15161        unsafe {
15162            crate::support::RefMut::new(AnimRefF32 {
15163                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Warp_get_radial(
15164                    self.raw.as_ptr(),
15165                )),
15166            })
15167        }
15168    }
15169}
15170
15171impl Default for Warp {
15172    fn default() -> Self {
15173        Self::new()
15174    }
15175}
15176
15177/// DMSE — Convex hull half-edge (v0, 4 bytes)
15178///
15179/// Half-edge connectivity for PHSH convex hull shapes (shapeType = 4). Entries are stored in consecutive twin pairs (forward 0x01 / reverse 0xFF). The nextAroundVertex field chains half-edges into closed per-vertex rings.
15180pub struct ConvexHullHalfEdge {
15181    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3ConvexHullHalfEdge>,
15182}
15183
15184impl Drop for ConvexHullHalfEdge {
15185    fn drop(&mut self) {
15186        // SAFETY: `raw` came from a native constructor and Drop runs once.
15187        unsafe { ffi::whiteout_m3_M3ConvexHullHalfEdge_delete(self.raw.as_ptr()) }
15188    }
15189}
15190
15191impl ConvexHullHalfEdge {
15192    /// # Safety
15193    /// `raw` must be a live handle this value takes ownership of.
15194    #[allow(dead_code)] // used by whichever methods return this type
15195    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3ConvexHullHalfEdge) -> Option<Self> {
15196        core::ptr::NonNull::new(raw).map(|raw| ConvexHullHalfEdge { raw })
15197    }
15198}
15199
15200// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
15201// is deliberately NOT implemented — the C++ types make no documented
15202// guarantee about concurrent use, and claiming one we haven't verified
15203// would be unsound. See `@bind thread_safe` in the plan.
15204unsafe impl Send for ConvexHullHalfEdge {}
15205
15206impl core::fmt::Debug for ConvexHullHalfEdge {
15207    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
15208        f.debug_struct("ConvexHullHalfEdge").finish_non_exhaustive()
15209    }
15210}
15211
15212impl ConvexHullHalfEdge {
15213    /// # Panics
15214    /// Panics if the native allocation fails.
15215    pub fn new() -> Self {
15216        // SAFETY: the native constructor returns a live handle; a null here
15217        // means the library is unusable.
15218        unsafe {
15219            let raw = ffi::whiteout_m3_M3ConvexHullHalfEdge_new();
15220            Self::from_raw(raw).expect("native ConvexHullHalfEdge allocation failed")
15221        }
15222    }
15223
15224    /// 0x01 = forward, 0xFF = reverse (twin)
15225    pub fn type_(&self) -> u8 {
15226        // SAFETY: plain scalar read through a live handle.
15227        unsafe { ffi::whiteout_m3_M3ConvexHullHalfEdge_get_type(self.raw.as_ptr()) }
15228    }
15229
15230    pub fn set_type_(&mut self, value: u8) {
15231        // SAFETY: plain scalar write through a live handle.
15232        unsafe { ffi::whiteout_m3_M3ConvexHullHalfEdge_set_type(self.raw.as_ptr(), value) }
15233    }
15234
15235    /// Face this half-edge borders
15236    pub fn face_index(&self) -> u8 {
15237        // SAFETY: plain scalar read through a live handle.
15238        unsafe { ffi::whiteout_m3_M3ConvexHullHalfEdge_get_faceIndex(self.raw.as_ptr()) }
15239    }
15240
15241    pub fn set_face_index(&mut self, value: u8) {
15242        // SAFETY: plain scalar write through a live handle.
15243        unsafe { ffi::whiteout_m3_M3ConvexHullHalfEdge_set_faceIndex(self.raw.as_ptr(), value) }
15244    }
15245
15246    /// Target vertex of this half-edge
15247    pub fn vertex_index(&self) -> u8 {
15248        // SAFETY: plain scalar read through a live handle.
15249        unsafe { ffi::whiteout_m3_M3ConvexHullHalfEdge_get_vertexIndex(self.raw.as_ptr()) }
15250    }
15251
15252    pub fn set_vertex_index(&mut self, value: u8) {
15253        // SAFETY: plain scalar write through a live handle.
15254        unsafe { ffi::whiteout_m3_M3ConvexHullHalfEdge_set_vertexIndex(self.raw.as_ptr(), value) }
15255    }
15256
15257    /// Next half-edge around the same vertex
15258    pub fn next_around_vertex(&self) -> u8 {
15259        // SAFETY: plain scalar read through a live handle.
15260        unsafe { ffi::whiteout_m3_M3ConvexHullHalfEdge_get_nextAroundVertex(self.raw.as_ptr()) }
15261    }
15262
15263    pub fn set_next_around_vertex(&mut self, value: u8) {
15264        // SAFETY: plain scalar write through a live handle.
15265        unsafe {
15266            ffi::whiteout_m3_M3ConvexHullHalfEdge_set_nextAroundVertex(self.raw.as_ptr(), value)
15267        }
15268    }
15269}
15270
15271impl Default for ConvexHullHalfEdge {
15272    fn default() -> Self {
15273        Self::new()
15274    }
15275}
15276
15277/// DMMN — Physics mesh BVH node (v0: 12 bytes, v1: 8 bytes)
15278///
15279/// DMMN entries form a linearized k-DOP Bounding Volume Hierarchy (BVH) tree for concave mesh collision. The entry count is always odd: n = 2*n_leaves - 1.
15280///
15281/// **Tree structure** — right-skewed binary tree stored in DFS preorder: - Array layout: (INT_0, LEAF_1), (INT_2, LEAF_3), ..., LEAF_{n-1} - Even indices 0..n-3: internal nodes - Odd indices 1..n-2: leaf nodes - Last index n-1: leaf node - Each internal node 2k: left child = leaf 2k+1, right child = node 2k+2
15282///
15283/// **v0** (Havok-era, 12 bytes per node) — stores only the slab normal direction as a plain Vector3f. No quantized slab bounds are present; the tree topology and bounding-slab directions are identical to v1, but distance culling relies on the runtime computing slab projections against meshBoundsCenter/Extent. Only 3 files in the corpus use v0 (all with PHSH v2).
15284///
15285/// **v1** (Domino physics, 8 bytes per node) — octahedral-encoded normal + quantized slab bounds: - i16 octX, octY: octahedral-mapped slab normal (snorm16 pair) - u16 slabMin, slabMax: quantized bounding-slab distances along the normal - Internal nodes: slabMax != 0; leaf sentinel: slabMax == 0 (except the last node, which may have slabMax != 0 despite being a leaf)
15286///
15287/// **Quantization** (v1, universally confirmed across 468 corpus files): - Per-axis step: tol_i = extent_i / 32767 - Projected step: tol_proj = dot(tolerance, |normal|) - Slab values quantized as: q = round(projection / tol_proj) - Root node slab range approaches [-32767, +32767] (full AABB)
15288///
15289/// Internal nodes use one slab direction; their paired leaf uses a DIFFERENT slab direction, forming a 2-DOP bound per primitive group. Most trees (391/468) use multiple slab normals across internal levels for tighter culling.
15290///
15291/// PHSH meshTreeDepth gives the tree height (longest root-to-leaf path in nodes).
15292pub struct PhysicsMeshBvhNode {
15293    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3PhysicsMeshBvhNode>,
15294}
15295
15296impl Drop for PhysicsMeshBvhNode {
15297    fn drop(&mut self) {
15298        // SAFETY: `raw` came from a native constructor and Drop runs once.
15299        unsafe { ffi::whiteout_m3_M3PhysicsMeshBvhNode_delete(self.raw.as_ptr()) }
15300    }
15301}
15302
15303impl PhysicsMeshBvhNode {
15304    /// # Safety
15305    /// `raw` must be a live handle this value takes ownership of.
15306    #[allow(dead_code)] // used by whichever methods return this type
15307    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3PhysicsMeshBvhNode) -> Option<Self> {
15308        core::ptr::NonNull::new(raw).map(|raw| PhysicsMeshBvhNode { raw })
15309    }
15310}
15311
15312// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
15313// is deliberately NOT implemented — the C++ types make no documented
15314// guarantee about concurrent use, and claiming one we haven't verified
15315// would be unsound. See `@bind thread_safe` in the plan.
15316unsafe impl Send for PhysicsMeshBvhNode {}
15317
15318impl core::fmt::Debug for PhysicsMeshBvhNode {
15319    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
15320        f.debug_struct("PhysicsMeshBvhNode").finish_non_exhaustive()
15321    }
15322}
15323
15324impl PhysicsMeshBvhNode {
15325    /// # Panics
15326    /// Panics if the native allocation fails.
15327    pub fn new() -> Self {
15328        // SAFETY: the native constructor returns a live handle; a null here
15329        // means the library is unusable.
15330        unsafe {
15331            let raw = ffi::whiteout_m3_M3PhysicsMeshBvhNode_new();
15332            Self::from_raw(raw).expect("native PhysicsMeshBvhNode allocation failed")
15333        }
15334    }
15335}
15336
15337impl Default for PhysicsMeshBvhNode {
15338    fn default() -> Self {
15339        Self::new()
15340    }
15341}
15342
15343/// DMMT — Physics mesh triangle (v0, 28 bytes)
15344pub struct PhysicsMeshTriangle {
15345    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3PhysicsMeshTriangle>,
15346}
15347
15348impl Drop for PhysicsMeshTriangle {
15349    fn drop(&mut self) {
15350        // SAFETY: `raw` came from a native constructor and Drop runs once.
15351        unsafe { ffi::whiteout_m3_M3PhysicsMeshTriangle_delete(self.raw.as_ptr()) }
15352    }
15353}
15354
15355impl PhysicsMeshTriangle {
15356    /// # Safety
15357    /// `raw` must be a live handle this value takes ownership of.
15358    #[allow(dead_code)] // used by whichever methods return this type
15359    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3PhysicsMeshTriangle) -> Option<Self> {
15360        core::ptr::NonNull::new(raw).map(|raw| PhysicsMeshTriangle { raw })
15361    }
15362}
15363
15364// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
15365// is deliberately NOT implemented — the C++ types make no documented
15366// guarantee about concurrent use, and claiming one we haven't verified
15367// would be unsound. See `@bind thread_safe` in the plan.
15368unsafe impl Send for PhysicsMeshTriangle {}
15369
15370impl core::fmt::Debug for PhysicsMeshTriangle {
15371    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
15372        f.debug_struct("PhysicsMeshTriangle")
15373            .finish_non_exhaustive()
15374    }
15375}
15376
15377impl PhysicsMeshTriangle {
15378    /// # Panics
15379    /// Panics if the native allocation fails.
15380    pub fn new() -> Self {
15381        // SAFETY: the native constructor returns a live handle; a null here
15382        // means the library is unusable.
15383        unsafe {
15384            let raw = ffi::whiteout_m3_M3PhysicsMeshTriangle_new();
15385            Self::from_raw(raw).expect("native PhysicsMeshTriangle allocation failed")
15386        }
15387    }
15388
15389    /// First vertex index
15390    pub fn vertex_index_0(&self) -> u32 {
15391        // SAFETY: plain scalar read through a live handle.
15392        unsafe { ffi::whiteout_m3_M3PhysicsMeshTriangle_get_vertexIndex0(self.raw.as_ptr()) }
15393    }
15394
15395    pub fn set_vertex_index_0(&mut self, value: u32) {
15396        // SAFETY: plain scalar write through a live handle.
15397        unsafe { ffi::whiteout_m3_M3PhysicsMeshTriangle_set_vertexIndex0(self.raw.as_ptr(), value) }
15398    }
15399
15400    /// Second vertex index
15401    pub fn vertex_index_1(&self) -> u32 {
15402        // SAFETY: plain scalar read through a live handle.
15403        unsafe { ffi::whiteout_m3_M3PhysicsMeshTriangle_get_vertexIndex1(self.raw.as_ptr()) }
15404    }
15405
15406    pub fn set_vertex_index_1(&mut self, value: u32) {
15407        // SAFETY: plain scalar write through a live handle.
15408        unsafe { ffi::whiteout_m3_M3PhysicsMeshTriangle_set_vertexIndex1(self.raw.as_ptr(), value) }
15409    }
15410
15411    /// Third vertex index
15412    pub fn vertex_index_2(&self) -> u32 {
15413        // SAFETY: plain scalar read through a live handle.
15414        unsafe { ffi::whiteout_m3_M3PhysicsMeshTriangle_get_vertexIndex2(self.raw.as_ptr()) }
15415    }
15416
15417    pub fn set_vertex_index_2(&mut self, value: u32) {
15418        // SAFETY: plain scalar write through a live handle.
15419        unsafe { ffi::whiteout_m3_M3PhysicsMeshTriangle_set_vertexIndex2(self.raw.as_ptr(), value) }
15420    }
15421
15422    /// First edge index
15423    pub fn edge_index_0(&self) -> u32 {
15424        // SAFETY: plain scalar read through a live handle.
15425        unsafe { ffi::whiteout_m3_M3PhysicsMeshTriangle_get_edgeIndex0(self.raw.as_ptr()) }
15426    }
15427
15428    pub fn set_edge_index_0(&mut self, value: u32) {
15429        // SAFETY: plain scalar write through a live handle.
15430        unsafe { ffi::whiteout_m3_M3PhysicsMeshTriangle_set_edgeIndex0(self.raw.as_ptr(), value) }
15431    }
15432
15433    /// Second edge index
15434    pub fn edge_index_1(&self) -> u32 {
15435        // SAFETY: plain scalar read through a live handle.
15436        unsafe { ffi::whiteout_m3_M3PhysicsMeshTriangle_get_edgeIndex1(self.raw.as_ptr()) }
15437    }
15438
15439    pub fn set_edge_index_1(&mut self, value: u32) {
15440        // SAFETY: plain scalar write through a live handle.
15441        unsafe { ffi::whiteout_m3_M3PhysicsMeshTriangle_set_edgeIndex1(self.raw.as_ptr(), value) }
15442    }
15443
15444    /// Third edge index
15445    pub fn edge_index_2(&self) -> u32 {
15446        // SAFETY: plain scalar read through a live handle.
15447        unsafe { ffi::whiteout_m3_M3PhysicsMeshTriangle_get_edgeIndex2(self.raw.as_ptr()) }
15448    }
15449
15450    pub fn set_edge_index_2(&mut self, value: u32) {
15451        // SAFETY: plain scalar write through a live handle.
15452        unsafe { ffi::whiteout_m3_M3PhysicsMeshTriangle_set_edgeIndex2(self.raw.as_ptr(), value) }
15453    }
15454
15455    /// Reserved
15456    pub fn reserved(&self) -> u16 {
15457        // SAFETY: plain scalar read through a live handle.
15458        unsafe { ffi::whiteout_m3_M3PhysicsMeshTriangle_get_reserved(self.raw.as_ptr()) }
15459    }
15460
15461    pub fn set_reserved(&mut self, value: u16) {
15462        // SAFETY: plain scalar write through a live handle.
15463        unsafe { ffi::whiteout_m3_M3PhysicsMeshTriangle_set_reserved(self.raw.as_ptr(), value) }
15464    }
15465
15466    /// Triangle flags
15467    pub fn flags(&self) -> u16 {
15468        // SAFETY: plain scalar read through a live handle.
15469        unsafe { ffi::whiteout_m3_M3PhysicsMeshTriangle_get_flags(self.raw.as_ptr()) }
15470    }
15471
15472    pub fn set_flags(&mut self, value: u16) {
15473        // SAFETY: plain scalar write through a live handle.
15474        unsafe { ffi::whiteout_m3_M3PhysicsMeshTriangle_set_flags(self.raw.as_ptr(), value) }
15475    }
15476}
15477
15478impl Default for PhysicsMeshTriangle {
15479    fn default() -> Self {
15480        Self::new()
15481    }
15482}
15483
15484/// DMME — Physics mesh edge (v0, 20 bytes)
15485pub struct PhysicsMeshEdge {
15486    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3PhysicsMeshEdge>,
15487}
15488
15489impl Drop for PhysicsMeshEdge {
15490    fn drop(&mut self) {
15491        // SAFETY: `raw` came from a native constructor and Drop runs once.
15492        unsafe { ffi::whiteout_m3_M3PhysicsMeshEdge_delete(self.raw.as_ptr()) }
15493    }
15494}
15495
15496impl PhysicsMeshEdge {
15497    /// # Safety
15498    /// `raw` must be a live handle this value takes ownership of.
15499    #[allow(dead_code)] // used by whichever methods return this type
15500    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3PhysicsMeshEdge) -> Option<Self> {
15501        core::ptr::NonNull::new(raw).map(|raw| PhysicsMeshEdge { raw })
15502    }
15503}
15504
15505// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
15506// is deliberately NOT implemented — the C++ types make no documented
15507// guarantee about concurrent use, and claiming one we haven't verified
15508// would be unsound. See `@bind thread_safe` in the plan.
15509unsafe impl Send for PhysicsMeshEdge {}
15510
15511impl core::fmt::Debug for PhysicsMeshEdge {
15512    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
15513        f.debug_struct("PhysicsMeshEdge").finish_non_exhaustive()
15514    }
15515}
15516
15517impl PhysicsMeshEdge {
15518    /// # Panics
15519    /// Panics if the native allocation fails.
15520    pub fn new() -> Self {
15521        // SAFETY: the native constructor returns a live handle; a null here
15522        // means the library is unusable.
15523        unsafe {
15524            let raw = ffi::whiteout_m3_M3PhysicsMeshEdge_new();
15525            Self::from_raw(raw).expect("native PhysicsMeshEdge allocation failed")
15526        }
15527    }
15528
15529    /// Edge type
15530    pub fn edge_type(&self) -> u32 {
15531        // SAFETY: plain scalar read through a live handle.
15532        unsafe { ffi::whiteout_m3_M3PhysicsMeshEdge_get_edgeType(self.raw.as_ptr()) }
15533    }
15534
15535    pub fn set_edge_type(&mut self, value: u32) {
15536        // SAFETY: plain scalar write through a live handle.
15537        unsafe { ffi::whiteout_m3_M3PhysicsMeshEdge_set_edgeType(self.raw.as_ptr(), value) }
15538    }
15539
15540    /// First vertex index
15541    pub fn vertex_a(&self) -> u32 {
15542        // SAFETY: plain scalar read through a live handle.
15543        unsafe { ffi::whiteout_m3_M3PhysicsMeshEdge_get_vertexA(self.raw.as_ptr()) }
15544    }
15545
15546    pub fn set_vertex_a(&mut self, value: u32) {
15547        // SAFETY: plain scalar write through a live handle.
15548        unsafe { ffi::whiteout_m3_M3PhysicsMeshEdge_set_vertexA(self.raw.as_ptr(), value) }
15549    }
15550
15551    /// Second vertex index
15552    pub fn vertex_b(&self) -> u32 {
15553        // SAFETY: plain scalar read through a live handle.
15554        unsafe { ffi::whiteout_m3_M3PhysicsMeshEdge_get_vertexB(self.raw.as_ptr()) }
15555    }
15556
15557    pub fn set_vertex_b(&mut self, value: u32) {
15558        // SAFETY: plain scalar write through a live handle.
15559        unsafe { ffi::whiteout_m3_M3PhysicsMeshEdge_set_vertexB(self.raw.as_ptr(), value) }
15560    }
15561
15562    /// First adjacent face
15563    pub fn face_a(&self) -> u32 {
15564        // SAFETY: plain scalar read through a live handle.
15565        unsafe { ffi::whiteout_m3_M3PhysicsMeshEdge_get_faceA(self.raw.as_ptr()) }
15566    }
15567
15568    pub fn set_face_a(&mut self, value: u32) {
15569        // SAFETY: plain scalar write through a live handle.
15570        unsafe { ffi::whiteout_m3_M3PhysicsMeshEdge_set_faceA(self.raw.as_ptr(), value) }
15571    }
15572
15573    /// Second adjacent face
15574    pub fn face_b(&self) -> u32 {
15575        // SAFETY: plain scalar read through a live handle.
15576        unsafe { ffi::whiteout_m3_M3PhysicsMeshEdge_get_faceB(self.raw.as_ptr()) }
15577    }
15578
15579    pub fn set_face_b(&mut self, value: u32) {
15580        // SAFETY: plain scalar write through a live handle.
15581        unsafe { ffi::whiteout_m3_M3PhysicsMeshEdge_set_faceB(self.raw.as_ptr(), value) }
15582    }
15583}
15584
15585impl Default for PhysicsMeshEdge {
15586    fn default() -> Self {
15587        Self::new()
15588    }
15589}
15590
15591/// PHSH — Physics shape (v0–v3, 132–300 bytes)
15592///
15593/// The 300-byte v3 layout is a three-part union. Bytes 0–79 are the common header. Bytes 80–103 hold shape dimensions for simple shapes (0–3) or are zero for complex shapes. Bytes 80–183 form the convex hull section (shapeType 4); bytes 184–299 form the mesh section (shapeType 5).
15594pub struct PhysicsShape {
15595    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3PhysicsShape>,
15596}
15597
15598impl Drop for PhysicsShape {
15599    fn drop(&mut self) {
15600        // SAFETY: `raw` came from a native constructor and Drop runs once.
15601        unsafe { ffi::whiteout_m3_M3PhysicsShape_delete(self.raw.as_ptr()) }
15602    }
15603}
15604
15605impl PhysicsShape {
15606    /// # Safety
15607    /// `raw` must be a live handle this value takes ownership of.
15608    #[allow(dead_code)] // used by whichever methods return this type
15609    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3PhysicsShape) -> Option<Self> {
15610        core::ptr::NonNull::new(raw).map(|raw| PhysicsShape { raw })
15611    }
15612}
15613
15614// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
15615// is deliberately NOT implemented — the C++ types make no documented
15616// guarantee about concurrent use, and claiming one we haven't verified
15617// would be unsound. See `@bind thread_safe` in the plan.
15618unsafe impl Send for PhysicsShape {}
15619
15620impl core::fmt::Debug for PhysicsShape {
15621    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
15622        f.debug_struct("PhysicsShape").finish_non_exhaustive()
15623    }
15624}
15625
15626impl PhysicsShape {
15627    /// # Panics
15628    /// Panics if the native allocation fails.
15629    pub fn new() -> Self {
15630        // SAFETY: the native constructor returns a live handle; a null here
15631        // means the library is unusable.
15632        unsafe {
15633            let raw = ffi::whiteout_m3_M3PhysicsShape_new();
15634            Self::from_raw(raw).expect("native PhysicsShape allocation failed")
15635        }
15636    }
15637
15638    /// Havok convex radius (v1 only, ≈ 0.019685)
15639    pub fn collision_margin(&self) -> f32 {
15640        // SAFETY: plain scalar read through a live handle.
15641        unsafe { ffi::whiteout_m3_M3PhysicsShape_get_collisionMargin(self.raw.as_ptr()) }
15642    }
15643
15644    pub fn set_collision_margin(&mut self, value: f32) {
15645        // SAFETY: plain scalar write through a live handle.
15646        unsafe { ffi::whiteout_m3_M3PhysicsShape_set_collisionMargin(self.raw.as_ptr(), value) }
15647    }
15648
15649    /// Shape type (box/sphere/capsule/cylinder/hull/mesh)
15650    pub fn shape_type(&self) -> PhysicsShapeType {
15651        // SAFETY: scalar read; the discriminant is validated below.
15652        unsafe { ffi::whiteout_m3_M3PhysicsShape_get_shapeType(self.raw.as_ptr()) }
15653            .try_into()
15654            .expect("unknown enum discriminant from the native library")
15655    }
15656
15657    pub fn set_shape_type(&mut self, value: PhysicsShapeType) {
15658        // SAFETY: scalar write through a live handle.
15659        unsafe { ffi::whiteout_m3_M3PhysicsShape_set_shapeType(self.raw.as_ptr(), value as i32) }
15660    }
15661
15662    /// Legacy sizes (v1 only, zero for shapeType 4–5)
15663    pub fn old_sizes(&self) -> crate::math::Vector3f {
15664        // SAFETY: the getter returns an interior pointer to a
15665        // layout-identical POD; we copy it out immediately.
15666        unsafe {
15667            *(ffi::whiteout_m3_M3PhysicsShape_get_oldSizes(self.raw.as_ptr())
15668                as *const crate::math::Vector3f)
15669        }
15670    }
15671
15672    pub fn set_old_sizes(&mut self, value: crate::math::Vector3f) {
15673        // SAFETY: as above, in the other direction.
15674        unsafe {
15675            ffi::whiteout_m3_M3PhysicsShape_set_oldSizes(
15676                self.raw.as_ptr(),
15677                &value as *const crate::math::Vector3f as *const _,
15678            )
15679        }
15680    }
15681
15682    /// Shape dimensions (v2+, zero for complex shapes)
15683    pub fn shape_dimensions(&self) -> crate::math::Vector3f {
15684        // SAFETY: the getter returns an interior pointer to a
15685        // layout-identical POD; we copy it out immediately.
15686        unsafe {
15687            *(ffi::whiteout_m3_M3PhysicsShape_get_shapeDimensions(self.raw.as_ptr())
15688                as *const crate::math::Vector3f)
15689        }
15690    }
15691
15692    pub fn set_shape_dimensions(&mut self, value: crate::math::Vector3f) {
15693        // SAFETY: as above, in the other direction.
15694        unsafe {
15695            ffi::whiteout_m3_M3PhysicsShape_set_shapeDimensions(
15696                self.raw.as_ptr(),
15697                &value as *const crate::math::Vector3f as *const _,
15698            )
15699        }
15700    }
15701
15702    /// Per-face unit normals (VEC3)
15703    /// Zero-copy view of the underlying `std::vector`.
15704    pub fn hull_face_normals(&self) -> &[crate::math::Vector3f] {
15705        // SAFETY: `_data`/`_count` describe one contiguous C++
15706        // allocation, borrowed for as long as `self` is.
15707        unsafe {
15708            let n = ffi::whiteout_m3_M3PhysicsShape_get_hullFaceNormals_count(self.raw.as_ptr());
15709            let p = ffi::whiteout_m3_M3PhysicsShape_get_hullFaceNormals_data(self.raw.as_ptr())
15710                as *const crate::math::Vector3f;
15711            if p.is_null() || n == 0 {
15712                &[]
15713            } else {
15714                core::slice::from_raw_parts(p, n)
15715            }
15716        }
15717    }
15718
15719    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
15720    pub fn hull_face_normals_mut(&mut self) -> &mut [crate::math::Vector3f] {
15721        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
15722        unsafe {
15723            let n = ffi::whiteout_m3_M3PhysicsShape_get_hullFaceNormals_count(self.raw.as_ptr());
15724            let p = ffi::whiteout_m3_M3PhysicsShape_get_hullFaceNormals_data(self.raw.as_ptr())
15725                as *const crate::math::Vector3f as *mut crate::math::Vector3f;
15726            if p.is_null() || n == 0 {
15727                &mut []
15728            } else {
15729                core::slice::from_raw_parts_mut(p, n)
15730            }
15731        }
15732    }
15733
15734    pub fn set_hull_face_normals(&mut self, values: &[crate::math::Vector3f]) {
15735        // SAFETY: the native side copies `values` before returning.
15736        unsafe {
15737            ffi::whiteout_m3_M3PhysicsShape_assign_hullFaceNormals(
15738                self.raw.as_ptr(),
15739                values.as_ptr() as *const _,
15740                values.len(),
15741            )
15742        }
15743    }
15744
15745    pub fn resize_hull_face_normals(&mut self, count: usize) {
15746        // SAFETY: reallocation is safe here precisely because
15747        // `&mut self` means no slice borrow is outstanding.
15748        unsafe { ffi::whiteout_m3_M3PhysicsShape_resize_hullFaceNormals(self.raw.as_ptr(), count) }
15749    }
15750
15751    /// Vertex positions, w=0 (VEC4)
15752    /// Zero-copy view of the underlying `std::vector`.
15753    pub fn hull_vertex_positions(&self) -> &[crate::math::Vector4f] {
15754        // SAFETY: `_data`/`_count` describe one contiguous C++
15755        // allocation, borrowed for as long as `self` is.
15756        unsafe {
15757            let n =
15758                ffi::whiteout_m3_M3PhysicsShape_get_hullVertexPositions_count(self.raw.as_ptr());
15759            let p = ffi::whiteout_m3_M3PhysicsShape_get_hullVertexPositions_data(self.raw.as_ptr())
15760                as *const crate::math::Vector4f;
15761            if p.is_null() || n == 0 {
15762                &[]
15763            } else {
15764                core::slice::from_raw_parts(p, n)
15765            }
15766        }
15767    }
15768
15769    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
15770    pub fn hull_vertex_positions_mut(&mut self) -> &mut [crate::math::Vector4f] {
15771        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
15772        unsafe {
15773            let n =
15774                ffi::whiteout_m3_M3PhysicsShape_get_hullVertexPositions_count(self.raw.as_ptr());
15775            let p = ffi::whiteout_m3_M3PhysicsShape_get_hullVertexPositions_data(self.raw.as_ptr())
15776                as *const crate::math::Vector4f as *mut crate::math::Vector4f;
15777            if p.is_null() || n == 0 {
15778                &mut []
15779            } else {
15780                core::slice::from_raw_parts_mut(p, n)
15781            }
15782        }
15783    }
15784
15785    pub fn set_hull_vertex_positions(&mut self, values: &[crate::math::Vector4f]) {
15786        // SAFETY: the native side copies `values` before returning.
15787        unsafe {
15788            ffi::whiteout_m3_M3PhysicsShape_assign_hullVertexPositions(
15789                self.raw.as_ptr(),
15790                values.as_ptr() as *const _,
15791                values.len(),
15792            )
15793        }
15794    }
15795
15796    pub fn resize_hull_vertex_positions(&mut self, count: usize) {
15797        // SAFETY: reallocation is safe here precisely because
15798        // `&mut self` means no slice borrow is outstanding.
15799        unsafe {
15800            ffi::whiteout_m3_M3PhysicsShape_resize_hullVertexPositions(self.raw.as_ptr(), count)
15801        }
15802    }
15803
15804    /// Half-edge table (DMSE)
15805    pub fn hull_half_edges_len(&self) -> usize {
15806        // SAFETY: scalar read through a live handle.
15807        unsafe { ffi::whiteout_m3_M3PhysicsShape_get_hullHalfEdges_count(self.raw.as_ptr()) }
15808    }
15809
15810    /// Borrows element `index` in place. `None` when out of range.
15811    pub fn hull_half_edges(
15812        &self,
15813        index: usize,
15814    ) -> Option<crate::support::Ref<'_, ConvexHullHalfEdge>> {
15815        if index >= self.hull_half_edges_len() {
15816            return None;
15817        }
15818        // SAFETY: index checked above; the pointer is interior to `self`.
15819        unsafe {
15820            Some(crate::support::Ref::new(ConvexHullHalfEdge {
15821                raw: core::ptr::NonNull::new_unchecked(
15822                    ffi::whiteout_m3_M3PhysicsShape_get_hullHalfEdges_at(self.raw.as_ptr(), index),
15823                ),
15824            }))
15825        }
15826    }
15827
15828    pub fn hull_half_edges_mut(
15829        &mut self,
15830        index: usize,
15831    ) -> Option<crate::support::RefMut<'_, ConvexHullHalfEdge>> {
15832        if index >= self.hull_half_edges_len() {
15833            return None;
15834        }
15835        // SAFETY: as above; `&mut self` guarantees exclusivity.
15836        unsafe {
15837            Some(crate::support::RefMut::new(ConvexHullHalfEdge {
15838                raw: core::ptr::NonNull::new_unchecked(
15839                    ffi::whiteout_m3_M3PhysicsShape_get_hullHalfEdges_at(self.raw.as_ptr(), index),
15840                ),
15841            }))
15842        }
15843    }
15844
15845    /// Iterate the elements, borrowing each in turn.
15846    pub fn hull_half_edges_iter(
15847        &self,
15848    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, ConvexHullHalfEdge>> {
15849        (0..self.hull_half_edges_len())
15850            .map(move |i| self.hull_half_edges(i).expect("index below len"))
15851    }
15852
15853    pub fn resize_hull_half_edges(&mut self, count: usize) {
15854        // SAFETY: exclusive access, so no borrow is outstanding.
15855        unsafe { ffi::whiteout_m3_M3PhysicsShape_resize_hullHalfEdges(self.raw.as_ptr(), count) }
15856    }
15857
15858    /// One face index per vertex (U8__)
15859    /// Zero-copy view of the underlying `std::vector`.
15860    pub fn hull_vertex_face_indices(&self) -> &[u8] {
15861        // SAFETY: `_data`/`_count` describe one contiguous C++
15862        // allocation, borrowed for as long as `self` is.
15863        unsafe {
15864            let n =
15865                ffi::whiteout_m3_M3PhysicsShape_get_hullVertexFaceIndices_count(self.raw.as_ptr());
15866            let p =
15867                ffi::whiteout_m3_M3PhysicsShape_get_hullVertexFaceIndices_data(self.raw.as_ptr());
15868            if p.is_null() || n == 0 {
15869                &[]
15870            } else {
15871                core::slice::from_raw_parts(p, n)
15872            }
15873        }
15874    }
15875
15876    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
15877    pub fn hull_vertex_face_indices_mut(&mut self) -> &mut [u8] {
15878        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
15879        unsafe {
15880            let n =
15881                ffi::whiteout_m3_M3PhysicsShape_get_hullVertexFaceIndices_count(self.raw.as_ptr());
15882            let p =
15883                ffi::whiteout_m3_M3PhysicsShape_get_hullVertexFaceIndices_data(self.raw.as_ptr())
15884                    as *mut u8;
15885            if p.is_null() || n == 0 {
15886                &mut []
15887            } else {
15888                core::slice::from_raw_parts_mut(p, n)
15889            }
15890        }
15891    }
15892
15893    pub fn set_hull_vertex_face_indices(&mut self, values: &[u8]) {
15894        // SAFETY: the native side copies `values` before returning.
15895        unsafe {
15896            ffi::whiteout_m3_M3PhysicsShape_assign_hullVertexFaceIndices(
15897                self.raw.as_ptr(),
15898                values.as_ptr() as *const _,
15899                values.len(),
15900            )
15901        }
15902    }
15903
15904    pub fn resize_hull_vertex_face_indices(&mut self, count: usize) {
15905        // SAFETY: reallocation is safe here precisely because
15906        // `&mut self` means no slice borrow is outstanding.
15907        unsafe {
15908            ffi::whiteout_m3_M3PhysicsShape_resize_hullVertexFaceIndices(self.raw.as_ptr(), count)
15909        }
15910    }
15911
15912    /// Hull centroid
15913    pub fn hull_center(&self) -> crate::math::Vector3f {
15914        // SAFETY: the getter returns an interior pointer to a
15915        // layout-identical POD; we copy it out immediately.
15916        unsafe {
15917            *(ffi::whiteout_m3_M3PhysicsShape_get_hullCenter(self.raw.as_ptr())
15918                as *const crate::math::Vector3f)
15919        }
15920    }
15921
15922    pub fn set_hull_center(&mut self, value: crate::math::Vector3f) {
15923        // SAFETY: as above, in the other direction.
15924        unsafe {
15925            ffi::whiteout_m3_M3PhysicsShape_set_hullCenter(
15926                self.raw.as_ptr(),
15927                &value as *const crate::math::Vector3f as *const _,
15928            )
15929        }
15930    }
15931
15932    /// Number of face normals
15933    pub fn hull_face_normal_count(&self) -> u32 {
15934        // SAFETY: plain scalar read through a live handle.
15935        unsafe { ffi::whiteout_m3_M3PhysicsShape_get_hullFaceNormalCount(self.raw.as_ptr()) }
15936    }
15937
15938    pub fn set_hull_face_normal_count(&mut self, value: u32) {
15939        // SAFETY: plain scalar write through a live handle.
15940        unsafe { ffi::whiteout_m3_M3PhysicsShape_set_hullFaceNormalCount(self.raw.as_ptr(), value) }
15941    }
15942
15943    /// Number of vertices
15944    pub fn hull_vertex_count(&self) -> u32 {
15945        // SAFETY: plain scalar read through a live handle.
15946        unsafe { ffi::whiteout_m3_M3PhysicsShape_get_hullVertexCount(self.raw.as_ptr()) }
15947    }
15948
15949    pub fn set_hull_vertex_count(&mut self, value: u32) {
15950        // SAFETY: plain scalar write through a live handle.
15951        unsafe { ffi::whiteout_m3_M3PhysicsShape_set_hullVertexCount(self.raw.as_ptr(), value) }
15952    }
15953
15954    /// Number of half-edges
15955    pub fn hull_half_edge_count(&self) -> u32 {
15956        // SAFETY: plain scalar read through a live handle.
15957        unsafe { ffi::whiteout_m3_M3PhysicsShape_get_hullHalfEdgeCount(self.raw.as_ptr()) }
15958    }
15959
15960    pub fn set_hull_half_edge_count(&mut self, value: u32) {
15961        // SAFETY: plain scalar write through a live handle.
15962        unsafe { ffi::whiteout_m3_M3PhysicsShape_set_hullHalfEdgeCount(self.raw.as_ptr(), value) }
15963    }
15964
15965    /// Unknown hull parameter 0
15966    pub fn hull_unknown_0(&self) -> f32 {
15967        // SAFETY: plain scalar read through a live handle.
15968        unsafe { ffi::whiteout_m3_M3PhysicsShape_get_hullUnknown0(self.raw.as_ptr()) }
15969    }
15970
15971    pub fn set_hull_unknown_0(&mut self, value: f32) {
15972        // SAFETY: plain scalar write through a live handle.
15973        unsafe { ffi::whiteout_m3_M3PhysicsShape_set_hullUnknown0(self.raw.as_ptr(), value) }
15974    }
15975
15976    /// Unknown hull parameter 1
15977    pub fn hull_unknown_1(&self) -> f32 {
15978        // SAFETY: plain scalar read through a live handle.
15979        unsafe { ffi::whiteout_m3_M3PhysicsShape_get_hullUnknown1(self.raw.as_ptr()) }
15980    }
15981
15982    pub fn set_hull_unknown_1(&mut self, value: f32) {
15983        // SAFETY: plain scalar write through a live handle.
15984        unsafe { ffi::whiteout_m3_M3PhysicsShape_set_hullUnknown1(self.raw.as_ptr(), value) }
15985    }
15986
15987    /// BVH tree nodes (DMMN)
15988    pub fn mesh_bvh_nodes_len(&self) -> usize {
15989        // SAFETY: scalar read through a live handle.
15990        unsafe { ffi::whiteout_m3_M3PhysicsShape_get_meshBvhNodes_count(self.raw.as_ptr()) }
15991    }
15992
15993    /// Borrows element `index` in place. `None` when out of range.
15994    pub fn mesh_bvh_nodes(
15995        &self,
15996        index: usize,
15997    ) -> Option<crate::support::Ref<'_, PhysicsMeshBvhNode>> {
15998        if index >= self.mesh_bvh_nodes_len() {
15999            return None;
16000        }
16001        // SAFETY: index checked above; the pointer is interior to `self`.
16002        unsafe {
16003            Some(crate::support::Ref::new(PhysicsMeshBvhNode {
16004                raw: core::ptr::NonNull::new_unchecked(
16005                    ffi::whiteout_m3_M3PhysicsShape_get_meshBvhNodes_at(self.raw.as_ptr(), index),
16006                ),
16007            }))
16008        }
16009    }
16010
16011    pub fn mesh_bvh_nodes_mut(
16012        &mut self,
16013        index: usize,
16014    ) -> Option<crate::support::RefMut<'_, PhysicsMeshBvhNode>> {
16015        if index >= self.mesh_bvh_nodes_len() {
16016            return None;
16017        }
16018        // SAFETY: as above; `&mut self` guarantees exclusivity.
16019        unsafe {
16020            Some(crate::support::RefMut::new(PhysicsMeshBvhNode {
16021                raw: core::ptr::NonNull::new_unchecked(
16022                    ffi::whiteout_m3_M3PhysicsShape_get_meshBvhNodes_at(self.raw.as_ptr(), index),
16023                ),
16024            }))
16025        }
16026    }
16027
16028    /// Iterate the elements, borrowing each in turn.
16029    pub fn mesh_bvh_nodes_iter(
16030        &self,
16031    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, PhysicsMeshBvhNode>> {
16032        (0..self.mesh_bvh_nodes_len())
16033            .map(move |i| self.mesh_bvh_nodes(i).expect("index below len"))
16034    }
16035
16036    pub fn resize_mesh_bvh_nodes(&mut self, count: usize) {
16037        // SAFETY: exclusive access, so no borrow is outstanding.
16038        unsafe { ffi::whiteout_m3_M3PhysicsShape_resize_meshBvhNodes(self.raw.as_ptr(), count) }
16039    }
16040
16041    /// Vertex positions, w=0 (VEC4)
16042    /// Zero-copy view of the underlying `std::vector`.
16043    pub fn mesh_vertex_positions(&self) -> &[crate::math::Vector4f] {
16044        // SAFETY: `_data`/`_count` describe one contiguous C++
16045        // allocation, borrowed for as long as `self` is.
16046        unsafe {
16047            let n =
16048                ffi::whiteout_m3_M3PhysicsShape_get_meshVertexPositions_count(self.raw.as_ptr());
16049            let p = ffi::whiteout_m3_M3PhysicsShape_get_meshVertexPositions_data(self.raw.as_ptr())
16050                as *const crate::math::Vector4f;
16051            if p.is_null() || n == 0 {
16052                &[]
16053            } else {
16054                core::slice::from_raw_parts(p, n)
16055            }
16056        }
16057    }
16058
16059    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
16060    pub fn mesh_vertex_positions_mut(&mut self) -> &mut [crate::math::Vector4f] {
16061        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
16062        unsafe {
16063            let n =
16064                ffi::whiteout_m3_M3PhysicsShape_get_meshVertexPositions_count(self.raw.as_ptr());
16065            let p = ffi::whiteout_m3_M3PhysicsShape_get_meshVertexPositions_data(self.raw.as_ptr())
16066                as *const crate::math::Vector4f as *mut crate::math::Vector4f;
16067            if p.is_null() || n == 0 {
16068                &mut []
16069            } else {
16070                core::slice::from_raw_parts_mut(p, n)
16071            }
16072        }
16073    }
16074
16075    pub fn set_mesh_vertex_positions(&mut self, values: &[crate::math::Vector4f]) {
16076        // SAFETY: the native side copies `values` before returning.
16077        unsafe {
16078            ffi::whiteout_m3_M3PhysicsShape_assign_meshVertexPositions(
16079                self.raw.as_ptr(),
16080                values.as_ptr() as *const _,
16081                values.len(),
16082            )
16083        }
16084    }
16085
16086    pub fn resize_mesh_vertex_positions(&mut self, count: usize) {
16087        // SAFETY: reallocation is safe here precisely because
16088        // `&mut self` means no slice borrow is outstanding.
16089        unsafe {
16090            ffi::whiteout_m3_M3PhysicsShape_resize_meshVertexPositions(self.raw.as_ptr(), count)
16091        }
16092    }
16093
16094    /// AABB center in model space (quantization grid origin)
16095    pub fn mesh_bounds_center(&self) -> crate::math::Vector3f {
16096        // SAFETY: the getter returns an interior pointer to a
16097        // layout-identical POD; we copy it out immediately.
16098        unsafe {
16099            *(ffi::whiteout_m3_M3PhysicsShape_get_meshBoundsCenter(self.raw.as_ptr())
16100                as *const crate::math::Vector3f)
16101        }
16102    }
16103
16104    pub fn set_mesh_bounds_center(&mut self, value: crate::math::Vector3f) {
16105        // SAFETY: as above, in the other direction.
16106        unsafe {
16107            ffi::whiteout_m3_M3PhysicsShape_set_meshBoundsCenter(
16108                self.raw.as_ptr(),
16109                &value as *const crate::math::Vector3f as *const _,
16110            )
16111        }
16112    }
16113
16114    /// AABB half-extents (quantization range: tolerance = extent / 32767)
16115    pub fn mesh_bounds_extent(&self) -> crate::math::Vector3f {
16116        // SAFETY: the getter returns an interior pointer to a
16117        // layout-identical POD; we copy it out immediately.
16118        unsafe {
16119            *(ffi::whiteout_m3_M3PhysicsShape_get_meshBoundsExtent(self.raw.as_ptr())
16120                as *const crate::math::Vector3f)
16121        }
16122    }
16123
16124    pub fn set_mesh_bounds_extent(&mut self, value: crate::math::Vector3f) {
16125        // SAFETY: as above, in the other direction.
16126        unsafe {
16127            ffi::whiteout_m3_M3PhysicsShape_set_meshBoundsExtent(
16128                self.raw.as_ptr(),
16129                &value as *const crate::math::Vector3f as *const _,
16130            )
16131        }
16132    }
16133
16134    /// Per-axis quantization step (= extent / 32767)
16135    pub fn mesh_tolerance(&self) -> crate::math::Vector3f {
16136        // SAFETY: the getter returns an interior pointer to a
16137        // layout-identical POD; we copy it out immediately.
16138        unsafe {
16139            *(ffi::whiteout_m3_M3PhysicsShape_get_meshTolerance(self.raw.as_ptr())
16140                as *const crate::math::Vector3f)
16141        }
16142    }
16143
16144    pub fn set_mesh_tolerance(&mut self, value: crate::math::Vector3f) {
16145        // SAFETY: as above, in the other direction.
16146        unsafe {
16147            ffi::whiteout_m3_M3PhysicsShape_set_meshTolerance(
16148                self.raw.as_ptr(),
16149                &value as *const crate::math::Vector3f as *const _,
16150            )
16151        }
16152    }
16153
16154    /// Number of mesh normals
16155    pub fn mesh_normal_count(&self) -> u32 {
16156        // SAFETY: plain scalar read through a live handle.
16157        unsafe { ffi::whiteout_m3_M3PhysicsShape_get_meshNormalCount(self.raw.as_ptr()) }
16158    }
16159
16160    pub fn set_mesh_normal_count(&mut self, value: u32) {
16161        // SAFETY: plain scalar write through a live handle.
16162        unsafe { ffi::whiteout_m3_M3PhysicsShape_set_meshNormalCount(self.raw.as_ptr(), value) }
16163    }
16164
16165    /// Number of mesh vertices
16166    pub fn mesh_vertex_count(&self) -> u32 {
16167        // SAFETY: plain scalar read through a live handle.
16168        unsafe { ffi::whiteout_m3_M3PhysicsShape_get_meshVertexCount(self.raw.as_ptr()) }
16169    }
16170
16171    pub fn set_mesh_vertex_count(&mut self, value: u32) {
16172        // SAFETY: plain scalar write through a live handle.
16173        unsafe { ffi::whiteout_m3_M3PhysicsShape_set_meshVertexCount(self.raw.as_ptr(), value) }
16174    }
16175
16176    /// MT16 face count (0 when MT32)
16177    pub fn mesh_face_index_16_count(&self) -> u32 {
16178        // SAFETY: plain scalar read through a live handle.
16179        unsafe { ffi::whiteout_m3_M3PhysicsShape_get_meshFaceIndex16Count(self.raw.as_ptr()) }
16180    }
16181
16182    pub fn set_mesh_face_index_16_count(&mut self, value: u32) {
16183        // SAFETY: plain scalar write through a live handle.
16184        unsafe {
16185            ffi::whiteout_m3_M3PhysicsShape_set_meshFaceIndex16Count(self.raw.as_ptr(), value)
16186        }
16187    }
16188
16189    /// MT32 face count (0 when MT16)
16190    pub fn mesh_face_index_32_count(&self) -> u32 {
16191        // SAFETY: plain scalar read through a live handle.
16192        unsafe { ffi::whiteout_m3_M3PhysicsShape_get_meshFaceIndex32Count(self.raw.as_ptr()) }
16193    }
16194
16195    pub fn set_mesh_face_index_32_count(&mut self, value: u32) {
16196        // SAFETY: plain scalar write through a live handle.
16197        unsafe {
16198            ffi::whiteout_m3_M3PhysicsShape_set_meshFaceIndex32Count(self.raw.as_ptr(), value)
16199        }
16200    }
16201
16202    /// Unknown mesh parameter
16203    pub fn mesh_unknown_1(&self) -> u32 {
16204        // SAFETY: plain scalar read through a live handle.
16205        unsafe { ffi::whiteout_m3_M3PhysicsShape_get_meshUnknown1(self.raw.as_ptr()) }
16206    }
16207
16208    pub fn set_mesh_unknown_1(&mut self, value: u32) {
16209        // SAFETY: plain scalar write through a live handle.
16210        unsafe { ffi::whiteout_m3_M3PhysicsShape_set_meshUnknown1(self.raw.as_ptr(), value) }
16211    }
16212
16213    /// Reserved (always 0)
16214    pub fn mesh_reserved(&self) -> u32 {
16215        // SAFETY: plain scalar read through a live handle.
16216        unsafe { ffi::whiteout_m3_M3PhysicsShape_get_meshReserved(self.raw.as_ptr()) }
16217    }
16218
16219    pub fn set_mesh_reserved(&mut self, value: u32) {
16220        // SAFETY: plain scalar write through a live handle.
16221        unsafe { ffi::whiteout_m3_M3PhysicsShape_set_meshReserved(self.raw.as_ptr(), value) }
16222    }
16223
16224    /// BVH tree height (root-to-leaf path length, 1–12)
16225    pub fn mesh_tree_depth(&self) -> u32 {
16226        // SAFETY: plain scalar read through a live handle.
16227        unsafe { ffi::whiteout_m3_M3PhysicsShape_get_meshTreeDepth(self.raw.as_ptr()) }
16228    }
16229
16230    pub fn set_mesh_tree_depth(&mut self, value: u32) {
16231        // SAFETY: plain scalar write through a live handle.
16232        unsafe { ffi::whiteout_m3_M3PhysicsShape_set_meshTreeDepth(self.raw.as_ptr(), value) }
16233    }
16234
16235    /// Collision margin (MT16: small float; MT32: 0.0)
16236    pub fn mesh_collision_margin(&self) -> f32 {
16237        // SAFETY: plain scalar read through a live handle.
16238        unsafe { ffi::whiteout_m3_M3PhysicsShape_get_meshCollisionMargin(self.raw.as_ptr()) }
16239    }
16240
16241    pub fn set_mesh_collision_margin(&mut self, value: f32) {
16242        // SAFETY: plain scalar write through a live handle.
16243        unsafe { ffi::whiteout_m3_M3PhysicsShape_set_meshCollisionMargin(self.raw.as_ptr(), value) }
16244    }
16245}
16246
16247impl Default for PhysicsShape {
16248    fn default() -> Self {
16249        Self::new()
16250    }
16251}
16252
16253/// PHRB — Rigid body (v2–v4, 56–104 bytes)
16254///
16255/// Havok rigid body with density, friction, restitution, damping, gravity scale, and collision shape references.
16256pub struct RigidBody {
16257    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3RigidBody>,
16258}
16259
16260impl Drop for RigidBody {
16261    fn drop(&mut self) {
16262        // SAFETY: `raw` came from a native constructor and Drop runs once.
16263        unsafe { ffi::whiteout_m3_M3RigidBody_delete(self.raw.as_ptr()) }
16264    }
16265}
16266
16267impl RigidBody {
16268    /// # Safety
16269    /// `raw` must be a live handle this value takes ownership of.
16270    #[allow(dead_code)] // used by whichever methods return this type
16271    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3RigidBody) -> Option<Self> {
16272        core::ptr::NonNull::new(raw).map(|raw| RigidBody { raw })
16273    }
16274}
16275
16276// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
16277// is deliberately NOT implemented — the C++ types make no documented
16278// guarantee about concurrent use, and claiming one we haven't verified
16279// would be unsound. See `@bind thread_safe` in the plan.
16280unsafe impl Send for RigidBody {}
16281
16282impl core::fmt::Debug for RigidBody {
16283    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
16284        f.debug_struct("RigidBody").finish_non_exhaustive()
16285    }
16286}
16287
16288impl RigidBody {
16289    /// # Panics
16290    /// Panics if the native allocation fails.
16291    pub fn new() -> Self {
16292        // SAFETY: the native constructor returns a live handle; a null here
16293        // means the library is unusable.
16294        unsafe {
16295            let raw = ffi::whiteout_m3_M3RigidBody_new();
16296            Self::from_raw(raw).expect("native RigidBody allocation failed")
16297        }
16298    }
16299
16300    /// Simulation mode (v3+)
16301    pub fn simulation_type(&self) -> u16 {
16302        // SAFETY: plain scalar read through a live handle.
16303        unsafe { ffi::whiteout_m3_M3RigidBody_get_simulationType(self.raw.as_ptr()) }
16304    }
16305
16306    pub fn set_simulation_type(&mut self, value: u16) {
16307        // SAFETY: plain scalar write through a live handle.
16308        unsafe { ffi::whiteout_m3_M3RigidBody_set_simulationType(self.raw.as_ptr(), value) }
16309    }
16310
16311    /// Parent bone index
16312    pub fn parent_bone_index(&self) -> u16 {
16313        // SAFETY: plain scalar read through a live handle.
16314        unsafe { ffi::whiteout_m3_M3RigidBody_get_parentBoneIndex(self.raw.as_ptr()) }
16315    }
16316
16317    pub fn set_parent_bone_index(&mut self, value: u16) {
16318        // SAFETY: plain scalar write through a live handle.
16319        unsafe { ffi::whiteout_m3_M3RigidBody_set_parentBoneIndex(self.raw.as_ptr(), value) }
16320    }
16321
16322    /// Engine-specific body type (v3+)
16323    pub fn physics_type(&self) -> u32 {
16324        // SAFETY: plain scalar read through a live handle.
16325        unsafe { ffi::whiteout_m3_M3RigidBody_get_physicsType(self.raw.as_ptr()) }
16326    }
16327
16328    pub fn set_physics_type(&mut self, value: u32) {
16329        // SAFETY: plain scalar write through a live handle.
16330        unsafe { ffi::whiteout_m3_M3RigidBody_set_physicsType(self.raw.as_ptr(), value) }
16331    }
16332
16333    /// Body density
16334    pub fn density(&self) -> f32 {
16335        // SAFETY: plain scalar read through a live handle.
16336        unsafe { ffi::whiteout_m3_M3RigidBody_get_density(self.raw.as_ptr()) }
16337    }
16338
16339    pub fn set_density(&mut self, value: f32) {
16340        // SAFETY: plain scalar write through a live handle.
16341        unsafe { ffi::whiteout_m3_M3RigidBody_set_density(self.raw.as_ptr(), value) }
16342    }
16343
16344    /// Surface friction
16345    pub fn friction(&self) -> f32 {
16346        // SAFETY: plain scalar read through a live handle.
16347        unsafe { ffi::whiteout_m3_M3RigidBody_get_friction(self.raw.as_ptr()) }
16348    }
16349
16350    pub fn set_friction(&mut self, value: f32) {
16351        // SAFETY: plain scalar write through a live handle.
16352        unsafe { ffi::whiteout_m3_M3RigidBody_set_friction(self.raw.as_ptr(), value) }
16353    }
16354
16355    /// Elasticity / bounciness
16356    pub fn restitution(&self) -> f32 {
16357        // SAFETY: plain scalar read through a live handle.
16358        unsafe { ffi::whiteout_m3_M3RigidBody_get_restitution(self.raw.as_ptr()) }
16359    }
16360
16361    pub fn set_restitution(&mut self, value: f32) {
16362        // SAFETY: plain scalar write through a live handle.
16363        unsafe { ffi::whiteout_m3_M3RigidBody_set_restitution(self.raw.as_ptr(), value) }
16364    }
16365
16366    /// Linear velocity damping
16367    pub fn linear_damping(&self) -> f32 {
16368        // SAFETY: plain scalar read through a live handle.
16369        unsafe { ffi::whiteout_m3_M3RigidBody_get_linearDamping(self.raw.as_ptr()) }
16370    }
16371
16372    pub fn set_linear_damping(&mut self, value: f32) {
16373        // SAFETY: plain scalar write through a live handle.
16374        unsafe { ffi::whiteout_m3_M3RigidBody_set_linearDamping(self.raw.as_ptr(), value) }
16375    }
16376
16377    /// Angular velocity damping
16378    pub fn angular_damping(&self) -> f32 {
16379        // SAFETY: plain scalar read through a live handle.
16380        unsafe { ffi::whiteout_m3_M3RigidBody_get_angularDamping(self.raw.as_ptr()) }
16381    }
16382
16383    pub fn set_angular_damping(&mut self, value: f32) {
16384        // SAFETY: plain scalar write through a live handle.
16385        unsafe { ffi::whiteout_m3_M3RigidBody_set_angularDamping(self.raw.as_ptr(), value) }
16386    }
16387
16388    /// Gravity influence scale
16389    pub fn gravity_scale(&self) -> f32 {
16390        // SAFETY: plain scalar read through a live handle.
16391        unsafe { ffi::whiteout_m3_M3RigidBody_get_gravityScale(self.raw.as_ptr()) }
16392    }
16393
16394    pub fn set_gravity_scale(&mut self, value: f32) {
16395        // SAFETY: plain scalar write through a live handle.
16396        unsafe { ffi::whiteout_m3_M3RigidBody_set_gravityScale(self.raw.as_ptr(), value) }
16397    }
16398
16399    /// Animated dynamic state (v4+)
16400    /// Borrows the field in place — no copy, no allocation.
16401    pub fn dynamic_state(&self) -> crate::support::Ref<'_, AnimRefU32> {
16402        // SAFETY: an interior pointer into `self`, valid for this
16403        // borrow and never freed by the `Ref`.
16404        unsafe {
16405            crate::support::Ref::new(AnimRefU32 {
16406                raw: core::ptr::NonNull::new_unchecked(
16407                    ffi::whiteout_m3_M3RigidBody_get_dynamicState(self.raw.as_ptr()),
16408                ),
16409            })
16410        }
16411    }
16412
16413    pub fn dynamic_state_mut(&mut self) -> crate::support::RefMut<'_, AnimRefU32> {
16414        // SAFETY: as above; `&mut self` guarantees exclusivity.
16415        unsafe {
16416            crate::support::RefMut::new(AnimRefU32 {
16417                raw: core::ptr::NonNull::new_unchecked(
16418                    ffi::whiteout_m3_M3RigidBody_get_dynamicState(self.raw.as_ptr()),
16419                ),
16420            })
16421        }
16422    }
16423
16424    /// Dynamic blend-out duration (v4+)
16425    pub fn dynamic_blend_out(&self) -> f32 {
16426        // SAFETY: plain scalar read through a live handle.
16427        unsafe { ffi::whiteout_m3_M3RigidBody_get_dynamicBlendOut(self.raw.as_ptr()) }
16428    }
16429
16430    pub fn set_dynamic_blend_out(&mut self, value: f32) {
16431        // SAFETY: plain scalar write through a live handle.
16432        unsafe { ffi::whiteout_m3_M3RigidBody_set_dynamicBlendOut(self.raw.as_ptr(), value) }
16433    }
16434
16435    /// Collision shapes (PHSH)
16436    pub fn rigid_body_shape_len(&self) -> usize {
16437        // SAFETY: scalar read through a live handle.
16438        unsafe { ffi::whiteout_m3_M3RigidBody_get_rigidBodyShape_count(self.raw.as_ptr()) }
16439    }
16440
16441    /// Borrows element `index` in place. `None` when out of range.
16442    pub fn rigid_body_shape(&self, index: usize) -> Option<crate::support::Ref<'_, PhysicsShape>> {
16443        if index >= self.rigid_body_shape_len() {
16444            return None;
16445        }
16446        // SAFETY: index checked above; the pointer is interior to `self`.
16447        unsafe {
16448            Some(crate::support::Ref::new(PhysicsShape {
16449                raw: core::ptr::NonNull::new_unchecked(
16450                    ffi::whiteout_m3_M3RigidBody_get_rigidBodyShape_at(self.raw.as_ptr(), index),
16451                ),
16452            }))
16453        }
16454    }
16455
16456    pub fn rigid_body_shape_mut(
16457        &mut self,
16458        index: usize,
16459    ) -> Option<crate::support::RefMut<'_, PhysicsShape>> {
16460        if index >= self.rigid_body_shape_len() {
16461            return None;
16462        }
16463        // SAFETY: as above; `&mut self` guarantees exclusivity.
16464        unsafe {
16465            Some(crate::support::RefMut::new(PhysicsShape {
16466                raw: core::ptr::NonNull::new_unchecked(
16467                    ffi::whiteout_m3_M3RigidBody_get_rigidBodyShape_at(self.raw.as_ptr(), index),
16468                ),
16469            }))
16470        }
16471    }
16472
16473    /// Iterate the elements, borrowing each in turn.
16474    pub fn rigid_body_shape_iter(
16475        &self,
16476    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, PhysicsShape>> {
16477        (0..self.rigid_body_shape_len())
16478            .map(move |i| self.rigid_body_shape(i).expect("index below len"))
16479    }
16480
16481    pub fn resize_rigid_body_shape(&mut self, count: usize) {
16482        // SAFETY: exclusive access, so no borrow is outstanding.
16483        unsafe { ffi::whiteout_m3_M3RigidBody_resize_rigidBodyShape(self.raw.as_ptr(), count) }
16484    }
16485
16486    /// Rigid body flags
16487    pub fn flags(&self) -> RigidBodyFlag {
16488        // SAFETY: scalar read; a flag set accepts any bits.
16489        RigidBodyFlag(unsafe { ffi::whiteout_m3_M3RigidBody_get_flags(self.raw.as_ptr()) })
16490    }
16491
16492    pub fn set_flags(&mut self, value: RigidBodyFlag) {
16493        // SAFETY: scalar write through a live handle.
16494        unsafe { ffi::whiteout_m3_M3RigidBody_set_flags(self.raw.as_ptr(), value.0) }
16495    }
16496
16497    /// Local force channel bitmask
16498    pub fn local_forces(&self) -> u16 {
16499        // SAFETY: plain scalar read through a live handle.
16500        unsafe { ffi::whiteout_m3_M3RigidBody_get_localForces(self.raw.as_ptr()) }
16501    }
16502
16503    pub fn set_local_forces(&mut self, value: u16) {
16504        // SAFETY: plain scalar write through a live handle.
16505        unsafe { ffi::whiteout_m3_M3RigidBody_set_localForces(self.raw.as_ptr(), value) }
16506    }
16507
16508    /// World force channel bitmask
16509    pub fn world_forces(&self) -> u16 {
16510        // SAFETY: plain scalar read through a live handle.
16511        unsafe { ffi::whiteout_m3_M3RigidBody_get_worldForces(self.raw.as_ptr()) }
16512    }
16513
16514    pub fn set_world_forces(&mut self, value: u16) {
16515        // SAFETY: plain scalar write through a live handle.
16516        unsafe { ffi::whiteout_m3_M3RigidBody_set_worldForces(self.raw.as_ptr(), value) }
16517    }
16518
16519    /// Simulation priority
16520    pub fn priority(&self) -> u32 {
16521        // SAFETY: plain scalar read through a live handle.
16522        unsafe { ffi::whiteout_m3_M3RigidBody_get_priority(self.raw.as_ptr()) }
16523    }
16524
16525    pub fn set_priority(&mut self, value: u32) {
16526        // SAFETY: plain scalar write through a live handle.
16527        unsafe { ffi::whiteout_m3_M3RigidBody_set_priority(self.raw.as_ptr(), value) }
16528    }
16529}
16530
16531impl Default for RigidBody {
16532    fn default() -> Self {
16533        Self::new()
16534    }
16535}
16536
16537/// PHYJ — Physics joint (v0, 180 bytes)
16538///
16539/// Connects two rigid bodies with limit, friction, and break-threshold parameters.
16540pub struct PhysicsJoint {
16541    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3PhysicsJoint>,
16542}
16543
16544impl Drop for PhysicsJoint {
16545    fn drop(&mut self) {
16546        // SAFETY: `raw` came from a native constructor and Drop runs once.
16547        unsafe { ffi::whiteout_m3_M3PhysicsJoint_delete(self.raw.as_ptr()) }
16548    }
16549}
16550
16551impl PhysicsJoint {
16552    /// # Safety
16553    /// `raw` must be a live handle this value takes ownership of.
16554    #[allow(dead_code)] // used by whichever methods return this type
16555    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3PhysicsJoint) -> Option<Self> {
16556        core::ptr::NonNull::new(raw).map(|raw| PhysicsJoint { raw })
16557    }
16558}
16559
16560// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
16561// is deliberately NOT implemented — the C++ types make no documented
16562// guarantee about concurrent use, and claiming one we haven't verified
16563// would be unsound. See `@bind thread_safe` in the plan.
16564unsafe impl Send for PhysicsJoint {}
16565
16566impl core::fmt::Debug for PhysicsJoint {
16567    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
16568        f.debug_struct("PhysicsJoint").finish_non_exhaustive()
16569    }
16570}
16571
16572impl PhysicsJoint {
16573    /// # Panics
16574    /// Panics if the native allocation fails.
16575    pub fn new() -> Self {
16576        // SAFETY: the native constructor returns a live handle; a null here
16577        // means the library is unusable.
16578        unsafe {
16579            let raw = ffi::whiteout_m3_M3PhysicsJoint_new();
16580            Self::from_raw(raw).expect("native PhysicsJoint allocation failed")
16581        }
16582    }
16583
16584    /// Joint type
16585    pub fn joint_type(&self) -> u32 {
16586        // SAFETY: plain scalar read through a live handle.
16587        unsafe { ffi::whiteout_m3_M3PhysicsJoint_get_jointType(self.raw.as_ptr()) }
16588    }
16589
16590    pub fn set_joint_type(&mut self, value: u32) {
16591        // SAFETY: plain scalar write through a live handle.
16592        unsafe { ffi::whiteout_m3_M3PhysicsJoint_set_jointType(self.raw.as_ptr(), value) }
16593    }
16594
16595    /// First bone index
16596    pub fn bone_index_1(&self) -> u32 {
16597        // SAFETY: plain scalar read through a live handle.
16598        unsafe { ffi::whiteout_m3_M3PhysicsJoint_get_boneIndex1(self.raw.as_ptr()) }
16599    }
16600
16601    pub fn set_bone_index_1(&mut self, value: u32) {
16602        // SAFETY: plain scalar write through a live handle.
16603        unsafe { ffi::whiteout_m3_M3PhysicsJoint_set_boneIndex1(self.raw.as_ptr(), value) }
16604    }
16605
16606    /// Second bone index
16607    pub fn bone_index_2(&self) -> u32 {
16608        // SAFETY: plain scalar read through a live handle.
16609        unsafe { ffi::whiteout_m3_M3PhysicsJoint_get_boneIndex2(self.raw.as_ptr()) }
16610    }
16611
16612    pub fn set_bone_index_2(&mut self, value: u32) {
16613        // SAFETY: plain scalar write through a live handle.
16614        unsafe { ffi::whiteout_m3_M3PhysicsJoint_set_boneIndex2(self.raw.as_ptr(), value) }
16615    }
16616
16617    /// Enable angular limits
16618    pub fn enable_limits(&self) -> u32 {
16619        // SAFETY: plain scalar read through a live handle.
16620        unsafe { ffi::whiteout_m3_M3PhysicsJoint_get_enableLimits(self.raw.as_ptr()) }
16621    }
16622
16623    pub fn set_enable_limits(&mut self, value: u32) {
16624        // SAFETY: plain scalar write through a live handle.
16625        unsafe { ffi::whiteout_m3_M3PhysicsJoint_set_enableLimits(self.raw.as_ptr(), value) }
16626    }
16627
16628    /// Minimum limit angle
16629    pub fn limit_min(&self) -> f32 {
16630        // SAFETY: plain scalar read through a live handle.
16631        unsafe { ffi::whiteout_m3_M3PhysicsJoint_get_limitMin(self.raw.as_ptr()) }
16632    }
16633
16634    pub fn set_limit_min(&mut self, value: f32) {
16635        // SAFETY: plain scalar write through a live handle.
16636        unsafe { ffi::whiteout_m3_M3PhysicsJoint_set_limitMin(self.raw.as_ptr(), value) }
16637    }
16638
16639    /// Maximum limit angle
16640    pub fn limit_max(&self) -> f32 {
16641        // SAFETY: plain scalar read through a live handle.
16642        unsafe { ffi::whiteout_m3_M3PhysicsJoint_get_limitMax(self.raw.as_ptr()) }
16643    }
16644
16645    pub fn set_limit_max(&mut self, value: f32) {
16646        // SAFETY: plain scalar write through a live handle.
16647        unsafe { ffi::whiteout_m3_M3PhysicsJoint_set_limitMax(self.raw.as_ptr(), value) }
16648    }
16649
16650    /// Cone constraint angle
16651    pub fn cone_angle(&self) -> f32 {
16652        // SAFETY: plain scalar read through a live handle.
16653        unsafe { ffi::whiteout_m3_M3PhysicsJoint_get_coneAngle(self.raw.as_ptr()) }
16654    }
16655
16656    pub fn set_cone_angle(&mut self, value: f32) {
16657        // SAFETY: plain scalar write through a live handle.
16658        unsafe { ffi::whiteout_m3_M3PhysicsJoint_set_coneAngle(self.raw.as_ptr(), value) }
16659    }
16660
16661    /// Enable joint friction
16662    pub fn enable_friction(&self) -> u32 {
16663        // SAFETY: plain scalar read through a live handle.
16664        unsafe { ffi::whiteout_m3_M3PhysicsJoint_get_enableFriction(self.raw.as_ptr()) }
16665    }
16666
16667    pub fn set_enable_friction(&mut self, value: u32) {
16668        // SAFETY: plain scalar write through a live handle.
16669        unsafe { ffi::whiteout_m3_M3PhysicsJoint_set_enableFriction(self.raw.as_ptr(), value) }
16670    }
16671
16672    /// Friction coefficient
16673    pub fn friction(&self) -> f32 {
16674        // SAFETY: plain scalar read through a live handle.
16675        unsafe { ffi::whiteout_m3_M3PhysicsJoint_get_friction(self.raw.as_ptr()) }
16676    }
16677
16678    pub fn set_friction(&mut self, value: f32) {
16679        // SAFETY: plain scalar write through a live handle.
16680        unsafe { ffi::whiteout_m3_M3PhysicsJoint_set_friction(self.raw.as_ptr(), value) }
16681    }
16682
16683    /// Damping ratio
16684    pub fn damping_ratio(&self) -> f32 {
16685        // SAFETY: plain scalar read through a live handle.
16686        unsafe { ffi::whiteout_m3_M3PhysicsJoint_get_dampingRatio(self.raw.as_ptr()) }
16687    }
16688
16689    pub fn set_damping_ratio(&mut self, value: f32) {
16690        // SAFETY: plain scalar write through a live handle.
16691        unsafe { ffi::whiteout_m3_M3PhysicsJoint_set_dampingRatio(self.raw.as_ptr(), value) }
16692    }
16693
16694    /// Angular frequency
16695    pub fn angular_frequency(&self) -> f32 {
16696        // SAFETY: plain scalar read through a live handle.
16697        unsafe { ffi::whiteout_m3_M3PhysicsJoint_get_angularFrequency(self.raw.as_ptr()) }
16698    }
16699
16700    pub fn set_angular_frequency(&mut self, value: f32) {
16701        // SAFETY: plain scalar write through a live handle.
16702        unsafe { ffi::whiteout_m3_M3PhysicsJoint_set_angularFrequency(self.raw.as_ptr(), value) }
16703    }
16704
16705    /// Force threshold to break joint
16706    pub fn break_threshold(&self) -> f32 {
16707        // SAFETY: plain scalar read through a live handle.
16708        unsafe { ffi::whiteout_m3_M3PhysicsJoint_get_breakThreshold(self.raw.as_ptr()) }
16709    }
16710
16711    pub fn set_break_threshold(&mut self, value: f32) {
16712        // SAFETY: plain scalar write through a live handle.
16713        unsafe { ffi::whiteout_m3_M3PhysicsJoint_set_breakThreshold(self.raw.as_ptr(), value) }
16714    }
16715
16716    /// Enable shape constraint
16717    pub fn enable_shape(&self) -> u8 {
16718        // SAFETY: plain scalar read through a live handle.
16719        unsafe { ffi::whiteout_m3_M3PhysicsJoint_get_enableShape(self.raw.as_ptr()) }
16720    }
16721
16722    pub fn set_enable_shape(&mut self, value: u8) {
16723        // SAFETY: plain scalar write through a live handle.
16724        unsafe { ffi::whiteout_m3_M3PhysicsJoint_set_enableShape(self.raw.as_ptr(), value) }
16725    }
16726}
16727
16728impl Default for PhysicsJoint {
16729    fn default() -> Self {
16730        Self::new()
16731    }
16732}
16733
16734/// PHCT — Physics constraint (v0, 24 bytes)
16735///
16736/// Constrains two rigid bodies with break-force threshold.
16737pub struct PhysicsConstraint {
16738    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3PhysicsConstraint>,
16739}
16740
16741impl Drop for PhysicsConstraint {
16742    fn drop(&mut self) {
16743        // SAFETY: `raw` came from a native constructor and Drop runs once.
16744        unsafe { ffi::whiteout_m3_M3PhysicsConstraint_delete(self.raw.as_ptr()) }
16745    }
16746}
16747
16748impl PhysicsConstraint {
16749    /// # Safety
16750    /// `raw` must be a live handle this value takes ownership of.
16751    #[allow(dead_code)] // used by whichever methods return this type
16752    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3PhysicsConstraint) -> Option<Self> {
16753        core::ptr::NonNull::new(raw).map(|raw| PhysicsConstraint { raw })
16754    }
16755}
16756
16757// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
16758// is deliberately NOT implemented — the C++ types make no documented
16759// guarantee about concurrent use, and claiming one we haven't verified
16760// would be unsound. See `@bind thread_safe` in the plan.
16761unsafe impl Send for PhysicsConstraint {}
16762
16763impl core::fmt::Debug for PhysicsConstraint {
16764    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
16765        f.debug_struct("PhysicsConstraint").finish_non_exhaustive()
16766    }
16767}
16768
16769impl PhysicsConstraint {
16770    /// # Panics
16771    /// Panics if the native allocation fails.
16772    pub fn new() -> Self {
16773        // SAFETY: the native constructor returns a live handle; a null here
16774        // means the library is unusable.
16775        unsafe {
16776            let raw = ffi::whiteout_m3_M3PhysicsConstraint_new();
16777            Self::from_raw(raw).expect("native PhysicsConstraint allocation failed")
16778        }
16779    }
16780
16781    /// Dependent bone indices (U16_)
16782    /// Zero-copy view of the underlying `std::vector`.
16783    pub fn dependents(&self) -> &[u16] {
16784        // SAFETY: `_data`/`_count` describe one contiguous C++
16785        // allocation, borrowed for as long as `self` is.
16786        unsafe {
16787            let n = ffi::whiteout_m3_M3PhysicsConstraint_get_dependents_count(self.raw.as_ptr());
16788            let p = ffi::whiteout_m3_M3PhysicsConstraint_get_dependents_data(self.raw.as_ptr());
16789            if p.is_null() || n == 0 {
16790                &[]
16791            } else {
16792                core::slice::from_raw_parts(p, n)
16793            }
16794        }
16795    }
16796
16797    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
16798    pub fn dependents_mut(&mut self) -> &mut [u16] {
16799        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
16800        unsafe {
16801            let n = ffi::whiteout_m3_M3PhysicsConstraint_get_dependents_count(self.raw.as_ptr());
16802            let p = ffi::whiteout_m3_M3PhysicsConstraint_get_dependents_data(self.raw.as_ptr())
16803                as *mut u16;
16804            if p.is_null() || n == 0 {
16805                &mut []
16806            } else {
16807                core::slice::from_raw_parts_mut(p, n)
16808            }
16809        }
16810    }
16811
16812    pub fn set_dependents(&mut self, values: &[u16]) {
16813        // SAFETY: the native side copies `values` before returning.
16814        unsafe {
16815            ffi::whiteout_m3_M3PhysicsConstraint_assign_dependents(
16816                self.raw.as_ptr(),
16817                values.as_ptr() as *const _,
16818                values.len(),
16819            )
16820        }
16821    }
16822
16823    pub fn resize_dependents(&mut self, count: usize) {
16824        // SAFETY: reallocation is safe here precisely because
16825        // `&mut self` means no slice borrow is outstanding.
16826        unsafe { ffi::whiteout_m3_M3PhysicsConstraint_resize_dependents(self.raw.as_ptr(), count) }
16827    }
16828
16829    /// First rigid body index
16830    pub fn rigid_body_1(&self) -> u16 {
16831        // SAFETY: plain scalar read through a live handle.
16832        unsafe { ffi::whiteout_m3_M3PhysicsConstraint_get_rigidBody1(self.raw.as_ptr()) }
16833    }
16834
16835    pub fn set_rigid_body_1(&mut self, value: u16) {
16836        // SAFETY: plain scalar write through a live handle.
16837        unsafe { ffi::whiteout_m3_M3PhysicsConstraint_set_rigidBody1(self.raw.as_ptr(), value) }
16838    }
16839
16840    /// Second rigid body index
16841    pub fn rigid_body_2(&self) -> u16 {
16842        // SAFETY: plain scalar read through a live handle.
16843        unsafe { ffi::whiteout_m3_M3PhysicsConstraint_get_rigidBody2(self.raw.as_ptr()) }
16844    }
16845
16846    pub fn set_rigid_body_2(&mut self, value: u16) {
16847        // SAFETY: plain scalar write through a live handle.
16848        unsafe { ffi::whiteout_m3_M3PhysicsConstraint_set_rigidBody2(self.raw.as_ptr(), value) }
16849    }
16850
16851    /// Force required to break constraint
16852    pub fn break_force(&self) -> f32 {
16853        // SAFETY: plain scalar read through a live handle.
16854        unsafe { ffi::whiteout_m3_M3PhysicsConstraint_get_breakForce(self.raw.as_ptr()) }
16855    }
16856
16857    pub fn set_break_force(&mut self, value: f32) {
16858        // SAFETY: plain scalar write through a live handle.
16859        unsafe { ffi::whiteout_m3_M3PhysicsConstraint_set_breakForce(self.raw.as_ptr(), value) }
16860    }
16861}
16862
16863impl Default for PhysicsConstraint {
16864    fn default() -> Self {
16865        Self::new()
16866    }
16867}
16868
16869/// PHCC — Cloth collider (v0, 76 bytes)
16870///
16871/// Capsule-shaped collider used by cloth simulation.
16872pub struct ClothCollider {
16873    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3ClothCollider>,
16874}
16875
16876impl Drop for ClothCollider {
16877    fn drop(&mut self) {
16878        // SAFETY: `raw` came from a native constructor and Drop runs once.
16879        unsafe { ffi::whiteout_m3_M3ClothCollider_delete(self.raw.as_ptr()) }
16880    }
16881}
16882
16883impl ClothCollider {
16884    /// # Safety
16885    /// `raw` must be a live handle this value takes ownership of.
16886    #[allow(dead_code)] // used by whichever methods return this type
16887    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3ClothCollider) -> Option<Self> {
16888        core::ptr::NonNull::new(raw).map(|raw| ClothCollider { raw })
16889    }
16890}
16891
16892// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
16893// is deliberately NOT implemented — the C++ types make no documented
16894// guarantee about concurrent use, and claiming one we haven't verified
16895// would be unsound. See `@bind thread_safe` in the plan.
16896unsafe impl Send for ClothCollider {}
16897
16898impl core::fmt::Debug for ClothCollider {
16899    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
16900        f.debug_struct("ClothCollider").finish_non_exhaustive()
16901    }
16902}
16903
16904impl ClothCollider {
16905    /// # Panics
16906    /// Panics if the native allocation fails.
16907    pub fn new() -> Self {
16908        // SAFETY: the native constructor returns a live handle; a null here
16909        // means the library is unusable.
16910        unsafe {
16911            let raw = ffi::whiteout_m3_M3ClothCollider_new();
16912            Self::from_raw(raw).expect("native ClothCollider allocation failed")
16913        }
16914    }
16915
16916    /// Capsule radius
16917    pub fn radius(&self) -> f32 {
16918        // SAFETY: plain scalar read through a live handle.
16919        unsafe { ffi::whiteout_m3_M3ClothCollider_get_radius(self.raw.as_ptr()) }
16920    }
16921
16922    pub fn set_radius(&mut self, value: f32) {
16923        // SAFETY: plain scalar write through a live handle.
16924        unsafe { ffi::whiteout_m3_M3ClothCollider_set_radius(self.raw.as_ptr(), value) }
16925    }
16926
16927    /// Capsule height
16928    pub fn height(&self) -> f32 {
16929        // SAFETY: plain scalar read through a live handle.
16930        unsafe { ffi::whiteout_m3_M3ClothCollider_get_height(self.raw.as_ptr()) }
16931    }
16932
16933    pub fn set_height(&mut self, value: f32) {
16934        // SAFETY: plain scalar write through a live handle.
16935        unsafe { ffi::whiteout_m3_M3ClothCollider_set_height(self.raw.as_ptr(), value) }
16936    }
16937
16938    /// Alignment padding
16939    pub fn padding(&self) -> u32 {
16940        // SAFETY: plain scalar read through a live handle.
16941        unsafe { ffi::whiteout_m3_M3ClothCollider_get_padding(self.raw.as_ptr()) }
16942    }
16943
16944    pub fn set_padding(&mut self, value: u32) {
16945        // SAFETY: plain scalar write through a live handle.
16946        unsafe { ffi::whiteout_m3_M3ClothCollider_set_padding(self.raw.as_ptr(), value) }
16947    }
16948}
16949
16950impl Default for ClothCollider {
16951    fn default() -> Self {
16952        Self::new()
16953    }
16954}
16955
16956/// PHAC — Cloth proxy (v0, 32 bytes)
16957///
16958/// Maps cloth vertices to proxy geometry for collision.
16959pub struct ClothProxy {
16960    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3ClothProxy>,
16961}
16962
16963impl Drop for ClothProxy {
16964    fn drop(&mut self) {
16965        // SAFETY: `raw` came from a native constructor and Drop runs once.
16966        unsafe { ffi::whiteout_m3_M3ClothProxy_delete(self.raw.as_ptr()) }
16967    }
16968}
16969
16970impl ClothProxy {
16971    /// # Safety
16972    /// `raw` must be a live handle this value takes ownership of.
16973    #[allow(dead_code)] // used by whichever methods return this type
16974    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3ClothProxy) -> Option<Self> {
16975        core::ptr::NonNull::new(raw).map(|raw| ClothProxy { raw })
16976    }
16977}
16978
16979// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
16980// is deliberately NOT implemented — the C++ types make no documented
16981// guarantee about concurrent use, and claiming one we haven't verified
16982// would be unsound. See `@bind thread_safe` in the plan.
16983unsafe impl Send for ClothProxy {}
16984
16985impl core::fmt::Debug for ClothProxy {
16986    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
16987        f.debug_struct("ClothProxy").finish_non_exhaustive()
16988    }
16989}
16990
16991impl ClothProxy {
16992    /// # Panics
16993    /// Panics if the native allocation fails.
16994    pub fn new() -> Self {
16995        // SAFETY: the native constructor returns a live handle; a null here
16996        // means the library is unusable.
16997        unsafe {
16998            let raw = ffi::whiteout_m3_M3ClothProxy_new();
16999            Self::from_raw(raw).expect("native ClothProxy allocation failed")
17000        }
17001    }
17002
17003    /// Proxy mesh index
17004    pub fn proxy_index(&self) -> u32 {
17005        // SAFETY: plain scalar read through a live handle.
17006        unsafe { ffi::whiteout_m3_M3ClothProxy_get_proxyIndex(self.raw.as_ptr()) }
17007    }
17008
17009    pub fn set_proxy_index(&mut self, value: u32) {
17010        // SAFETY: plain scalar write through a live handle.
17011        unsafe { ffi::whiteout_m3_M3ClothProxy_set_proxyIndex(self.raw.as_ptr(), value) }
17012    }
17013
17014    /// Cloth mesh index
17015    pub fn cloth_index(&self) -> u32 {
17016        // SAFETY: plain scalar read through a live handle.
17017        unsafe { ffi::whiteout_m3_M3ClothProxy_get_clothIndex(self.raw.as_ptr()) }
17018    }
17019
17020    pub fn set_cloth_index(&mut self, value: u32) {
17021        // SAFETY: plain scalar write through a live handle.
17022        unsafe { ffi::whiteout_m3_M3ClothProxy_set_clothIndex(self.raw.as_ptr(), value) }
17023    }
17024
17025    /// Proxy vertex data (U64_)
17026    /// Zero-copy view of the underlying `std::vector`.
17027    pub fn proxy_vertices(&self) -> &[u64] {
17028        // SAFETY: `_data`/`_count` describe one contiguous C++
17029        // allocation, borrowed for as long as `self` is.
17030        unsafe {
17031            let n = ffi::whiteout_m3_M3ClothProxy_get_proxyVertices_count(self.raw.as_ptr());
17032            let p = ffi::whiteout_m3_M3ClothProxy_get_proxyVertices_data(self.raw.as_ptr());
17033            if p.is_null() || n == 0 {
17034                &[]
17035            } else {
17036                core::slice::from_raw_parts(p, n)
17037            }
17038        }
17039    }
17040
17041    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
17042    pub fn proxy_vertices_mut(&mut self) -> &mut [u64] {
17043        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
17044        unsafe {
17045            let n = ffi::whiteout_m3_M3ClothProxy_get_proxyVertices_count(self.raw.as_ptr());
17046            let p =
17047                ffi::whiteout_m3_M3ClothProxy_get_proxyVertices_data(self.raw.as_ptr()) as *mut u64;
17048            if p.is_null() || n == 0 {
17049                &mut []
17050            } else {
17051                core::slice::from_raw_parts_mut(p, n)
17052            }
17053        }
17054    }
17055
17056    pub fn set_proxy_vertices(&mut self, values: &[u64]) {
17057        // SAFETY: the native side copies `values` before returning.
17058        unsafe {
17059            ffi::whiteout_m3_M3ClothProxy_assign_proxyVertices(
17060                self.raw.as_ptr(),
17061                values.as_ptr() as *const _,
17062                values.len(),
17063            )
17064        }
17065    }
17066
17067    pub fn resize_proxy_vertices(&mut self, count: usize) {
17068        // SAFETY: reallocation is safe here precisely because
17069        // `&mut self` means no slice borrow is outstanding.
17070        unsafe { ffi::whiteout_m3_M3ClothProxy_resize_proxyVertices(self.raw.as_ptr(), count) }
17071    }
17072
17073    /// Proxy blend weights (U32_)
17074    /// Zero-copy view of the underlying `std::vector`.
17075    pub fn proxy_weights(&self) -> &[u32] {
17076        // SAFETY: `_data`/`_count` describe one contiguous C++
17077        // allocation, borrowed for as long as `self` is.
17078        unsafe {
17079            let n = ffi::whiteout_m3_M3ClothProxy_get_proxyWeights_count(self.raw.as_ptr());
17080            let p = ffi::whiteout_m3_M3ClothProxy_get_proxyWeights_data(self.raw.as_ptr());
17081            if p.is_null() || n == 0 {
17082                &[]
17083            } else {
17084                core::slice::from_raw_parts(p, n)
17085            }
17086        }
17087    }
17088
17089    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
17090    pub fn proxy_weights_mut(&mut self) -> &mut [u32] {
17091        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
17092        unsafe {
17093            let n = ffi::whiteout_m3_M3ClothProxy_get_proxyWeights_count(self.raw.as_ptr());
17094            let p =
17095                ffi::whiteout_m3_M3ClothProxy_get_proxyWeights_data(self.raw.as_ptr()) as *mut u32;
17096            if p.is_null() || n == 0 {
17097                &mut []
17098            } else {
17099                core::slice::from_raw_parts_mut(p, n)
17100            }
17101        }
17102    }
17103
17104    pub fn set_proxy_weights(&mut self, values: &[u32]) {
17105        // SAFETY: the native side copies `values` before returning.
17106        unsafe {
17107            ffi::whiteout_m3_M3ClothProxy_assign_proxyWeights(
17108                self.raw.as_ptr(),
17109                values.as_ptr() as *const _,
17110                values.len(),
17111            )
17112        }
17113    }
17114
17115    pub fn resize_proxy_weights(&mut self, count: usize) {
17116        // SAFETY: reallocation is safe here precisely because
17117        // `&mut self` means no slice borrow is outstanding.
17118        unsafe { ffi::whiteout_m3_M3ClothProxy_resize_proxyWeights(self.raw.as_ptr(), count) }
17119    }
17120}
17121
17122impl Default for ClothProxy {
17123    fn default() -> Self {
17124        Self::new()
17125    }
17126}
17127
17128/// PHCL — Cloth physics (v0–v4, 192 bytes)
17129///
17130/// Full cloth simulation configuration: skin bone binding, stiffness parameters, damping, wind/explosion/gravity scales, colliders, and proxies. Added in MODL v28.
17131pub struct ClothPhysics {
17132    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3ClothPhysics>,
17133}
17134
17135impl Drop for ClothPhysics {
17136    fn drop(&mut self) {
17137        // SAFETY: `raw` came from a native constructor and Drop runs once.
17138        unsafe { ffi::whiteout_m3_M3ClothPhysics_delete(self.raw.as_ptr()) }
17139    }
17140}
17141
17142impl ClothPhysics {
17143    /// # Safety
17144    /// `raw` must be a live handle this value takes ownership of.
17145    #[allow(dead_code)] // used by whichever methods return this type
17146    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3ClothPhysics) -> Option<Self> {
17147        core::ptr::NonNull::new(raw).map(|raw| ClothPhysics { raw })
17148    }
17149}
17150
17151// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
17152// is deliberately NOT implemented — the C++ types make no documented
17153// guarantee about concurrent use, and claiming one we haven't verified
17154// would be unsound. See `@bind thread_safe` in the plan.
17155unsafe impl Send for ClothPhysics {}
17156
17157impl core::fmt::Debug for ClothPhysics {
17158    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
17159        f.debug_struct("ClothPhysics").finish_non_exhaustive()
17160    }
17161}
17162
17163impl ClothPhysics {
17164    /// # Panics
17165    /// Panics if the native allocation fails.
17166    pub fn new() -> Self {
17167        // SAFETY: the native constructor returns a live handle; a null here
17168        // means the library is unusable.
17169        unsafe {
17170            let raw = ffi::whiteout_m3_M3ClothPhysics_new();
17171            Self::from_raw(raw).expect("native ClothPhysics allocation failed")
17172        }
17173    }
17174
17175    /// Number of cloth mesh sections
17176    pub fn cloth_mesh_count(&self) -> u32 {
17177        // SAFETY: plain scalar read through a live handle.
17178        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_clothMeshCount(self.raw.as_ptr()) }
17179    }
17180
17181    pub fn set_cloth_mesh_count(&mut self, value: u32) {
17182        // SAFETY: plain scalar write through a live handle.
17183        unsafe { ffi::whiteout_m3_M3ClothPhysics_set_clothMeshCount(self.raw.as_ptr(), value) }
17184    }
17185
17186    /// Number of skin bones
17187    pub fn skin_bone_count(&self) -> u32 {
17188        // SAFETY: plain scalar read through a live handle.
17189        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_skinBoneCount(self.raw.as_ptr()) }
17190    }
17191
17192    pub fn set_skin_bone_count(&mut self, value: u32) {
17193        // SAFETY: plain scalar write through a live handle.
17194        unsafe { ffi::whiteout_m3_M3ClothPhysics_set_skinBoneCount(self.raw.as_ptr(), value) }
17195    }
17196
17197    /// Skin bone indices (U16_)
17198    /// Zero-copy view of the underlying `std::vector`.
17199    pub fn skin_bones(&self) -> &[u16] {
17200        // SAFETY: `_data`/`_count` describe one contiguous C++
17201        // allocation, borrowed for as long as `self` is.
17202        unsafe {
17203            let n = ffi::whiteout_m3_M3ClothPhysics_get_skinBones_count(self.raw.as_ptr());
17204            let p = ffi::whiteout_m3_M3ClothPhysics_get_skinBones_data(self.raw.as_ptr());
17205            if p.is_null() || n == 0 {
17206                &[]
17207            } else {
17208                core::slice::from_raw_parts(p, n)
17209            }
17210        }
17211    }
17212
17213    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
17214    pub fn skin_bones_mut(&mut self) -> &mut [u16] {
17215        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
17216        unsafe {
17217            let n = ffi::whiteout_m3_M3ClothPhysics_get_skinBones_count(self.raw.as_ptr());
17218            let p =
17219                ffi::whiteout_m3_M3ClothPhysics_get_skinBones_data(self.raw.as_ptr()) as *mut u16;
17220            if p.is_null() || n == 0 {
17221                &mut []
17222            } else {
17223                core::slice::from_raw_parts_mut(p, n)
17224            }
17225        }
17226    }
17227
17228    pub fn set_skin_bones(&mut self, values: &[u16]) {
17229        // SAFETY: the native side copies `values` before returning.
17230        unsafe {
17231            ffi::whiteout_m3_M3ClothPhysics_assign_skinBones(
17232                self.raw.as_ptr(),
17233                values.as_ptr() as *const _,
17234                values.len(),
17235            )
17236        }
17237    }
17238
17239    pub fn resize_skin_bones(&mut self, count: usize) {
17240        // SAFETY: reallocation is safe here precisely because
17241        // `&mut self` means no slice borrow is outstanding.
17242        unsafe { ffi::whiteout_m3_M3ClothPhysics_resize_skinBones(self.raw.as_ptr(), count) }
17243    }
17244
17245    /// Per-vertex simulation enable flags (U8__)
17246    /// Zero-copy view of the underlying `std::vector`.
17247    pub fn sim_enabled(&self) -> &[u8] {
17248        // SAFETY: `_data`/`_count` describe one contiguous C++
17249        // allocation, borrowed for as long as `self` is.
17250        unsafe {
17251            let n = ffi::whiteout_m3_M3ClothPhysics_get_simEnabled_count(self.raw.as_ptr());
17252            let p = ffi::whiteout_m3_M3ClothPhysics_get_simEnabled_data(self.raw.as_ptr());
17253            if p.is_null() || n == 0 {
17254                &[]
17255            } else {
17256                core::slice::from_raw_parts(p, n)
17257            }
17258        }
17259    }
17260
17261    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
17262    pub fn sim_enabled_mut(&mut self) -> &mut [u8] {
17263        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
17264        unsafe {
17265            let n = ffi::whiteout_m3_M3ClothPhysics_get_simEnabled_count(self.raw.as_ptr());
17266            let p =
17267                ffi::whiteout_m3_M3ClothPhysics_get_simEnabled_data(self.raw.as_ptr()) as *mut u8;
17268            if p.is_null() || n == 0 {
17269                &mut []
17270            } else {
17271                core::slice::from_raw_parts_mut(p, n)
17272            }
17273        }
17274    }
17275
17276    pub fn set_sim_enabled(&mut self, values: &[u8]) {
17277        // SAFETY: the native side copies `values` before returning.
17278        unsafe {
17279            ffi::whiteout_m3_M3ClothPhysics_assign_simEnabled(
17280                self.raw.as_ptr(),
17281                values.as_ptr() as *const _,
17282                values.len(),
17283            )
17284        }
17285    }
17286
17287    pub fn resize_sim_enabled(&mut self, count: usize) {
17288        // SAFETY: reallocation is safe here precisely because
17289        // `&mut self` means no slice borrow is outstanding.
17290        unsafe { ffi::whiteout_m3_M3ClothPhysics_resize_simEnabled(self.raw.as_ptr(), count) }
17291    }
17292
17293    /// Per-vertex bone indices (U32_)
17294    /// Zero-copy view of the underlying `std::vector`.
17295    pub fn vertex_bones(&self) -> &[u32] {
17296        // SAFETY: `_data`/`_count` describe one contiguous C++
17297        // allocation, borrowed for as long as `self` is.
17298        unsafe {
17299            let n = ffi::whiteout_m3_M3ClothPhysics_get_vertexBones_count(self.raw.as_ptr());
17300            let p = ffi::whiteout_m3_M3ClothPhysics_get_vertexBones_data(self.raw.as_ptr());
17301            if p.is_null() || n == 0 {
17302                &[]
17303            } else {
17304                core::slice::from_raw_parts(p, n)
17305            }
17306        }
17307    }
17308
17309    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
17310    pub fn vertex_bones_mut(&mut self) -> &mut [u32] {
17311        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
17312        unsafe {
17313            let n = ffi::whiteout_m3_M3ClothPhysics_get_vertexBones_count(self.raw.as_ptr());
17314            let p =
17315                ffi::whiteout_m3_M3ClothPhysics_get_vertexBones_data(self.raw.as_ptr()) as *mut u32;
17316            if p.is_null() || n == 0 {
17317                &mut []
17318            } else {
17319                core::slice::from_raw_parts_mut(p, n)
17320            }
17321        }
17322    }
17323
17324    pub fn set_vertex_bones(&mut self, values: &[u32]) {
17325        // SAFETY: the native side copies `values` before returning.
17326        unsafe {
17327            ffi::whiteout_m3_M3ClothPhysics_assign_vertexBones(
17328                self.raw.as_ptr(),
17329                values.as_ptr() as *const _,
17330                values.len(),
17331            )
17332        }
17333    }
17334
17335    pub fn resize_vertex_bones(&mut self, count: usize) {
17336        // SAFETY: reallocation is safe here precisely because
17337        // `&mut self` means no slice borrow is outstanding.
17338        unsafe { ffi::whiteout_m3_M3ClothPhysics_resize_vertexBones(self.raw.as_ptr(), count) }
17339    }
17340
17341    /// Per-vertex bone weights (U32_)
17342    /// Zero-copy view of the underlying `std::vector`.
17343    pub fn vertex_weights(&self) -> &[u32] {
17344        // SAFETY: `_data`/`_count` describe one contiguous C++
17345        // allocation, borrowed for as long as `self` is.
17346        unsafe {
17347            let n = ffi::whiteout_m3_M3ClothPhysics_get_vertexWeights_count(self.raw.as_ptr());
17348            let p = ffi::whiteout_m3_M3ClothPhysics_get_vertexWeights_data(self.raw.as_ptr());
17349            if p.is_null() || n == 0 {
17350                &[]
17351            } else {
17352                core::slice::from_raw_parts(p, n)
17353            }
17354        }
17355    }
17356
17357    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
17358    pub fn vertex_weights_mut(&mut self) -> &mut [u32] {
17359        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
17360        unsafe {
17361            let n = ffi::whiteout_m3_M3ClothPhysics_get_vertexWeights_count(self.raw.as_ptr());
17362            let p = ffi::whiteout_m3_M3ClothPhysics_get_vertexWeights_data(self.raw.as_ptr())
17363                as *mut u32;
17364            if p.is_null() || n == 0 {
17365                &mut []
17366            } else {
17367                core::slice::from_raw_parts_mut(p, n)
17368            }
17369        }
17370    }
17371
17372    pub fn set_vertex_weights(&mut self, values: &[u32]) {
17373        // SAFETY: the native side copies `values` before returning.
17374        unsafe {
17375            ffi::whiteout_m3_M3ClothPhysics_assign_vertexWeights(
17376                self.raw.as_ptr(),
17377                values.as_ptr() as *const _,
17378                values.len(),
17379            )
17380        }
17381    }
17382
17383    pub fn resize_vertex_weights(&mut self, count: usize) {
17384        // SAFETY: reallocation is safe here precisely because
17385        // `&mut self` means no slice borrow is outstanding.
17386        unsafe { ffi::whiteout_m3_M3ClothPhysics_resize_vertexWeights(self.raw.as_ptr(), count) }
17387    }
17388
17389    /// Cloth colliders (PHCC)
17390    pub fn colliders_len(&self) -> usize {
17391        // SAFETY: scalar read through a live handle.
17392        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_colliders_count(self.raw.as_ptr()) }
17393    }
17394
17395    /// Borrows element `index` in place. `None` when out of range.
17396    pub fn colliders(&self, index: usize) -> Option<crate::support::Ref<'_, ClothCollider>> {
17397        if index >= self.colliders_len() {
17398            return None;
17399        }
17400        // SAFETY: index checked above; the pointer is interior to `self`.
17401        unsafe {
17402            Some(crate::support::Ref::new(ClothCollider {
17403                raw: core::ptr::NonNull::new_unchecked(
17404                    ffi::whiteout_m3_M3ClothPhysics_get_colliders_at(self.raw.as_ptr(), index),
17405                ),
17406            }))
17407        }
17408    }
17409
17410    pub fn colliders_mut(
17411        &mut self,
17412        index: usize,
17413    ) -> Option<crate::support::RefMut<'_, ClothCollider>> {
17414        if index >= self.colliders_len() {
17415            return None;
17416        }
17417        // SAFETY: as above; `&mut self` guarantees exclusivity.
17418        unsafe {
17419            Some(crate::support::RefMut::new(ClothCollider {
17420                raw: core::ptr::NonNull::new_unchecked(
17421                    ffi::whiteout_m3_M3ClothPhysics_get_colliders_at(self.raw.as_ptr(), index),
17422                ),
17423            }))
17424        }
17425    }
17426
17427    /// Iterate the elements, borrowing each in turn.
17428    pub fn colliders_iter(
17429        &self,
17430    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, ClothCollider>> {
17431        (0..self.colliders_len()).map(move |i| self.colliders(i).expect("index below len"))
17432    }
17433
17434    pub fn resize_colliders(&mut self, count: usize) {
17435        // SAFETY: exclusive access, so no borrow is outstanding.
17436        unsafe { ffi::whiteout_m3_M3ClothPhysics_resize_colliders(self.raw.as_ptr(), count) }
17437    }
17438
17439    /// Cloth proxies (PHAC)
17440    pub fn proxies_len(&self) -> usize {
17441        // SAFETY: scalar read through a live handle.
17442        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_proxies_count(self.raw.as_ptr()) }
17443    }
17444
17445    /// Borrows element `index` in place. `None` when out of range.
17446    pub fn proxies(&self, index: usize) -> Option<crate::support::Ref<'_, ClothProxy>> {
17447        if index >= self.proxies_len() {
17448            return None;
17449        }
17450        // SAFETY: index checked above; the pointer is interior to `self`.
17451        unsafe {
17452            Some(crate::support::Ref::new(ClothProxy {
17453                raw: core::ptr::NonNull::new_unchecked(
17454                    ffi::whiteout_m3_M3ClothPhysics_get_proxies_at(self.raw.as_ptr(), index),
17455                ),
17456            }))
17457        }
17458    }
17459
17460    pub fn proxies_mut(&mut self, index: usize) -> Option<crate::support::RefMut<'_, ClothProxy>> {
17461        if index >= self.proxies_len() {
17462            return None;
17463        }
17464        // SAFETY: as above; `&mut self` guarantees exclusivity.
17465        unsafe {
17466            Some(crate::support::RefMut::new(ClothProxy {
17467                raw: core::ptr::NonNull::new_unchecked(
17468                    ffi::whiteout_m3_M3ClothPhysics_get_proxies_at(self.raw.as_ptr(), index),
17469                ),
17470            }))
17471        }
17472    }
17473
17474    /// Iterate the elements, borrowing each in turn.
17475    pub fn proxies_iter(
17476        &self,
17477    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, ClothProxy>> {
17478        (0..self.proxies_len()).map(move |i| self.proxies(i).expect("index below len"))
17479    }
17480
17481    pub fn resize_proxies(&mut self, count: usize) {
17482        // SAFETY: exclusive access, so no borrow is outstanding.
17483        unsafe { ffi::whiteout_m3_M3ClothPhysics_resize_proxies(self.raw.as_ptr(), count) }
17484    }
17485
17486    /// Cloth density
17487    pub fn density(&self) -> f32 {
17488        // SAFETY: plain scalar read through a live handle.
17489        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_density(self.raw.as_ptr()) }
17490    }
17491
17492    pub fn set_density(&mut self, value: f32) {
17493        // SAFETY: plain scalar write through a live handle.
17494        unsafe { ffi::whiteout_m3_M3ClothPhysics_set_density(self.raw.as_ptr(), value) }
17495    }
17496
17497    /// Tracking factor
17498    pub fn tracking(&self) -> f32 {
17499        // SAFETY: plain scalar read through a live handle.
17500        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_tracking(self.raw.as_ptr()) }
17501    }
17502
17503    pub fn set_tracking(&mut self, value: f32) {
17504        // SAFETY: plain scalar write through a live handle.
17505        unsafe { ffi::whiteout_m3_M3ClothPhysics_set_tracking(self.raw.as_ptr(), value) }
17506    }
17507
17508    /// Stretch stiffness
17509    pub fn stretch_stiffness(&self) -> f32 {
17510        // SAFETY: plain scalar read through a live handle.
17511        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_stretchStiffness(self.raw.as_ptr()) }
17512    }
17513
17514    pub fn set_stretch_stiffness(&mut self, value: f32) {
17515        // SAFETY: plain scalar write through a live handle.
17516        unsafe { ffi::whiteout_m3_M3ClothPhysics_set_stretchStiffness(self.raw.as_ptr(), value) }
17517    }
17518
17519    /// Horizontal stiffness
17520    pub fn horizontal_stiffness(&self) -> f32 {
17521        // SAFETY: plain scalar read through a live handle.
17522        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_horizontalStiffness(self.raw.as_ptr()) }
17523    }
17524
17525    pub fn set_horizontal_stiffness(&mut self, value: f32) {
17526        // SAFETY: plain scalar write through a live handle.
17527        unsafe { ffi::whiteout_m3_M3ClothPhysics_set_horizontalStiffness(self.raw.as_ptr(), value) }
17528    }
17529
17530    /// Bending stiffness
17531    pub fn bending_stiffness(&self) -> f32 {
17532        // SAFETY: plain scalar read through a live handle.
17533        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_bendingStiffness(self.raw.as_ptr()) }
17534    }
17535
17536    pub fn set_bending_stiffness(&mut self, value: f32) {
17537        // SAFETY: plain scalar write through a live handle.
17538        unsafe { ffi::whiteout_m3_M3ClothPhysics_set_bendingStiffness(self.raw.as_ptr(), value) }
17539    }
17540
17541    /// Damping coefficient
17542    pub fn damping(&self) -> f32 {
17543        // SAFETY: plain scalar read through a live handle.
17544        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_damping(self.raw.as_ptr()) }
17545    }
17546
17547    pub fn set_damping(&mut self, value: f32) {
17548        // SAFETY: plain scalar write through a live handle.
17549        unsafe { ffi::whiteout_m3_M3ClothPhysics_set_damping(self.raw.as_ptr(), value) }
17550    }
17551
17552    /// Friction coefficient
17553    pub fn friction(&self) -> f32 {
17554        // SAFETY: plain scalar read through a live handle.
17555        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_friction(self.raw.as_ptr()) }
17556    }
17557
17558    pub fn set_friction(&mut self, value: f32) {
17559        // SAFETY: plain scalar write through a live handle.
17560        unsafe { ffi::whiteout_m3_M3ClothPhysics_set_friction(self.raw.as_ptr(), value) }
17561    }
17562
17563    /// Gravity influence
17564    pub fn gravity(&self) -> f32 {
17565        // SAFETY: plain scalar read through a live handle.
17566        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_gravity(self.raw.as_ptr()) }
17567    }
17568
17569    pub fn set_gravity(&mut self, value: f32) {
17570        // SAFETY: plain scalar write through a live handle.
17571        unsafe { ffi::whiteout_m3_M3ClothPhysics_set_gravity(self.raw.as_ptr(), value) }
17572    }
17573
17574    /// Explosion force scale
17575    pub fn explosion_scale(&self) -> f32 {
17576        // SAFETY: plain scalar read through a live handle.
17577        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_explosionScale(self.raw.as_ptr()) }
17578    }
17579
17580    pub fn set_explosion_scale(&mut self, value: f32) {
17581        // SAFETY: plain scalar write through a live handle.
17582        unsafe { ffi::whiteout_m3_M3ClothPhysics_set_explosionScale(self.raw.as_ptr(), value) }
17583    }
17584
17585    /// Wind force scale
17586    pub fn wind_scale(&self) -> f32 {
17587        // SAFETY: plain scalar read through a live handle.
17588        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_windScale(self.raw.as_ptr()) }
17589    }
17590
17591    pub fn set_wind_scale(&mut self, value: f32) {
17592        // SAFETY: plain scalar write through a live handle.
17593        unsafe { ffi::whiteout_m3_M3ClothPhysics_set_windScale(self.raw.as_ptr(), value) }
17594    }
17595
17596    /// Shear stiffness
17597    pub fn shear_stiffness(&self) -> f32 {
17598        // SAFETY: plain scalar read through a live handle.
17599        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_shearStiffness(self.raw.as_ptr()) }
17600    }
17601
17602    pub fn set_shear_stiffness(&mut self, value: f32) {
17603        // SAFETY: plain scalar write through a live handle.
17604        unsafe { ffi::whiteout_m3_M3ClothPhysics_set_shearStiffness(self.raw.as_ptr(), value) }
17605    }
17606
17607    /// Drag factor
17608    pub fn drag_factor(&self) -> f32 {
17609        // SAFETY: plain scalar read through a live handle.
17610        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_dragFactor(self.raw.as_ptr()) }
17611    }
17612
17613    pub fn set_drag_factor(&mut self, value: f32) {
17614        // SAFETY: plain scalar write through a live handle.
17615        unsafe { ffi::whiteout_m3_M3ClothPhysics_set_dragFactor(self.raw.as_ptr(), value) }
17616    }
17617
17618    /// Lift factor (v4+)
17619    pub fn lift_factor(&self) -> f32 {
17620        // SAFETY: plain scalar read through a live handle.
17621        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_liftFactor(self.raw.as_ptr()) }
17622    }
17623
17624    pub fn set_lift_factor(&mut self, value: f32) {
17625        // SAFETY: plain scalar write through a live handle.
17626        unsafe { ffi::whiteout_m3_M3ClothPhysics_set_liftFactor(self.raw.as_ptr(), value) }
17627    }
17628
17629    /// Sphere collider stiffness (v4+)
17630    pub fn sphere_stiffness(&self) -> f32 {
17631        // SAFETY: plain scalar read through a live handle.
17632        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_sphereStiffness(self.raw.as_ptr()) }
17633    }
17634
17635    pub fn set_sphere_stiffness(&mut self, value: f32) {
17636        // SAFETY: plain scalar write through a live handle.
17637        unsafe { ffi::whiteout_m3_M3ClothPhysics_set_sphereStiffness(self.raw.as_ptr(), value) }
17638    }
17639
17640    /// Flatten mode (v4+)
17641    pub fn flatten(&self) -> u32 {
17642        // SAFETY: plain scalar read through a live handle.
17643        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_flatten(self.raw.as_ptr()) }
17644    }
17645
17646    pub fn set_flatten(&mut self, value: u32) {
17647        // SAFETY: plain scalar write through a live handle.
17648        unsafe { ffi::whiteout_m3_M3ClothPhysics_set_flatten(self.raw.as_ptr(), value) }
17649    }
17650
17651    /// Animated active state
17652    /// Borrows the field in place — no copy, no allocation.
17653    pub fn active(&self) -> crate::support::Ref<'_, AnimRefU32> {
17654        // SAFETY: an interior pointer into `self`, valid for this
17655        // borrow and never freed by the `Ref`.
17656        unsafe {
17657            crate::support::Ref::new(AnimRefU32 {
17658                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3ClothPhysics_get_active(
17659                    self.raw.as_ptr(),
17660                )),
17661            })
17662        }
17663    }
17664
17665    pub fn active_mut(&mut self) -> crate::support::RefMut<'_, AnimRefU32> {
17666        // SAFETY: as above; `&mut self` guarantees exclusivity.
17667        unsafe {
17668            crate::support::RefMut::new(AnimRefU32 {
17669                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3ClothPhysics_get_active(
17670                    self.raw.as_ptr(),
17671                )),
17672            })
17673        }
17674    }
17675
17676    /// Use skin mesh for collision
17677    pub fn use_skin_collision(&self) -> u32 {
17678        // SAFETY: plain scalar read through a live handle.
17679        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_useSkinCollision(self.raw.as_ptr()) }
17680    }
17681
17682    pub fn set_use_skin_collision(&mut self, value: u32) {
17683        // SAFETY: plain scalar write through a live handle.
17684        unsafe { ffi::whiteout_m3_M3ClothPhysics_set_useSkinCollision(self.raw.as_ptr(), value) }
17685    }
17686
17687    /// Skin collision offset
17688    pub fn skin_offset(&self) -> f32 {
17689        // SAFETY: plain scalar read through a live handle.
17690        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_skinOffset(self.raw.as_ptr()) }
17691    }
17692
17693    pub fn set_skin_offset(&mut self, value: f32) {
17694        // SAFETY: plain scalar write through a live handle.
17695        unsafe { ffi::whiteout_m3_M3ClothPhysics_set_skinOffset(self.raw.as_ptr(), value) }
17696    }
17697
17698    /// Skin collision exponent
17699    pub fn skin_exponent(&self) -> f32 {
17700        // SAFETY: plain scalar read through a live handle.
17701        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_skinExponent(self.raw.as_ptr()) }
17702    }
17703
17704    pub fn set_skin_exponent(&mut self, value: f32) {
17705        // SAFETY: plain scalar write through a live handle.
17706        unsafe { ffi::whiteout_m3_M3ClothPhysics_set_skinExponent(self.raw.as_ptr(), value) }
17707    }
17708
17709    /// Skin collision stiffness
17710    pub fn skin_stiffness(&self) -> f32 {
17711        // SAFETY: plain scalar read through a live handle.
17712        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_skinStiffness(self.raw.as_ptr()) }
17713    }
17714
17715    pub fn set_skin_stiffness(&mut self, value: f32) {
17716        // SAFETY: plain scalar write through a live handle.
17717        unsafe { ffi::whiteout_m3_M3ClothPhysics_set_skinStiffness(self.raw.as_ptr(), value) }
17718    }
17719
17720    /// Local force channel bitmask
17721    pub fn local_channels(&self) -> u32 {
17722        // SAFETY: plain scalar read through a live handle.
17723        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_localChannels(self.raw.as_ptr()) }
17724    }
17725
17726    pub fn set_local_channels(&mut self, value: u32) {
17727        // SAFETY: plain scalar write through a live handle.
17728        unsafe { ffi::whiteout_m3_M3ClothPhysics_set_localChannels(self.raw.as_ptr(), value) }
17729    }
17730
17731    /// Local wind direction and magnitude
17732    pub fn local_wind(&self) -> crate::math::Vector3f {
17733        // SAFETY: the getter returns an interior pointer to a
17734        // layout-identical POD; we copy it out immediately.
17735        unsafe {
17736            *(ffi::whiteout_m3_M3ClothPhysics_get_localWind(self.raw.as_ptr())
17737                as *const crate::math::Vector3f)
17738        }
17739    }
17740
17741    pub fn set_local_wind(&mut self, value: crate::math::Vector3f) {
17742        // SAFETY: as above, in the other direction.
17743        unsafe {
17744            ffi::whiteout_m3_M3ClothPhysics_set_localWind(
17745                self.raw.as_ptr(),
17746                &value as *const crate::math::Vector3f as *const _,
17747            )
17748        }
17749    }
17750}
17751
17752impl Default for ClothPhysics {
17753    fn default() -> Self {
17754        Self::new()
17755    }
17756}
17757
17758/// LITE — Light source (v0–v7, 212 bytes)
17759///
17760/// Omni, spot, or directional light with animated diffuse/specular colors, intensity, decay, attenuation start/end, and spot-light hot-spot/falloff.
17761pub struct Light {
17762    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3Light>,
17763}
17764
17765impl Drop for Light {
17766    fn drop(&mut self) {
17767        // SAFETY: `raw` came from a native constructor and Drop runs once.
17768        unsafe { ffi::whiteout_m3_M3Light_delete(self.raw.as_ptr()) }
17769    }
17770}
17771
17772impl Light {
17773    /// # Safety
17774    /// `raw` must be a live handle this value takes ownership of.
17775    #[allow(dead_code)] // used by whichever methods return this type
17776    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3Light) -> Option<Self> {
17777        core::ptr::NonNull::new(raw).map(|raw| Light { raw })
17778    }
17779}
17780
17781// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
17782// is deliberately NOT implemented — the C++ types make no documented
17783// guarantee about concurrent use, and claiming one we haven't verified
17784// would be unsound. See `@bind thread_safe` in the plan.
17785unsafe impl Send for Light {}
17786
17787impl core::fmt::Debug for Light {
17788    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
17789        f.debug_struct("Light").finish_non_exhaustive()
17790    }
17791}
17792
17793impl Light {
17794    /// # Panics
17795    /// Panics if the native allocation fails.
17796    pub fn new() -> Self {
17797        // SAFETY: the native constructor returns a live handle; a null here
17798        // means the library is unusable.
17799        unsafe {
17800            let raw = ffi::whiteout_m3_M3Light_new();
17801            Self::from_raw(raw).expect("native Light allocation failed")
17802        }
17803    }
17804
17805    /// Light type (omni/spot/directional)
17806    pub fn light_type(&self) -> LightType {
17807        // SAFETY: scalar read; the discriminant is validated below.
17808        unsafe { ffi::whiteout_m3_M3Light_get_lightType(self.raw.as_ptr()) }
17809            .try_into()
17810            .expect("unknown enum discriminant from the native library")
17811    }
17812
17813    pub fn set_light_type(&mut self, value: LightType) {
17814        // SAFETY: scalar write through a live handle.
17815        unsafe { ffi::whiteout_m3_M3Light_set_lightType(self.raw.as_ptr(), value as i32) }
17816    }
17817
17818    /// Index into BONE array
17819    pub fn bone_index(&self) -> u16 {
17820        // SAFETY: plain scalar read through a live handle.
17821        unsafe { ffi::whiteout_m3_M3Light_get_boneIndex(self.raw.as_ptr()) }
17822    }
17823
17824    pub fn set_bone_index(&mut self, value: u16) {
17825        // SAFETY: plain scalar write through a live handle.
17826        unsafe { ffi::whiteout_m3_M3Light_set_boneIndex(self.raw.as_ptr(), value) }
17827    }
17828
17829    /// Light flags (shadows, specular, AO, etc.)
17830    pub fn flags(&self) -> LightFlag {
17831        // SAFETY: scalar read; a flag set accepts any bits.
17832        LightFlag(unsafe { ffi::whiteout_m3_M3Light_get_flags(self.raw.as_ptr()) })
17833    }
17834
17835    pub fn set_flags(&mut self, value: LightFlag) {
17836        // SAFETY: scalar write through a live handle.
17837        unsafe { ffi::whiteout_m3_M3Light_set_flags(self.raw.as_ptr(), value.0) }
17838    }
17839
17840    /// LOD cut-off level
17841    pub fn lod_cut(&self) -> u32 {
17842        // SAFETY: plain scalar read through a live handle.
17843        unsafe { ffi::whiteout_m3_M3Light_get_lodCut(self.raw.as_ptr()) }
17844    }
17845
17846    pub fn set_lod_cut(&mut self, value: u32) {
17847        // SAFETY: plain scalar write through a live handle.
17848        unsafe { ffi::whiteout_m3_M3Light_set_lodCut(self.raw.as_ptr(), value) }
17849    }
17850
17851    /// Shadow LOD cut-off level
17852    pub fn shadow_lod_cut(&self) -> u32 {
17853        // SAFETY: plain scalar read through a live handle.
17854        unsafe { ffi::whiteout_m3_M3Light_get_shadowLodCut(self.raw.as_ptr()) }
17855    }
17856
17857    pub fn set_shadow_lod_cut(&mut self, value: u32) {
17858        // SAFETY: plain scalar write through a live handle.
17859        unsafe { ffi::whiteout_m3_M3Light_set_shadowLodCut(self.raw.as_ptr(), value) }
17860    }
17861
17862    /// Animated diffuse color (RGB)
17863    /// Borrows the field in place — no copy, no allocation.
17864    pub fn diffuse_color(&self) -> crate::support::Ref<'_, AnimRefVector3f> {
17865        // SAFETY: an interior pointer into `self`, valid for this
17866        // borrow and never freed by the `Ref`.
17867        unsafe {
17868            crate::support::Ref::new(AnimRefVector3f {
17869                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Light_get_diffuseColor(
17870                    self.raw.as_ptr(),
17871                )),
17872            })
17873        }
17874    }
17875
17876    pub fn diffuse_color_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector3f> {
17877        // SAFETY: as above; `&mut self` guarantees exclusivity.
17878        unsafe {
17879            crate::support::RefMut::new(AnimRefVector3f {
17880                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Light_get_diffuseColor(
17881                    self.raw.as_ptr(),
17882                )),
17883            })
17884        }
17885    }
17886
17887    /// Animated intensity multiplier
17888    /// Borrows the field in place — no copy, no allocation.
17889    pub fn intensity_multiplier(&self) -> crate::support::Ref<'_, AnimRefF32> {
17890        // SAFETY: an interior pointer into `self`, valid for this
17891        // borrow and never freed by the `Ref`.
17892        unsafe {
17893            crate::support::Ref::new(AnimRefF32 {
17894                raw: core::ptr::NonNull::new_unchecked(
17895                    ffi::whiteout_m3_M3Light_get_intensityMultiplier(self.raw.as_ptr()),
17896                ),
17897            })
17898        }
17899    }
17900
17901    pub fn intensity_multiplier_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
17902        // SAFETY: as above; `&mut self` guarantees exclusivity.
17903        unsafe {
17904            crate::support::RefMut::new(AnimRefF32 {
17905                raw: core::ptr::NonNull::new_unchecked(
17906                    ffi::whiteout_m3_M3Light_get_intensityMultiplier(self.raw.as_ptr()),
17907                ),
17908            })
17909        }
17910    }
17911
17912    /// Animated specular color (RGB)
17913    /// Borrows the field in place — no copy, no allocation.
17914    pub fn specular_color(&self) -> crate::support::Ref<'_, AnimRefVector3f> {
17915        // SAFETY: an interior pointer into `self`, valid for this
17916        // borrow and never freed by the `Ref`.
17917        unsafe {
17918            crate::support::Ref::new(AnimRefVector3f {
17919                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Light_get_specularColor(
17920                    self.raw.as_ptr(),
17921                )),
17922            })
17923        }
17924    }
17925
17926    pub fn specular_color_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector3f> {
17927        // SAFETY: as above; `&mut self` guarantees exclusivity.
17928        unsafe {
17929            crate::support::RefMut::new(AnimRefVector3f {
17930                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Light_get_specularColor(
17931                    self.raw.as_ptr(),
17932                )),
17933            })
17934        }
17935    }
17936
17937    /// Animated specular multiplier
17938    /// Borrows the field in place — no copy, no allocation.
17939    pub fn specular_multiplier(&self) -> crate::support::Ref<'_, AnimRefF32> {
17940        // SAFETY: an interior pointer into `self`, valid for this
17941        // borrow and never freed by the `Ref`.
17942        unsafe {
17943            crate::support::Ref::new(AnimRefF32 {
17944                raw: core::ptr::NonNull::new_unchecked(
17945                    ffi::whiteout_m3_M3Light_get_specularMultiplier(self.raw.as_ptr()),
17946                ),
17947            })
17948        }
17949    }
17950
17951    pub fn specular_multiplier_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
17952        // SAFETY: as above; `&mut self` guarantees exclusivity.
17953        unsafe {
17954            crate::support::RefMut::new(AnimRefF32 {
17955                raw: core::ptr::NonNull::new_unchecked(
17956                    ffi::whiteout_m3_M3Light_get_specularMultiplier(self.raw.as_ptr()),
17957                ),
17958            })
17959        }
17960    }
17961
17962    /// Animated distance decay exponent
17963    /// Borrows the field in place — no copy, no allocation.
17964    pub fn decay(&self) -> crate::support::Ref<'_, AnimRefF32> {
17965        // SAFETY: an interior pointer into `self`, valid for this
17966        // borrow and never freed by the `Ref`.
17967        unsafe {
17968            crate::support::Ref::new(AnimRefF32 {
17969                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Light_get_decay(
17970                    self.raw.as_ptr(),
17971                )),
17972            })
17973        }
17974    }
17975
17976    pub fn decay_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
17977        // SAFETY: as above; `&mut self` guarantees exclusivity.
17978        unsafe {
17979            crate::support::RefMut::new(AnimRefF32 {
17980                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Light_get_decay(
17981                    self.raw.as_ptr(),
17982                )),
17983            })
17984        }
17985    }
17986
17987    /// Attenuation end distance
17988    pub fn attenuation_end(&self) -> f32 {
17989        // SAFETY: plain scalar read through a live handle.
17990        unsafe { ffi::whiteout_m3_M3Light_get_attenuationEnd(self.raw.as_ptr()) }
17991    }
17992
17993    pub fn set_attenuation_end(&mut self, value: f32) {
17994        // SAFETY: plain scalar write through a live handle.
17995        unsafe { ffi::whiteout_m3_M3Light_set_attenuationEnd(self.raw.as_ptr(), value) }
17996    }
17997
17998    /// Animated attenuation start distance
17999    /// Borrows the field in place — no copy, no allocation.
18000    pub fn attenuation_start(&self) -> crate::support::Ref<'_, AnimRefF32> {
18001        // SAFETY: an interior pointer into `self`, valid for this
18002        // borrow and never freed by the `Ref`.
18003        unsafe {
18004            crate::support::Ref::new(AnimRefF32 {
18005                raw: core::ptr::NonNull::new_unchecked(
18006                    ffi::whiteout_m3_M3Light_get_attenuationStart(self.raw.as_ptr()),
18007                ),
18008            })
18009        }
18010    }
18011
18012    pub fn attenuation_start_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
18013        // SAFETY: as above; `&mut self` guarantees exclusivity.
18014        unsafe {
18015            crate::support::RefMut::new(AnimRefF32 {
18016                raw: core::ptr::NonNull::new_unchecked(
18017                    ffi::whiteout_m3_M3Light_get_attenuationStart(self.raw.as_ptr()),
18018                ),
18019            })
18020        }
18021    }
18022
18023    /// Animated spot inner cone angle
18024    /// Borrows the field in place — no copy, no allocation.
18025    pub fn hot_spot(&self) -> crate::support::Ref<'_, AnimRefF32> {
18026        // SAFETY: an interior pointer into `self`, valid for this
18027        // borrow and never freed by the `Ref`.
18028        unsafe {
18029            crate::support::Ref::new(AnimRefF32 {
18030                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Light_get_hotSpot(
18031                    self.raw.as_ptr(),
18032                )),
18033            })
18034        }
18035    }
18036
18037    pub fn hot_spot_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
18038        // SAFETY: as above; `&mut self` guarantees exclusivity.
18039        unsafe {
18040            crate::support::RefMut::new(AnimRefF32 {
18041                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Light_get_hotSpot(
18042                    self.raw.as_ptr(),
18043                )),
18044            })
18045        }
18046    }
18047
18048    /// Animated spot outer cone falloff
18049    /// Borrows the field in place — no copy, no allocation.
18050    pub fn falloff(&self) -> crate::support::Ref<'_, AnimRefF32> {
18051        // SAFETY: an interior pointer into `self`, valid for this
18052        // borrow and never freed by the `Ref`.
18053        unsafe {
18054            crate::support::Ref::new(AnimRefF32 {
18055                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Light_get_falloff(
18056                    self.raw.as_ptr(),
18057                )),
18058            })
18059        }
18060    }
18061
18062    pub fn falloff_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
18063        // SAFETY: as above; `&mut self` guarantees exclusivity.
18064        unsafe {
18065            crate::support::RefMut::new(AnimRefF32 {
18066                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Light_get_falloff(
18067                    self.raw.as_ptr(),
18068                )),
18069            })
18070        }
18071    }
18072}
18073
18074impl Default for Light {
18075    fn default() -> Self {
18076        Self::new()
18077    }
18078}
18079
18080/// CAM_ — Camera (v2–v5, 144–264 bytes)
18081///
18082/// Bone-attached camera with animated FOV, clip planes, shadow clip distance, depth-of-field parameters, and version-dependent bokeh settings.
18083pub struct Camera {
18084    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3Camera>,
18085}
18086
18087impl Drop for Camera {
18088    fn drop(&mut self) {
18089        // SAFETY: `raw` came from a native constructor and Drop runs once.
18090        unsafe { ffi::whiteout_m3_M3Camera_delete(self.raw.as_ptr()) }
18091    }
18092}
18093
18094impl Camera {
18095    /// # Safety
18096    /// `raw` must be a live handle this value takes ownership of.
18097    #[allow(dead_code)] // used by whichever methods return this type
18098    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3Camera) -> Option<Self> {
18099        core::ptr::NonNull::new(raw).map(|raw| Camera { raw })
18100    }
18101}
18102
18103// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
18104// is deliberately NOT implemented — the C++ types make no documented
18105// guarantee about concurrent use, and claiming one we haven't verified
18106// would be unsound. See `@bind thread_safe` in the plan.
18107unsafe impl Send for Camera {}
18108
18109impl core::fmt::Debug for Camera {
18110    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
18111        f.debug_struct("Camera").finish_non_exhaustive()
18112    }
18113}
18114
18115impl Camera {
18116    /// # Panics
18117    /// Panics if the native allocation fails.
18118    pub fn new() -> Self {
18119        // SAFETY: the native constructor returns a live handle; a null here
18120        // means the library is unusable.
18121        unsafe {
18122            let raw = ffi::whiteout_m3_M3Camera_new();
18123            Self::from_raw(raw).expect("native Camera allocation failed")
18124        }
18125    }
18126
18127    /// Index into BONE array
18128    pub fn bone_index(&self) -> u32 {
18129        // SAFETY: plain scalar read through a live handle.
18130        unsafe { ffi::whiteout_m3_M3Camera_get_boneIndex(self.raw.as_ptr()) }
18131    }
18132
18133    pub fn set_bone_index(&mut self, value: u32) {
18134        // SAFETY: plain scalar write through a live handle.
18135        unsafe { ffi::whiteout_m3_M3Camera_set_boneIndex(self.raw.as_ptr(), value) }
18136    }
18137
18138    /// Camera name (`Ref<CHAR>`)
18139    pub fn name(&self) -> String {
18140        // SAFETY: the native side hands over an owned CString.
18141        unsafe {
18142            crate::support::take_string(ffi::whiteout_m3_M3Camera_get_name(self.raw.as_ptr()))
18143        }
18144    }
18145
18146    pub fn set_name(&mut self, value: &str) {
18147        let value = std::ffi::CString::new(value).unwrap_or_default();
18148        // SAFETY: the pointer outlives the call.
18149        unsafe { ffi::whiteout_m3_M3Camera_set_name(self.raw.as_ptr(), value.as_ptr()) }
18150    }
18151
18152    /// Animated FOV in radians (v2+)
18153    /// Borrows the field in place — no copy, no allocation.
18154    pub fn field_of_view(&self) -> crate::support::Ref<'_, AnimRefF32> {
18155        // SAFETY: an interior pointer into `self`, valid for this
18156        // borrow and never freed by the `Ref`.
18157        unsafe {
18158            crate::support::Ref::new(AnimRefF32 {
18159                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Camera_get_fieldOfView(
18160                    self.raw.as_ptr(),
18161                )),
18162            })
18163        }
18164    }
18165
18166    pub fn field_of_view_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
18167        // SAFETY: as above; `&mut self` guarantees exclusivity.
18168        unsafe {
18169            crate::support::RefMut::new(AnimRefF32 {
18170                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Camera_get_fieldOfView(
18171                    self.raw.as_ptr(),
18172                )),
18173            })
18174        }
18175    }
18176
18177    /// Use vertical FOV (0 or 1, v2+)
18178    pub fn use_vertical_fov(&self) -> u32 {
18179        // SAFETY: plain scalar read through a live handle.
18180        unsafe { ffi::whiteout_m3_M3Camera_get_useVerticalFOV(self.raw.as_ptr()) }
18181    }
18182
18183    pub fn set_use_vertical_fov(&mut self, value: u32) {
18184        // SAFETY: plain scalar write through a live handle.
18185        unsafe { ffi::whiteout_m3_M3Camera_set_useVerticalFOV(self.raw.as_ptr(), value) }
18186    }
18187
18188    /// DOF type (v5 only, default 3)
18189    pub fn dof_type(&self) -> u32 {
18190        // SAFETY: plain scalar read through a live handle.
18191        unsafe { ffi::whiteout_m3_M3Camera_get_dofType(self.raw.as_ptr()) }
18192    }
18193
18194    pub fn set_dof_type(&mut self, value: u32) {
18195        // SAFETY: plain scalar write through a live handle.
18196        unsafe { ffi::whiteout_m3_M3Camera_set_dofType(self.raw.as_ptr(), value) }
18197    }
18198
18199    /// Animated far clip plane (v3+)
18200    /// Borrows the field in place — no copy, no allocation.
18201    pub fn far_clip(&self) -> crate::support::Ref<'_, AnimRefF32> {
18202        // SAFETY: an interior pointer into `self`, valid for this
18203        // borrow and never freed by the `Ref`.
18204        unsafe {
18205            crate::support::Ref::new(AnimRefF32 {
18206                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Camera_get_farClip(
18207                    self.raw.as_ptr(),
18208                )),
18209            })
18210        }
18211    }
18212
18213    pub fn far_clip_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
18214        // SAFETY: as above; `&mut self` guarantees exclusivity.
18215        unsafe {
18216            crate::support::RefMut::new(AnimRefF32 {
18217                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Camera_get_farClip(
18218                    self.raw.as_ptr(),
18219                )),
18220            })
18221        }
18222    }
18223
18224    /// Animated near clip plane (v3+)
18225    /// Borrows the field in place — no copy, no allocation.
18226    pub fn near_clip(&self) -> crate::support::Ref<'_, AnimRefF32> {
18227        // SAFETY: an interior pointer into `self`, valid for this
18228        // borrow and never freed by the `Ref`.
18229        unsafe {
18230            crate::support::Ref::new(AnimRefF32 {
18231                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Camera_get_nearClip(
18232                    self.raw.as_ptr(),
18233                )),
18234            })
18235        }
18236    }
18237
18238    pub fn near_clip_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
18239        // SAFETY: as above; `&mut self` guarantees exclusivity.
18240        unsafe {
18241            crate::support::RefMut::new(AnimRefF32 {
18242                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Camera_get_nearClip(
18243                    self.raw.as_ptr(),
18244                )),
18245            })
18246        }
18247    }
18248
18249    /// Animated shadow clip distance (v2+)
18250    /// Borrows the field in place — no copy, no allocation.
18251    pub fn shadow_clip_distance(&self) -> crate::support::Ref<'_, AnimRefF32> {
18252        // SAFETY: an interior pointer into `self`, valid for this
18253        // borrow and never freed by the `Ref`.
18254        unsafe {
18255            crate::support::Ref::new(AnimRefF32 {
18256                raw: core::ptr::NonNull::new_unchecked(
18257                    ffi::whiteout_m3_M3Camera_get_shadowClipDistance(self.raw.as_ptr()),
18258                ),
18259            })
18260        }
18261    }
18262
18263    pub fn shadow_clip_distance_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
18264        // SAFETY: as above; `&mut self` guarantees exclusivity.
18265        unsafe {
18266            crate::support::RefMut::new(AnimRefF32 {
18267                raw: core::ptr::NonNull::new_unchecked(
18268                    ffi::whiteout_m3_M3Camera_get_shadowClipDistance(self.raw.as_ptr()),
18269                ),
18270            })
18271        }
18272    }
18273
18274    /// Animated DOF focal point distance (v2+)
18275    /// Borrows the field in place — no copy, no allocation.
18276    pub fn focus_distance(&self) -> crate::support::Ref<'_, AnimRefF32> {
18277        // SAFETY: an interior pointer into `self`, valid for this
18278        // borrow and never freed by the `Ref`.
18279        unsafe {
18280            crate::support::Ref::new(AnimRefF32 {
18281                raw: core::ptr::NonNull::new_unchecked(
18282                    ffi::whiteout_m3_M3Camera_get_focusDistance(self.raw.as_ptr()),
18283                ),
18284            })
18285        }
18286    }
18287
18288    pub fn focus_distance_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
18289        // SAFETY: as above; `&mut self` guarantees exclusivity.
18290        unsafe {
18291            crate::support::RefMut::new(AnimRefF32 {
18292                raw: core::ptr::NonNull::new_unchecked(
18293                    ffi::whiteout_m3_M3Camera_get_focusDistance(self.raw.as_ptr()),
18294                ),
18295            })
18296        }
18297    }
18298
18299    /// Animated DOF far focus range (v2+)
18300    /// Borrows the field in place — no copy, no allocation.
18301    pub fn far_focus_range(&self) -> crate::support::Ref<'_, AnimRefF32> {
18302        // SAFETY: an interior pointer into `self`, valid for this
18303        // borrow and never freed by the `Ref`.
18304        unsafe {
18305            crate::support::Ref::new(AnimRefF32 {
18306                raw: core::ptr::NonNull::new_unchecked(
18307                    ffi::whiteout_m3_M3Camera_get_farFocusRange(self.raw.as_ptr()),
18308                ),
18309            })
18310        }
18311    }
18312
18313    pub fn far_focus_range_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
18314        // SAFETY: as above; `&mut self` guarantees exclusivity.
18315        unsafe {
18316            crate::support::RefMut::new(AnimRefF32 {
18317                raw: core::ptr::NonNull::new_unchecked(
18318                    ffi::whiteout_m3_M3Camera_get_farFocusRange(self.raw.as_ptr()),
18319                ),
18320            })
18321        }
18322    }
18323
18324    /// Animated DOF near focus range (v2+)
18325    /// Borrows the field in place — no copy, no allocation.
18326    pub fn near_focus_range(&self) -> crate::support::Ref<'_, AnimRefF32> {
18327        // SAFETY: an interior pointer into `self`, valid for this
18328        // borrow and never freed by the `Ref`.
18329        unsafe {
18330            crate::support::Ref::new(AnimRefF32 {
18331                raw: core::ptr::NonNull::new_unchecked(
18332                    ffi::whiteout_m3_M3Camera_get_nearFocusRange(self.raw.as_ptr()),
18333                ),
18334            })
18335        }
18336    }
18337
18338    pub fn near_focus_range_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
18339        // SAFETY: as above; `&mut self` guarantees exclusivity.
18340        unsafe {
18341            crate::support::RefMut::new(AnimRefF32 {
18342                raw: core::ptr::NonNull::new_unchecked(
18343                    ffi::whiteout_m3_M3Camera_get_nearFocusRange(self.raw.as_ptr()),
18344                ),
18345            })
18346        }
18347    }
18348
18349    /// Animated near falloff start (v4+)
18350    /// Borrows the field in place — no copy, no allocation.
18351    pub fn near_falloff_start(&self) -> crate::support::Ref<'_, AnimRefF32> {
18352        // SAFETY: an interior pointer into `self`, valid for this
18353        // borrow and never freed by the `Ref`.
18354        unsafe {
18355            crate::support::Ref::new(AnimRefF32 {
18356                raw: core::ptr::NonNull::new_unchecked(
18357                    ffi::whiteout_m3_M3Camera_get_nearFalloffStart(self.raw.as_ptr()),
18358                ),
18359            })
18360        }
18361    }
18362
18363    pub fn near_falloff_start_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
18364        // SAFETY: as above; `&mut self` guarantees exclusivity.
18365        unsafe {
18366            crate::support::RefMut::new(AnimRefF32 {
18367                raw: core::ptr::NonNull::new_unchecked(
18368                    ffi::whiteout_m3_M3Camera_get_nearFalloffStart(self.raw.as_ptr()),
18369                ),
18370            })
18371        }
18372    }
18373
18374    /// Animated near falloff end (v4+)
18375    /// Borrows the field in place — no copy, no allocation.
18376    pub fn near_falloff_end(&self) -> crate::support::Ref<'_, AnimRefF32> {
18377        // SAFETY: an interior pointer into `self`, valid for this
18378        // borrow and never freed by the `Ref`.
18379        unsafe {
18380            crate::support::Ref::new(AnimRefF32 {
18381                raw: core::ptr::NonNull::new_unchecked(
18382                    ffi::whiteout_m3_M3Camera_get_nearFalloffEnd(self.raw.as_ptr()),
18383                ),
18384            })
18385        }
18386    }
18387
18388    pub fn near_falloff_end_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
18389        // SAFETY: as above; `&mut self` guarantees exclusivity.
18390        unsafe {
18391            crate::support::RefMut::new(AnimRefF32 {
18392                raw: core::ptr::NonNull::new_unchecked(
18393                    ffi::whiteout_m3_M3Camera_get_nearFalloffEnd(self.raw.as_ptr()),
18394                ),
18395            })
18396        }
18397    }
18398
18399    /// Animated DOF strength (v2+)
18400    /// Borrows the field in place — no copy, no allocation.
18401    pub fn dof_amount(&self) -> crate::support::Ref<'_, AnimRefF32> {
18402        // SAFETY: an interior pointer into `self`, valid for this
18403        // borrow and never freed by the `Ref`.
18404        unsafe {
18405            crate::support::Ref::new(AnimRefF32 {
18406                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Camera_get_dofAmount(
18407                    self.raw.as_ptr(),
18408                )),
18409            })
18410        }
18411    }
18412
18413    pub fn dof_amount_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
18414        // SAFETY: as above; `&mut self` guarantees exclusivity.
18415        unsafe {
18416            crate::support::RefMut::new(AnimRefF32 {
18417                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Camera_get_dofAmount(
18418                    self.raw.as_ptr(),
18419                )),
18420            })
18421        }
18422    }
18423
18424    /// Animated bokeh f-stop (v5+)
18425    /// Borrows the field in place — no copy, no allocation.
18426    pub fn bokeh_f_stop(&self) -> crate::support::Ref<'_, AnimRefF32> {
18427        // SAFETY: an interior pointer into `self`, valid for this
18428        // borrow and never freed by the `Ref`.
18429        unsafe {
18430            crate::support::Ref::new(AnimRefF32 {
18431                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Camera_get_bokehFStop(
18432                    self.raw.as_ptr(),
18433                )),
18434            })
18435        }
18436    }
18437
18438    pub fn bokeh_f_stop_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
18439        // SAFETY: as above; `&mut self` guarantees exclusivity.
18440        unsafe {
18441            crate::support::RefMut::new(AnimRefF32 {
18442                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Camera_get_bokehFStop(
18443                    self.raw.as_ptr(),
18444                )),
18445            })
18446        }
18447    }
18448
18449    /// Animated bokeh max CoC diameter (v5+)
18450    /// Borrows the field in place — no copy, no allocation.
18451    pub fn bokeh_max_co_c_diameter(&self) -> crate::support::Ref<'_, AnimRefF32> {
18452        // SAFETY: an interior pointer into `self`, valid for this
18453        // borrow and never freed by the `Ref`.
18454        unsafe {
18455            crate::support::Ref::new(AnimRefF32 {
18456                raw: core::ptr::NonNull::new_unchecked(
18457                    ffi::whiteout_m3_M3Camera_get_bokehMaxCoCDiameter(self.raw.as_ptr()),
18458                ),
18459            })
18460        }
18461    }
18462
18463    pub fn bokeh_max_co_c_diameter_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
18464        // SAFETY: as above; `&mut self` guarantees exclusivity.
18465        unsafe {
18466            crate::support::RefMut::new(AnimRefF32 {
18467                raw: core::ptr::NonNull::new_unchecked(
18468                    ffi::whiteout_m3_M3Camera_get_bokehMaxCoCDiameter(self.raw.as_ptr()),
18469                ),
18470            })
18471        }
18472    }
18473}
18474
18475impl Default for Camera {
18476    fn default() -> Self {
18477        Self::new()
18478    }
18479}
18480
18481/// MODL — Model root chunk (v23–v30, 784–868 bytes)
18482///
18483/// The root of all model data. Contains `Ref<T>` fields pointing to every sub-chunk in the file: skeleton, mesh, materials, particles, physics, etc. The preamble (bytes 0x000–0x0E3) is identical across all versions; version-dependent material and physics references follow at 0x0E4+.
18484///
18485/// Version history: - v23 (784 bytes): Base release layout - v24 (+ikCCD): 796 bytes - v25 (+volumeNoiseMaterials): 808 bytes - v26 (+stbMaterials): 820 bytes - v28 (+reflectionMaterials, +clothPhysics): 844 bytes - v29 (+lensFlareMaterials): 856 bytes - v30 (+materialAddData): 868 bytes
18486pub struct Model {
18487    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3Model>,
18488}
18489
18490impl Drop for Model {
18491    fn drop(&mut self) {
18492        // SAFETY: `raw` came from a native constructor and Drop runs once.
18493        unsafe { ffi::whiteout_m3_M3Model_delete(self.raw.as_ptr()) }
18494    }
18495}
18496
18497impl Model {
18498    /// # Safety
18499    /// `raw` must be a live handle this value takes ownership of.
18500    #[allow(dead_code)] // used by whichever methods return this type
18501    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3Model) -> Option<Self> {
18502        core::ptr::NonNull::new(raw).map(|raw| Model { raw })
18503    }
18504}
18505
18506// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
18507// is deliberately NOT implemented — the C++ types make no documented
18508// guarantee about concurrent use, and claiming one we haven't verified
18509// would be unsound. See `@bind thread_safe` in the plan.
18510unsafe impl Send for Model {}
18511
18512impl core::fmt::Debug for Model {
18513    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
18514        f.debug_struct("Model").finish_non_exhaustive()
18515    }
18516}
18517
18518impl Model {
18519    /// # Panics
18520    /// Panics if the native allocation fails.
18521    pub fn new() -> Self {
18522        // SAFETY: the native constructor returns a live handle; a null here
18523        // means the library is unusable.
18524        unsafe {
18525            let raw = ffi::whiteout_m3_M3Model_new();
18526            Self::from_raw(raw).expect("native Model allocation failed")
18527        }
18528    }
18529
18530    /// Model file path (`Ref<CHAR>`)
18531    pub fn name(&self) -> String {
18532        // SAFETY: the native side hands over an owned CString.
18533        unsafe { crate::support::take_string(ffi::whiteout_m3_M3Model_get_name(self.raw.as_ptr())) }
18534    }
18535
18536    pub fn set_name(&mut self, value: &str) {
18537        let value = std::ffi::CString::new(value).unwrap_or_default();
18538        // SAFETY: the pointer outlives the call.
18539        unsafe { ffi::whiteout_m3_M3Model_set_name(self.raw.as_ptr(), value.as_ptr()) }
18540    }
18541
18542    /// Model flags (tangents, FOW, instancing, etc.)
18543    pub fn flags(&self) -> ModelFlag {
18544        // SAFETY: scalar read; a flag set accepts any bits.
18545        ModelFlag(unsafe { ffi::whiteout_m3_M3Model_get_flags(self.raw.as_ptr()) })
18546    }
18547
18548    pub fn set_flags(&mut self, value: ModelFlag) {
18549        // SAFETY: scalar write through a live handle.
18550        unsafe { ffi::whiteout_m3_M3Model_set_flags(self.raw.as_ptr(), value.0) }
18551    }
18552
18553    /// Animation sequences (SEQS)
18554    pub fn sequences_len(&self) -> usize {
18555        // SAFETY: scalar read through a live handle.
18556        unsafe { ffi::whiteout_m3_M3Model_get_sequences_count(self.raw.as_ptr()) }
18557    }
18558
18559    /// Borrows element `index` in place. `None` when out of range.
18560    pub fn sequences(&self, index: usize) -> Option<crate::support::Ref<'_, Sequence>> {
18561        if index >= self.sequences_len() {
18562            return None;
18563        }
18564        // SAFETY: index checked above; the pointer is interior to `self`.
18565        unsafe {
18566            Some(crate::support::Ref::new(Sequence {
18567                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Model_get_sequences_at(
18568                    self.raw.as_ptr(),
18569                    index,
18570                )),
18571            }))
18572        }
18573    }
18574
18575    pub fn sequences_mut(&mut self, index: usize) -> Option<crate::support::RefMut<'_, Sequence>> {
18576        if index >= self.sequences_len() {
18577            return None;
18578        }
18579        // SAFETY: as above; `&mut self` guarantees exclusivity.
18580        unsafe {
18581            Some(crate::support::RefMut::new(Sequence {
18582                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Model_get_sequences_at(
18583                    self.raw.as_ptr(),
18584                    index,
18585                )),
18586            }))
18587        }
18588    }
18589
18590    /// Iterate the elements, borrowing each in turn.
18591    pub fn sequences_iter(
18592        &self,
18593    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, Sequence>> {
18594        (0..self.sequences_len()).map(move |i| self.sequences(i).expect("index below len"))
18595    }
18596
18597    pub fn resize_sequences(&mut self, count: usize) {
18598        // SAFETY: exclusive access, so no borrow is outstanding.
18599        unsafe { ffi::whiteout_m3_M3Model_resize_sequences(self.raw.as_ptr(), count) }
18600    }
18601
18602    /// Sub-track containers (STC_) with keyframe refs
18603    pub fn sub_track_collections_len(&self) -> usize {
18604        // SAFETY: scalar read through a live handle.
18605        unsafe { ffi::whiteout_m3_M3Model_get_subTrackCollections_count(self.raw.as_ptr()) }
18606    }
18607
18608    /// Borrows element `index` in place. `None` when out of range.
18609    pub fn sub_track_collections(
18610        &self,
18611        index: usize,
18612    ) -> Option<crate::support::Ref<'_, SubTrackContainer>> {
18613        if index >= self.sub_track_collections_len() {
18614            return None;
18615        }
18616        // SAFETY: index checked above; the pointer is interior to `self`.
18617        unsafe {
18618            Some(crate::support::Ref::new(SubTrackContainer {
18619                raw: core::ptr::NonNull::new_unchecked(
18620                    ffi::whiteout_m3_M3Model_get_subTrackCollections_at(self.raw.as_ptr(), index),
18621                ),
18622            }))
18623        }
18624    }
18625
18626    pub fn sub_track_collections_mut(
18627        &mut self,
18628        index: usize,
18629    ) -> Option<crate::support::RefMut<'_, SubTrackContainer>> {
18630        if index >= self.sub_track_collections_len() {
18631            return None;
18632        }
18633        // SAFETY: as above; `&mut self` guarantees exclusivity.
18634        unsafe {
18635            Some(crate::support::RefMut::new(SubTrackContainer {
18636                raw: core::ptr::NonNull::new_unchecked(
18637                    ffi::whiteout_m3_M3Model_get_subTrackCollections_at(self.raw.as_ptr(), index),
18638                ),
18639            }))
18640        }
18641    }
18642
18643    /// Iterate the elements, borrowing each in turn.
18644    pub fn sub_track_collections_iter(
18645        &self,
18646    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, SubTrackContainer>> {
18647        (0..self.sub_track_collections_len())
18648            .map(move |i| self.sub_track_collections(i).expect("index below len"))
18649    }
18650
18651    pub fn resize_sub_track_collections(&mut self, count: usize) {
18652        // SAFETY: exclusive access, so no borrow is outstanding.
18653        unsafe { ffi::whiteout_m3_M3Model_resize_subTrackCollections(self.raw.as_ptr(), count) }
18654    }
18655
18656    /// Animation groups (STG_)
18657    pub fn animation_groups_len(&self) -> usize {
18658        // SAFETY: scalar read through a live handle.
18659        unsafe { ffi::whiteout_m3_M3Model_get_animationGroups_count(self.raw.as_ptr()) }
18660    }
18661
18662    /// Borrows element `index` in place. `None` when out of range.
18663    pub fn animation_groups(
18664        &self,
18665        index: usize,
18666    ) -> Option<crate::support::Ref<'_, AnimationGroup>> {
18667        if index >= self.animation_groups_len() {
18668            return None;
18669        }
18670        // SAFETY: index checked above; the pointer is interior to `self`.
18671        unsafe {
18672            Some(crate::support::Ref::new(AnimationGroup {
18673                raw: core::ptr::NonNull::new_unchecked(
18674                    ffi::whiteout_m3_M3Model_get_animationGroups_at(self.raw.as_ptr(), index),
18675                ),
18676            }))
18677        }
18678    }
18679
18680    pub fn animation_groups_mut(
18681        &mut self,
18682        index: usize,
18683    ) -> Option<crate::support::RefMut<'_, AnimationGroup>> {
18684        if index >= self.animation_groups_len() {
18685            return None;
18686        }
18687        // SAFETY: as above; `&mut self` guarantees exclusivity.
18688        unsafe {
18689            Some(crate::support::RefMut::new(AnimationGroup {
18690                raw: core::ptr::NonNull::new_unchecked(
18691                    ffi::whiteout_m3_M3Model_get_animationGroups_at(self.raw.as_ptr(), index),
18692                ),
18693            }))
18694        }
18695    }
18696
18697    /// Iterate the elements, borrowing each in turn.
18698    pub fn animation_groups_iter(
18699        &self,
18700    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, AnimationGroup>> {
18701        (0..self.animation_groups_len())
18702            .map(move |i| self.animation_groups(i).expect("index below len"))
18703    }
18704
18705    pub fn resize_animation_groups(&mut self, count: usize) {
18706        // SAFETY: exclusive access, so no borrow is outstanding.
18707        unsafe { ffi::whiteout_m3_M3Model_resize_animationGroups(self.raw.as_ptr(), count) }
18708    }
18709
18710    /// Bone animation sets (BSET, always null)
18711    pub fn bone_animation_sets_len(&self) -> usize {
18712        // SAFETY: scalar read through a live handle.
18713        unsafe { ffi::whiteout_m3_M3Model_get_boneAnimationSets_count(self.raw.as_ptr()) }
18714    }
18715
18716    /// Borrows element `index` in place. `None` when out of range.
18717    pub fn bone_animation_sets(
18718        &self,
18719        index: usize,
18720    ) -> Option<crate::support::Ref<'_, BoneAnimationSet>> {
18721        if index >= self.bone_animation_sets_len() {
18722            return None;
18723        }
18724        // SAFETY: index checked above; the pointer is interior to `self`.
18725        unsafe {
18726            Some(crate::support::Ref::new(BoneAnimationSet {
18727                raw: core::ptr::NonNull::new_unchecked(
18728                    ffi::whiteout_m3_M3Model_get_boneAnimationSets_at(self.raw.as_ptr(), index),
18729                ),
18730            }))
18731        }
18732    }
18733
18734    pub fn bone_animation_sets_mut(
18735        &mut self,
18736        index: usize,
18737    ) -> Option<crate::support::RefMut<'_, BoneAnimationSet>> {
18738        if index >= self.bone_animation_sets_len() {
18739            return None;
18740        }
18741        // SAFETY: as above; `&mut self` guarantees exclusivity.
18742        unsafe {
18743            Some(crate::support::RefMut::new(BoneAnimationSet {
18744                raw: core::ptr::NonNull::new_unchecked(
18745                    ffi::whiteout_m3_M3Model_get_boneAnimationSets_at(self.raw.as_ptr(), index),
18746                ),
18747            }))
18748        }
18749    }
18750
18751    /// Iterate the elements, borrowing each in turn.
18752    pub fn bone_animation_sets_iter(
18753        &self,
18754    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, BoneAnimationSet>> {
18755        (0..self.bone_animation_sets_len())
18756            .map(move |i| self.bone_animation_sets(i).expect("index below len"))
18757    }
18758
18759    pub fn resize_bone_animation_sets(&mut self, count: usize) {
18760        // SAFETY: exclusive access, so no borrow is outstanding.
18761        unsafe { ffi::whiteout_m3_M3Model_resize_boneAnimationSets(self.raw.as_ptr(), count) }
18762    }
18763
18764    /// Always 0
18765    pub fn animation_split_count(&self) -> u32 {
18766        // SAFETY: plain scalar read through a live handle.
18767        unsafe { ffi::whiteout_m3_M3Model_get_animationSplitCount(self.raw.as_ptr()) }
18768    }
18769
18770    pub fn set_animation_split_count(&mut self, value: u32) {
18771        // SAFETY: plain scalar write through a live handle.
18772        unsafe { ffi::whiteout_m3_M3Model_set_animationSplitCount(self.raw.as_ptr(), value) }
18773    }
18774
18775    /// Animation states (STS_)
18776    pub fn animation_states_len(&self) -> usize {
18777        // SAFETY: scalar read through a live handle.
18778        unsafe { ffi::whiteout_m3_M3Model_get_animationStates_count(self.raw.as_ptr()) }
18779    }
18780
18781    /// Borrows element `index` in place. `None` when out of range.
18782    pub fn animation_states(
18783        &self,
18784        index: usize,
18785    ) -> Option<crate::support::Ref<'_, AnimationState>> {
18786        if index >= self.animation_states_len() {
18787            return None;
18788        }
18789        // SAFETY: index checked above; the pointer is interior to `self`.
18790        unsafe {
18791            Some(crate::support::Ref::new(AnimationState {
18792                raw: core::ptr::NonNull::new_unchecked(
18793                    ffi::whiteout_m3_M3Model_get_animationStates_at(self.raw.as_ptr(), index),
18794                ),
18795            }))
18796        }
18797    }
18798
18799    pub fn animation_states_mut(
18800        &mut self,
18801        index: usize,
18802    ) -> Option<crate::support::RefMut<'_, AnimationState>> {
18803        if index >= self.animation_states_len() {
18804            return None;
18805        }
18806        // SAFETY: as above; `&mut self` guarantees exclusivity.
18807        unsafe {
18808            Some(crate::support::RefMut::new(AnimationState {
18809                raw: core::ptr::NonNull::new_unchecked(
18810                    ffi::whiteout_m3_M3Model_get_animationStates_at(self.raw.as_ptr(), index),
18811                ),
18812            }))
18813        }
18814    }
18815
18816    /// Iterate the elements, borrowing each in turn.
18817    pub fn animation_states_iter(
18818        &self,
18819    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, AnimationState>> {
18820        (0..self.animation_states_len())
18821            .map(move |i| self.animation_states(i).expect("index below len"))
18822    }
18823
18824    pub fn resize_animation_states(&mut self, count: usize) {
18825        // SAFETY: exclusive access, so no borrow is outstanding.
18826        unsafe { ffi::whiteout_m3_M3Model_resize_animationStates(self.raw.as_ptr(), count) }
18827    }
18828
18829    /// Skeleton bones (BONE)
18830    pub fn bones_len(&self) -> usize {
18831        // SAFETY: scalar read through a live handle.
18832        unsafe { ffi::whiteout_m3_M3Model_get_bones_count(self.raw.as_ptr()) }
18833    }
18834
18835    /// Borrows element `index` in place. `None` when out of range.
18836    pub fn bones(&self, index: usize) -> Option<crate::support::Ref<'_, Bone>> {
18837        if index >= self.bones_len() {
18838            return None;
18839        }
18840        // SAFETY: index checked above; the pointer is interior to `self`.
18841        unsafe {
18842            Some(crate::support::Ref::new(Bone {
18843                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Model_get_bones_at(
18844                    self.raw.as_ptr(),
18845                    index,
18846                )),
18847            }))
18848        }
18849    }
18850
18851    pub fn bones_mut(&mut self, index: usize) -> Option<crate::support::RefMut<'_, Bone>> {
18852        if index >= self.bones_len() {
18853            return None;
18854        }
18855        // SAFETY: as above; `&mut self` guarantees exclusivity.
18856        unsafe {
18857            Some(crate::support::RefMut::new(Bone {
18858                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Model_get_bones_at(
18859                    self.raw.as_ptr(),
18860                    index,
18861                )),
18862            }))
18863        }
18864    }
18865
18866    /// Iterate the elements, borrowing each in turn.
18867    pub fn bones_iter(&self) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, Bone>> {
18868        (0..self.bones_len()).map(move |i| self.bones(i).expect("index below len"))
18869    }
18870
18871    pub fn resize_bones(&mut self, count: usize) {
18872        // SAFETY: exclusive access, so no borrow is outstanding.
18873        unsafe { ffi::whiteout_m3_M3Model_resize_bones(self.raw.as_ptr(), count) }
18874    }
18875
18876    /// Number of bones affecting skin
18877    pub fn skin_bone_count(&self) -> u32 {
18878        // SAFETY: plain scalar read through a live handle.
18879        unsafe { ffi::whiteout_m3_M3Model_get_skinBoneCount(self.raw.as_ptr()) }
18880    }
18881
18882    pub fn set_skin_bone_count(&mut self, value: u32) {
18883        // SAFETY: plain scalar write through a live handle.
18884        unsafe { ffi::whiteout_m3_M3Model_set_skinBoneCount(self.raw.as_ptr(), value) }
18885    }
18886
18887    /// Mesh divisions (DIV_: faces, regions, batches)
18888    pub fn divisions_len(&self) -> usize {
18889        // SAFETY: scalar read through a live handle.
18890        unsafe { ffi::whiteout_m3_M3Model_get_divisions_count(self.raw.as_ptr()) }
18891    }
18892
18893    /// Borrows element `index` in place. `None` when out of range.
18894    pub fn divisions(&self, index: usize) -> Option<crate::support::Ref<'_, MeshDivision>> {
18895        if index >= self.divisions_len() {
18896            return None;
18897        }
18898        // SAFETY: index checked above; the pointer is interior to `self`.
18899        unsafe {
18900            Some(crate::support::Ref::new(MeshDivision {
18901                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Model_get_divisions_at(
18902                    self.raw.as_ptr(),
18903                    index,
18904                )),
18905            }))
18906        }
18907    }
18908
18909    pub fn divisions_mut(
18910        &mut self,
18911        index: usize,
18912    ) -> Option<crate::support::RefMut<'_, MeshDivision>> {
18913        if index >= self.divisions_len() {
18914            return None;
18915        }
18916        // SAFETY: as above; `&mut self` guarantees exclusivity.
18917        unsafe {
18918            Some(crate::support::RefMut::new(MeshDivision {
18919                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Model_get_divisions_at(
18920                    self.raw.as_ptr(),
18921                    index,
18922                )),
18923            }))
18924        }
18925    }
18926
18927    /// Iterate the elements, borrowing each in turn.
18928    pub fn divisions_iter(
18929        &self,
18930    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, MeshDivision>> {
18931        (0..self.divisions_len()).map(move |i| self.divisions(i).expect("index below len"))
18932    }
18933
18934    pub fn resize_divisions(&mut self, count: usize) {
18935        // SAFETY: exclusive access, so no borrow is outstanding.
18936        unsafe { ffi::whiteout_m3_M3Model_resize_divisions(self.raw.as_ptr(), count) }
18937    }
18938
18939    /// Bone index remap table (U16_)
18940    /// Zero-copy view of the underlying `std::vector`.
18941    pub fn bone_lookup(&self) -> &[u16] {
18942        // SAFETY: `_data`/`_count` describe one contiguous C++
18943        // allocation, borrowed for as long as `self` is.
18944        unsafe {
18945            let n = ffi::whiteout_m3_M3Model_get_boneLookup_count(self.raw.as_ptr());
18946            let p = ffi::whiteout_m3_M3Model_get_boneLookup_data(self.raw.as_ptr());
18947            if p.is_null() || n == 0 {
18948                &[]
18949            } else {
18950                core::slice::from_raw_parts(p, n)
18951            }
18952        }
18953    }
18954
18955    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
18956    pub fn bone_lookup_mut(&mut self) -> &mut [u16] {
18957        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
18958        unsafe {
18959            let n = ffi::whiteout_m3_M3Model_get_boneLookup_count(self.raw.as_ptr());
18960            let p = ffi::whiteout_m3_M3Model_get_boneLookup_data(self.raw.as_ptr()) as *mut u16;
18961            if p.is_null() || n == 0 {
18962                &mut []
18963            } else {
18964                core::slice::from_raw_parts_mut(p, n)
18965            }
18966        }
18967    }
18968
18969    pub fn set_bone_lookup(&mut self, values: &[u16]) {
18970        // SAFETY: the native side copies `values` before returning.
18971        unsafe {
18972            ffi::whiteout_m3_M3Model_assign_boneLookup(
18973                self.raw.as_ptr(),
18974                values.as_ptr() as *const _,
18975                values.len(),
18976            )
18977        }
18978    }
18979
18980    pub fn resize_bone_lookup(&mut self, count: usize) {
18981        // SAFETY: reallocation is safe here precisely because
18982        // `&mut self` means no slice borrow is outstanding.
18983        unsafe { ffi::whiteout_m3_M3Model_resize_boneLookup(self.raw.as_ptr(), count) }
18984    }
18985
18986    /// Model bounding volume
18987    /// Borrows the field in place — no copy, no allocation.
18988    pub fn bounds(&self) -> crate::support::Ref<'_, Extent> {
18989        // SAFETY: an interior pointer into `self`, valid for this
18990        // borrow and never freed by the `Ref`.
18991        unsafe {
18992            crate::support::Ref::new(Extent {
18993                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Model_get_bounds(
18994                    self.raw.as_ptr(),
18995                )),
18996            })
18997        }
18998    }
18999
19000    pub fn bounds_mut(&mut self) -> crate::support::RefMut<'_, Extent> {
19001        // SAFETY: as above; `&mut self` guarantees exclusivity.
19002        unsafe {
19003            crate::support::RefMut::new(Extent {
19004                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Model_get_bounds(
19005                    self.raw.as_ptr(),
19006                )),
19007            })
19008        }
19009    }
19010
19011    /// Collision bounding volume
19012    /// Borrows the field in place — no copy, no allocation.
19013    pub fn collision_bounds(&self) -> crate::support::Ref<'_, Extent> {
19014        // SAFETY: an interior pointer into `self`, valid for this
19015        // borrow and never freed by the `Ref`.
19016        unsafe {
19017            crate::support::Ref::new(Extent {
19018                raw: core::ptr::NonNull::new_unchecked(
19019                    ffi::whiteout_m3_M3Model_get_collisionBounds(self.raw.as_ptr()),
19020                ),
19021            })
19022        }
19023    }
19024
19025    pub fn collision_bounds_mut(&mut self) -> crate::support::RefMut<'_, Extent> {
19026        // SAFETY: as above; `&mut self` guarantees exclusivity.
19027        unsafe {
19028            crate::support::RefMut::new(Extent {
19029                raw: core::ptr::NonNull::new_unchecked(
19030                    ffi::whiteout_m3_M3Model_get_collisionBounds(self.raw.as_ptr()),
19031                ),
19032            })
19033        }
19034    }
19035
19036    /// Collision triangle indices (U16_)
19037    /// Zero-copy view of the underlying `std::vector`.
19038    pub fn collision_faces(&self) -> &[u16] {
19039        // SAFETY: `_data`/`_count` describe one contiguous C++
19040        // allocation, borrowed for as long as `self` is.
19041        unsafe {
19042            let n = ffi::whiteout_m3_M3Model_get_collisionFaces_count(self.raw.as_ptr());
19043            let p = ffi::whiteout_m3_M3Model_get_collisionFaces_data(self.raw.as_ptr());
19044            if p.is_null() || n == 0 {
19045                &[]
19046            } else {
19047                core::slice::from_raw_parts(p, n)
19048            }
19049        }
19050    }
19051
19052    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
19053    pub fn collision_faces_mut(&mut self) -> &mut [u16] {
19054        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
19055        unsafe {
19056            let n = ffi::whiteout_m3_M3Model_get_collisionFaces_count(self.raw.as_ptr());
19057            let p = ffi::whiteout_m3_M3Model_get_collisionFaces_data(self.raw.as_ptr()) as *mut u16;
19058            if p.is_null() || n == 0 {
19059                &mut []
19060            } else {
19061                core::slice::from_raw_parts_mut(p, n)
19062            }
19063        }
19064    }
19065
19066    pub fn set_collision_faces(&mut self, values: &[u16]) {
19067        // SAFETY: the native side copies `values` before returning.
19068        unsafe {
19069            ffi::whiteout_m3_M3Model_assign_collisionFaces(
19070                self.raw.as_ptr(),
19071                values.as_ptr() as *const _,
19072                values.len(),
19073            )
19074        }
19075    }
19076
19077    pub fn resize_collision_faces(&mut self, count: usize) {
19078        // SAFETY: reallocation is safe here precisely because
19079        // `&mut self` means no slice borrow is outstanding.
19080        unsafe { ffi::whiteout_m3_M3Model_resize_collisionFaces(self.raw.as_ptr(), count) }
19081    }
19082
19083    /// Collision vertex positions (VEC3)
19084    /// Zero-copy view of the underlying `std::vector`.
19085    pub fn collision_verts(&self) -> &[crate::math::Vector3f] {
19086        // SAFETY: `_data`/`_count` describe one contiguous C++
19087        // allocation, borrowed for as long as `self` is.
19088        unsafe {
19089            let n = ffi::whiteout_m3_M3Model_get_collisionVerts_count(self.raw.as_ptr());
19090            let p = ffi::whiteout_m3_M3Model_get_collisionVerts_data(self.raw.as_ptr())
19091                as *const crate::math::Vector3f;
19092            if p.is_null() || n == 0 {
19093                &[]
19094            } else {
19095                core::slice::from_raw_parts(p, n)
19096            }
19097        }
19098    }
19099
19100    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
19101    pub fn collision_verts_mut(&mut self) -> &mut [crate::math::Vector3f] {
19102        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
19103        unsafe {
19104            let n = ffi::whiteout_m3_M3Model_get_collisionVerts_count(self.raw.as_ptr());
19105            let p = ffi::whiteout_m3_M3Model_get_collisionVerts_data(self.raw.as_ptr())
19106                as *const crate::math::Vector3f as *mut crate::math::Vector3f;
19107            if p.is_null() || n == 0 {
19108                &mut []
19109            } else {
19110                core::slice::from_raw_parts_mut(p, n)
19111            }
19112        }
19113    }
19114
19115    pub fn set_collision_verts(&mut self, values: &[crate::math::Vector3f]) {
19116        // SAFETY: the native side copies `values` before returning.
19117        unsafe {
19118            ffi::whiteout_m3_M3Model_assign_collisionVerts(
19119                self.raw.as_ptr(),
19120                values.as_ptr() as *const _,
19121                values.len(),
19122            )
19123        }
19124    }
19125
19126    pub fn resize_collision_verts(&mut self, count: usize) {
19127        // SAFETY: reallocation is safe here precisely because
19128        // `&mut self` means no slice borrow is outstanding.
19129        unsafe { ffi::whiteout_m3_M3Model_resize_collisionVerts(self.raw.as_ptr(), count) }
19130    }
19131
19132    /// Collision face normals (VEC3)
19133    /// Zero-copy view of the underlying `std::vector`.
19134    pub fn collision_normals(&self) -> &[crate::math::Vector3f] {
19135        // SAFETY: `_data`/`_count` describe one contiguous C++
19136        // allocation, borrowed for as long as `self` is.
19137        unsafe {
19138            let n = ffi::whiteout_m3_M3Model_get_collisionNormals_count(self.raw.as_ptr());
19139            let p = ffi::whiteout_m3_M3Model_get_collisionNormals_data(self.raw.as_ptr())
19140                as *const crate::math::Vector3f;
19141            if p.is_null() || n == 0 {
19142                &[]
19143            } else {
19144                core::slice::from_raw_parts(p, n)
19145            }
19146        }
19147    }
19148
19149    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
19150    pub fn collision_normals_mut(&mut self) -> &mut [crate::math::Vector3f] {
19151        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
19152        unsafe {
19153            let n = ffi::whiteout_m3_M3Model_get_collisionNormals_count(self.raw.as_ptr());
19154            let p = ffi::whiteout_m3_M3Model_get_collisionNormals_data(self.raw.as_ptr())
19155                as *const crate::math::Vector3f as *mut crate::math::Vector3f;
19156            if p.is_null() || n == 0 {
19157                &mut []
19158            } else {
19159                core::slice::from_raw_parts_mut(p, n)
19160            }
19161        }
19162    }
19163
19164    pub fn set_collision_normals(&mut self, values: &[crate::math::Vector3f]) {
19165        // SAFETY: the native side copies `values` before returning.
19166        unsafe {
19167            ffi::whiteout_m3_M3Model_assign_collisionNormals(
19168                self.raw.as_ptr(),
19169                values.as_ptr() as *const _,
19170                values.len(),
19171            )
19172        }
19173    }
19174
19175    pub fn resize_collision_normals(&mut self, count: usize) {
19176        // SAFETY: reallocation is safe here precisely because
19177        // `&mut self` means no slice borrow is outstanding.
19178        unsafe { ffi::whiteout_m3_M3Model_resize_collisionNormals(self.raw.as_ptr(), count) }
19179    }
19180
19181    /// Named bone locations (ATT_)
19182    pub fn attachment_points_len(&self) -> usize {
19183        // SAFETY: scalar read through a live handle.
19184        unsafe { ffi::whiteout_m3_M3Model_get_attachmentPoints_count(self.raw.as_ptr()) }
19185    }
19186
19187    /// Borrows element `index` in place. `None` when out of range.
19188    pub fn attachment_points(
19189        &self,
19190        index: usize,
19191    ) -> Option<crate::support::Ref<'_, AttachmentPoint>> {
19192        if index >= self.attachment_points_len() {
19193            return None;
19194        }
19195        // SAFETY: index checked above; the pointer is interior to `self`.
19196        unsafe {
19197            Some(crate::support::Ref::new(AttachmentPoint {
19198                raw: core::ptr::NonNull::new_unchecked(
19199                    ffi::whiteout_m3_M3Model_get_attachmentPoints_at(self.raw.as_ptr(), index),
19200                ),
19201            }))
19202        }
19203    }
19204
19205    pub fn attachment_points_mut(
19206        &mut self,
19207        index: usize,
19208    ) -> Option<crate::support::RefMut<'_, AttachmentPoint>> {
19209        if index >= self.attachment_points_len() {
19210            return None;
19211        }
19212        // SAFETY: as above; `&mut self` guarantees exclusivity.
19213        unsafe {
19214            Some(crate::support::RefMut::new(AttachmentPoint {
19215                raw: core::ptr::NonNull::new_unchecked(
19216                    ffi::whiteout_m3_M3Model_get_attachmentPoints_at(self.raw.as_ptr(), index),
19217                ),
19218            }))
19219        }
19220    }
19221
19222    /// Iterate the elements, borrowing each in turn.
19223    pub fn attachment_points_iter(
19224        &self,
19225    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, AttachmentPoint>> {
19226        (0..self.attachment_points_len())
19227            .map(move |i| self.attachment_points(i).expect("index below len"))
19228    }
19229
19230    pub fn resize_attachment_points(&mut self, count: usize) {
19231        // SAFETY: exclusive access, so no borrow is outstanding.
19232        unsafe { ffi::whiteout_m3_M3Model_resize_attachmentPoints(self.raw.as_ptr(), count) }
19233    }
19234
19235    /// Attachment point addon indices (U16_)
19236    /// Zero-copy view of the underlying `std::vector`.
19237    pub fn attachment_point_addons(&self) -> &[u16] {
19238        // SAFETY: `_data`/`_count` describe one contiguous C++
19239        // allocation, borrowed for as long as `self` is.
19240        unsafe {
19241            let n = ffi::whiteout_m3_M3Model_get_attachmentPointAddons_count(self.raw.as_ptr());
19242            let p = ffi::whiteout_m3_M3Model_get_attachmentPointAddons_data(self.raw.as_ptr());
19243            if p.is_null() || n == 0 {
19244                &[]
19245            } else {
19246                core::slice::from_raw_parts(p, n)
19247            }
19248        }
19249    }
19250
19251    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
19252    pub fn attachment_point_addons_mut(&mut self) -> &mut [u16] {
19253        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
19254        unsafe {
19255            let n = ffi::whiteout_m3_M3Model_get_attachmentPointAddons_count(self.raw.as_ptr());
19256            let p = ffi::whiteout_m3_M3Model_get_attachmentPointAddons_data(self.raw.as_ptr())
19257                as *mut u16;
19258            if p.is_null() || n == 0 {
19259                &mut []
19260            } else {
19261                core::slice::from_raw_parts_mut(p, n)
19262            }
19263        }
19264    }
19265
19266    pub fn set_attachment_point_addons(&mut self, values: &[u16]) {
19267        // SAFETY: the native side copies `values` before returning.
19268        unsafe {
19269            ffi::whiteout_m3_M3Model_assign_attachmentPointAddons(
19270                self.raw.as_ptr(),
19271                values.as_ptr() as *const _,
19272                values.len(),
19273            )
19274        }
19275    }
19276
19277    pub fn resize_attachment_point_addons(&mut self, count: usize) {
19278        // SAFETY: reallocation is safe here precisely because
19279        // `&mut self` means no slice borrow is outstanding.
19280        unsafe { ffi::whiteout_m3_M3Model_resize_attachmentPointAddons(self.raw.as_ptr(), count) }
19281    }
19282
19283    /// Lights (LITE)
19284    pub fn lights_len(&self) -> usize {
19285        // SAFETY: scalar read through a live handle.
19286        unsafe { ffi::whiteout_m3_M3Model_get_lights_count(self.raw.as_ptr()) }
19287    }
19288
19289    /// Borrows element `index` in place. `None` when out of range.
19290    pub fn lights(&self, index: usize) -> Option<crate::support::Ref<'_, Light>> {
19291        if index >= self.lights_len() {
19292            return None;
19293        }
19294        // SAFETY: index checked above; the pointer is interior to `self`.
19295        unsafe {
19296            Some(crate::support::Ref::new(Light {
19297                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Model_get_lights_at(
19298                    self.raw.as_ptr(),
19299                    index,
19300                )),
19301            }))
19302        }
19303    }
19304
19305    pub fn lights_mut(&mut self, index: usize) -> Option<crate::support::RefMut<'_, Light>> {
19306        if index >= self.lights_len() {
19307            return None;
19308        }
19309        // SAFETY: as above; `&mut self` guarantees exclusivity.
19310        unsafe {
19311            Some(crate::support::RefMut::new(Light {
19312                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Model_get_lights_at(
19313                    self.raw.as_ptr(),
19314                    index,
19315                )),
19316            }))
19317        }
19318    }
19319
19320    /// Iterate the elements, borrowing each in turn.
19321    pub fn lights_iter(&self) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, Light>> {
19322        (0..self.lights_len()).map(move |i| self.lights(i).expect("index below len"))
19323    }
19324
19325    pub fn resize_lights(&mut self, count: usize) {
19326        // SAFETY: exclusive access, so no borrow is outstanding.
19327        unsafe { ffi::whiteout_m3_M3Model_resize_lights(self.raw.as_ptr(), count) }
19328    }
19329
19330    /// Shadow boxes (SHBX)
19331    pub fn shadow_boxes_len(&self) -> usize {
19332        // SAFETY: scalar read through a live handle.
19333        unsafe { ffi::whiteout_m3_M3Model_get_shadowBoxes_count(self.raw.as_ptr()) }
19334    }
19335
19336    /// Borrows element `index` in place. `None` when out of range.
19337    pub fn shadow_boxes(&self, index: usize) -> Option<crate::support::Ref<'_, ShadowBox>> {
19338        if index >= self.shadow_boxes_len() {
19339            return None;
19340        }
19341        // SAFETY: index checked above; the pointer is interior to `self`.
19342        unsafe {
19343            Some(crate::support::Ref::new(ShadowBox {
19344                raw: core::ptr::NonNull::new_unchecked(
19345                    ffi::whiteout_m3_M3Model_get_shadowBoxes_at(self.raw.as_ptr(), index),
19346                ),
19347            }))
19348        }
19349    }
19350
19351    pub fn shadow_boxes_mut(
19352        &mut self,
19353        index: usize,
19354    ) -> Option<crate::support::RefMut<'_, ShadowBox>> {
19355        if index >= self.shadow_boxes_len() {
19356            return None;
19357        }
19358        // SAFETY: as above; `&mut self` guarantees exclusivity.
19359        unsafe {
19360            Some(crate::support::RefMut::new(ShadowBox {
19361                raw: core::ptr::NonNull::new_unchecked(
19362                    ffi::whiteout_m3_M3Model_get_shadowBoxes_at(self.raw.as_ptr(), index),
19363                ),
19364            }))
19365        }
19366    }
19367
19368    /// Iterate the elements, borrowing each in turn.
19369    pub fn shadow_boxes_iter(
19370        &self,
19371    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, ShadowBox>> {
19372        (0..self.shadow_boxes_len()).map(move |i| self.shadow_boxes(i).expect("index below len"))
19373    }
19374
19375    pub fn resize_shadow_boxes(&mut self, count: usize) {
19376        // SAFETY: exclusive access, so no borrow is outstanding.
19377        unsafe { ffi::whiteout_m3_M3Model_resize_shadowBoxes(self.raw.as_ptr(), count) }
19378    }
19379
19380    /// Cameras (CAM_)
19381    pub fn cameras_len(&self) -> usize {
19382        // SAFETY: scalar read through a live handle.
19383        unsafe { ffi::whiteout_m3_M3Model_get_cameras_count(self.raw.as_ptr()) }
19384    }
19385
19386    /// Borrows element `index` in place. `None` when out of range.
19387    pub fn cameras(&self, index: usize) -> Option<crate::support::Ref<'_, Camera>> {
19388        if index >= self.cameras_len() {
19389            return None;
19390        }
19391        // SAFETY: index checked above; the pointer is interior to `self`.
19392        unsafe {
19393            Some(crate::support::Ref::new(Camera {
19394                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Model_get_cameras_at(
19395                    self.raw.as_ptr(),
19396                    index,
19397                )),
19398            }))
19399        }
19400    }
19401
19402    pub fn cameras_mut(&mut self, index: usize) -> Option<crate::support::RefMut<'_, Camera>> {
19403        if index >= self.cameras_len() {
19404            return None;
19405        }
19406        // SAFETY: as above; `&mut self` guarantees exclusivity.
19407        unsafe {
19408            Some(crate::support::RefMut::new(Camera {
19409                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Model_get_cameras_at(
19410                    self.raw.as_ptr(),
19411                    index,
19412                )),
19413            }))
19414        }
19415    }
19416
19417    /// Iterate the elements, borrowing each in turn.
19418    pub fn cameras_iter(&self) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, Camera>> {
19419        (0..self.cameras_len()).map(move |i| self.cameras(i).expect("index below len"))
19420    }
19421
19422    pub fn resize_cameras(&mut self, count: usize) {
19423        // SAFETY: exclusive access, so no borrow is outstanding.
19424        unsafe { ffi::whiteout_m3_M3Model_resize_cameras(self.raw.as_ptr(), count) }
19425    }
19426
19427    /// Camera addon indices (U16_)
19428    /// Zero-copy view of the underlying `std::vector`.
19429    pub fn cameras_addons(&self) -> &[u16] {
19430        // SAFETY: `_data`/`_count` describe one contiguous C++
19431        // allocation, borrowed for as long as `self` is.
19432        unsafe {
19433            let n = ffi::whiteout_m3_M3Model_get_camerasAddons_count(self.raw.as_ptr());
19434            let p = ffi::whiteout_m3_M3Model_get_camerasAddons_data(self.raw.as_ptr());
19435            if p.is_null() || n == 0 {
19436                &[]
19437            } else {
19438                core::slice::from_raw_parts(p, n)
19439            }
19440        }
19441    }
19442
19443    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
19444    pub fn cameras_addons_mut(&mut self) -> &mut [u16] {
19445        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
19446        unsafe {
19447            let n = ffi::whiteout_m3_M3Model_get_camerasAddons_count(self.raw.as_ptr());
19448            let p = ffi::whiteout_m3_M3Model_get_camerasAddons_data(self.raw.as_ptr()) as *mut u16;
19449            if p.is_null() || n == 0 {
19450                &mut []
19451            } else {
19452                core::slice::from_raw_parts_mut(p, n)
19453            }
19454        }
19455    }
19456
19457    pub fn set_cameras_addons(&mut self, values: &[u16]) {
19458        // SAFETY: the native side copies `values` before returning.
19459        unsafe {
19460            ffi::whiteout_m3_M3Model_assign_camerasAddons(
19461                self.raw.as_ptr(),
19462                values.as_ptr() as *const _,
19463                values.len(),
19464            )
19465        }
19466    }
19467
19468    pub fn resize_cameras_addons(&mut self, count: usize) {
19469        // SAFETY: reallocation is safe here precisely because
19470        // `&mut self` means no slice borrow is outstanding.
19471        unsafe { ffi::whiteout_m3_M3Model_resize_camerasAddons(self.raw.as_ptr(), count) }
19472    }
19473
19474    /// Material type+index maps (MATM)
19475    pub fn material_maps_len(&self) -> usize {
19476        // SAFETY: scalar read through a live handle.
19477        unsafe { ffi::whiteout_m3_M3Model_get_materialMaps_count(self.raw.as_ptr()) }
19478    }
19479
19480    /// Borrows element `index` in place. `None` when out of range.
19481    pub fn material_maps(&self, index: usize) -> Option<crate::support::Ref<'_, MaterialMap>> {
19482        if index >= self.material_maps_len() {
19483            return None;
19484        }
19485        // SAFETY: index checked above; the pointer is interior to `self`.
19486        unsafe {
19487            Some(crate::support::Ref::new(MaterialMap {
19488                raw: core::ptr::NonNull::new_unchecked(
19489                    ffi::whiteout_m3_M3Model_get_materialMaps_at(self.raw.as_ptr(), index),
19490                ),
19491            }))
19492        }
19493    }
19494
19495    pub fn material_maps_mut(
19496        &mut self,
19497        index: usize,
19498    ) -> Option<crate::support::RefMut<'_, MaterialMap>> {
19499        if index >= self.material_maps_len() {
19500            return None;
19501        }
19502        // SAFETY: as above; `&mut self` guarantees exclusivity.
19503        unsafe {
19504            Some(crate::support::RefMut::new(MaterialMap {
19505                raw: core::ptr::NonNull::new_unchecked(
19506                    ffi::whiteout_m3_M3Model_get_materialMaps_at(self.raw.as_ptr(), index),
19507                ),
19508            }))
19509        }
19510    }
19511
19512    /// Iterate the elements, borrowing each in turn.
19513    pub fn material_maps_iter(
19514        &self,
19515    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, MaterialMap>> {
19516        (0..self.material_maps_len()).map(move |i| self.material_maps(i).expect("index below len"))
19517    }
19518
19519    pub fn resize_material_maps(&mut self, count: usize) {
19520        // SAFETY: exclusive access, so no borrow is outstanding.
19521        unsafe { ffi::whiteout_m3_M3Model_resize_materialMaps(self.raw.as_ptr(), count) }
19522    }
19523
19524    /// Standard materials (MAT_)
19525    pub fn standard_materials_len(&self) -> usize {
19526        // SAFETY: scalar read through a live handle.
19527        unsafe { ffi::whiteout_m3_M3Model_get_standardMaterials_count(self.raw.as_ptr()) }
19528    }
19529
19530    /// Borrows element `index` in place. `None` when out of range.
19531    pub fn standard_materials(
19532        &self,
19533        index: usize,
19534    ) -> Option<crate::support::Ref<'_, StandardMaterial>> {
19535        if index >= self.standard_materials_len() {
19536            return None;
19537        }
19538        // SAFETY: index checked above; the pointer is interior to `self`.
19539        unsafe {
19540            Some(crate::support::Ref::new(StandardMaterial {
19541                raw: core::ptr::NonNull::new_unchecked(
19542                    ffi::whiteout_m3_M3Model_get_standardMaterials_at(self.raw.as_ptr(), index),
19543                ),
19544            }))
19545        }
19546    }
19547
19548    pub fn standard_materials_mut(
19549        &mut self,
19550        index: usize,
19551    ) -> Option<crate::support::RefMut<'_, StandardMaterial>> {
19552        if index >= self.standard_materials_len() {
19553            return None;
19554        }
19555        // SAFETY: as above; `&mut self` guarantees exclusivity.
19556        unsafe {
19557            Some(crate::support::RefMut::new(StandardMaterial {
19558                raw: core::ptr::NonNull::new_unchecked(
19559                    ffi::whiteout_m3_M3Model_get_standardMaterials_at(self.raw.as_ptr(), index),
19560                ),
19561            }))
19562        }
19563    }
19564
19565    /// Iterate the elements, borrowing each in turn.
19566    pub fn standard_materials_iter(
19567        &self,
19568    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, StandardMaterial>> {
19569        (0..self.standard_materials_len())
19570            .map(move |i| self.standard_materials(i).expect("index below len"))
19571    }
19572
19573    pub fn resize_standard_materials(&mut self, count: usize) {
19574        // SAFETY: exclusive access, so no borrow is outstanding.
19575        unsafe { ffi::whiteout_m3_M3Model_resize_standardMaterials(self.raw.as_ptr(), count) }
19576    }
19577
19578    /// Displacement materials (DIS_)
19579    pub fn displacement_materials_len(&self) -> usize {
19580        // SAFETY: scalar read through a live handle.
19581        unsafe { ffi::whiteout_m3_M3Model_get_displacementMaterials_count(self.raw.as_ptr()) }
19582    }
19583
19584    /// Borrows element `index` in place. `None` when out of range.
19585    pub fn displacement_materials(
19586        &self,
19587        index: usize,
19588    ) -> Option<crate::support::Ref<'_, DisplacementMaterial>> {
19589        if index >= self.displacement_materials_len() {
19590            return None;
19591        }
19592        // SAFETY: index checked above; the pointer is interior to `self`.
19593        unsafe {
19594            Some(crate::support::Ref::new(DisplacementMaterial {
19595                raw: core::ptr::NonNull::new_unchecked(
19596                    ffi::whiteout_m3_M3Model_get_displacementMaterials_at(self.raw.as_ptr(), index),
19597                ),
19598            }))
19599        }
19600    }
19601
19602    pub fn displacement_materials_mut(
19603        &mut self,
19604        index: usize,
19605    ) -> Option<crate::support::RefMut<'_, DisplacementMaterial>> {
19606        if index >= self.displacement_materials_len() {
19607            return None;
19608        }
19609        // SAFETY: as above; `&mut self` guarantees exclusivity.
19610        unsafe {
19611            Some(crate::support::RefMut::new(DisplacementMaterial {
19612                raw: core::ptr::NonNull::new_unchecked(
19613                    ffi::whiteout_m3_M3Model_get_displacementMaterials_at(self.raw.as_ptr(), index),
19614                ),
19615            }))
19616        }
19617    }
19618
19619    /// Iterate the elements, borrowing each in turn.
19620    pub fn displacement_materials_iter(
19621        &self,
19622    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, DisplacementMaterial>> {
19623        (0..self.displacement_materials_len())
19624            .map(move |i| self.displacement_materials(i).expect("index below len"))
19625    }
19626
19627    pub fn resize_displacement_materials(&mut self, count: usize) {
19628        // SAFETY: exclusive access, so no borrow is outstanding.
19629        unsafe { ffi::whiteout_m3_M3Model_resize_displacementMaterials(self.raw.as_ptr(), count) }
19630    }
19631
19632    /// Composite materials (CMP_)
19633    pub fn composite_materials_len(&self) -> usize {
19634        // SAFETY: scalar read through a live handle.
19635        unsafe { ffi::whiteout_m3_M3Model_get_compositeMaterials_count(self.raw.as_ptr()) }
19636    }
19637
19638    /// Borrows element `index` in place. `None` when out of range.
19639    pub fn composite_materials(
19640        &self,
19641        index: usize,
19642    ) -> Option<crate::support::Ref<'_, CompositeMaterial>> {
19643        if index >= self.composite_materials_len() {
19644            return None;
19645        }
19646        // SAFETY: index checked above; the pointer is interior to `self`.
19647        unsafe {
19648            Some(crate::support::Ref::new(CompositeMaterial {
19649                raw: core::ptr::NonNull::new_unchecked(
19650                    ffi::whiteout_m3_M3Model_get_compositeMaterials_at(self.raw.as_ptr(), index),
19651                ),
19652            }))
19653        }
19654    }
19655
19656    pub fn composite_materials_mut(
19657        &mut self,
19658        index: usize,
19659    ) -> Option<crate::support::RefMut<'_, CompositeMaterial>> {
19660        if index >= self.composite_materials_len() {
19661            return None;
19662        }
19663        // SAFETY: as above; `&mut self` guarantees exclusivity.
19664        unsafe {
19665            Some(crate::support::RefMut::new(CompositeMaterial {
19666                raw: core::ptr::NonNull::new_unchecked(
19667                    ffi::whiteout_m3_M3Model_get_compositeMaterials_at(self.raw.as_ptr(), index),
19668                ),
19669            }))
19670        }
19671    }
19672
19673    /// Iterate the elements, borrowing each in turn.
19674    pub fn composite_materials_iter(
19675        &self,
19676    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, CompositeMaterial>> {
19677        (0..self.composite_materials_len())
19678            .map(move |i| self.composite_materials(i).expect("index below len"))
19679    }
19680
19681    pub fn resize_composite_materials(&mut self, count: usize) {
19682        // SAFETY: exclusive access, so no borrow is outstanding.
19683        unsafe { ffi::whiteout_m3_M3Model_resize_compositeMaterials(self.raw.as_ptr(), count) }
19684    }
19685
19686    /// Terrain materials (TER_)
19687    pub fn terrain_materials_len(&self) -> usize {
19688        // SAFETY: scalar read through a live handle.
19689        unsafe { ffi::whiteout_m3_M3Model_get_terrainMaterials_count(self.raw.as_ptr()) }
19690    }
19691
19692    /// Borrows element `index` in place. `None` when out of range.
19693    pub fn terrain_materials(
19694        &self,
19695        index: usize,
19696    ) -> Option<crate::support::Ref<'_, TerrainMaterial>> {
19697        if index >= self.terrain_materials_len() {
19698            return None;
19699        }
19700        // SAFETY: index checked above; the pointer is interior to `self`.
19701        unsafe {
19702            Some(crate::support::Ref::new(TerrainMaterial {
19703                raw: core::ptr::NonNull::new_unchecked(
19704                    ffi::whiteout_m3_M3Model_get_terrainMaterials_at(self.raw.as_ptr(), index),
19705                ),
19706            }))
19707        }
19708    }
19709
19710    pub fn terrain_materials_mut(
19711        &mut self,
19712        index: usize,
19713    ) -> Option<crate::support::RefMut<'_, TerrainMaterial>> {
19714        if index >= self.terrain_materials_len() {
19715            return None;
19716        }
19717        // SAFETY: as above; `&mut self` guarantees exclusivity.
19718        unsafe {
19719            Some(crate::support::RefMut::new(TerrainMaterial {
19720                raw: core::ptr::NonNull::new_unchecked(
19721                    ffi::whiteout_m3_M3Model_get_terrainMaterials_at(self.raw.as_ptr(), index),
19722                ),
19723            }))
19724        }
19725    }
19726
19727    /// Iterate the elements, borrowing each in turn.
19728    pub fn terrain_materials_iter(
19729        &self,
19730    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, TerrainMaterial>> {
19731        (0..self.terrain_materials_len())
19732            .map(move |i| self.terrain_materials(i).expect("index below len"))
19733    }
19734
19735    pub fn resize_terrain_materials(&mut self, count: usize) {
19736        // SAFETY: exclusive access, so no borrow is outstanding.
19737        unsafe { ffi::whiteout_m3_M3Model_resize_terrainMaterials(self.raw.as_ptr(), count) }
19738    }
19739
19740    /// Volume materials (VOL_)
19741    pub fn volume_materials_len(&self) -> usize {
19742        // SAFETY: scalar read through a live handle.
19743        unsafe { ffi::whiteout_m3_M3Model_get_volumeMaterials_count(self.raw.as_ptr()) }
19744    }
19745
19746    /// Borrows element `index` in place. `None` when out of range.
19747    pub fn volume_materials(
19748        &self,
19749        index: usize,
19750    ) -> Option<crate::support::Ref<'_, VolumeMaterial>> {
19751        if index >= self.volume_materials_len() {
19752            return None;
19753        }
19754        // SAFETY: index checked above; the pointer is interior to `self`.
19755        unsafe {
19756            Some(crate::support::Ref::new(VolumeMaterial {
19757                raw: core::ptr::NonNull::new_unchecked(
19758                    ffi::whiteout_m3_M3Model_get_volumeMaterials_at(self.raw.as_ptr(), index),
19759                ),
19760            }))
19761        }
19762    }
19763
19764    pub fn volume_materials_mut(
19765        &mut self,
19766        index: usize,
19767    ) -> Option<crate::support::RefMut<'_, VolumeMaterial>> {
19768        if index >= self.volume_materials_len() {
19769            return None;
19770        }
19771        // SAFETY: as above; `&mut self` guarantees exclusivity.
19772        unsafe {
19773            Some(crate::support::RefMut::new(VolumeMaterial {
19774                raw: core::ptr::NonNull::new_unchecked(
19775                    ffi::whiteout_m3_M3Model_get_volumeMaterials_at(self.raw.as_ptr(), index),
19776                ),
19777            }))
19778        }
19779    }
19780
19781    /// Iterate the elements, borrowing each in turn.
19782    pub fn volume_materials_iter(
19783        &self,
19784    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, VolumeMaterial>> {
19785        (0..self.volume_materials_len())
19786            .map(move |i| self.volume_materials(i).expect("index below len"))
19787    }
19788
19789    pub fn resize_volume_materials(&mut self, count: usize) {
19790        // SAFETY: exclusive access, so no borrow is outstanding.
19791        unsafe { ffi::whiteout_m3_M3Model_resize_volumeMaterials(self.raw.as_ptr(), count) }
19792    }
19793
19794    /// Hair materials (HAI_, defunct — always null)
19795    pub fn hair_materials_len(&self) -> usize {
19796        // SAFETY: scalar read through a live handle.
19797        unsafe { ffi::whiteout_m3_M3Model_get_hairMaterials_count(self.raw.as_ptr()) }
19798    }
19799
19800    /// Borrows element `index` in place. `None` when out of range.
19801    pub fn hair_materials(&self, index: usize) -> Option<crate::support::Ref<'_, HairMaterial>> {
19802        if index >= self.hair_materials_len() {
19803            return None;
19804        }
19805        // SAFETY: index checked above; the pointer is interior to `self`.
19806        unsafe {
19807            Some(crate::support::Ref::new(HairMaterial {
19808                raw: core::ptr::NonNull::new_unchecked(
19809                    ffi::whiteout_m3_M3Model_get_hairMaterials_at(self.raw.as_ptr(), index),
19810                ),
19811            }))
19812        }
19813    }
19814
19815    pub fn hair_materials_mut(
19816        &mut self,
19817        index: usize,
19818    ) -> Option<crate::support::RefMut<'_, HairMaterial>> {
19819        if index >= self.hair_materials_len() {
19820            return None;
19821        }
19822        // SAFETY: as above; `&mut self` guarantees exclusivity.
19823        unsafe {
19824            Some(crate::support::RefMut::new(HairMaterial {
19825                raw: core::ptr::NonNull::new_unchecked(
19826                    ffi::whiteout_m3_M3Model_get_hairMaterials_at(self.raw.as_ptr(), index),
19827                ),
19828            }))
19829        }
19830    }
19831
19832    /// Iterate the elements, borrowing each in turn.
19833    pub fn hair_materials_iter(
19834        &self,
19835    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, HairMaterial>> {
19836        (0..self.hair_materials_len())
19837            .map(move |i| self.hair_materials(i).expect("index below len"))
19838    }
19839
19840    pub fn resize_hair_materials(&mut self, count: usize) {
19841        // SAFETY: exclusive access, so no borrow is outstanding.
19842        unsafe { ffi::whiteout_m3_M3Model_resize_hairMaterials(self.raw.as_ptr(), count) }
19843    }
19844
19845    /// Creep materials (CREP)
19846    pub fn creep_materials_len(&self) -> usize {
19847        // SAFETY: scalar read through a live handle.
19848        unsafe { ffi::whiteout_m3_M3Model_get_creepMaterials_count(self.raw.as_ptr()) }
19849    }
19850
19851    /// Borrows element `index` in place. `None` when out of range.
19852    pub fn creep_materials(&self, index: usize) -> Option<crate::support::Ref<'_, CreepMaterial>> {
19853        if index >= self.creep_materials_len() {
19854            return None;
19855        }
19856        // SAFETY: index checked above; the pointer is interior to `self`.
19857        unsafe {
19858            Some(crate::support::Ref::new(CreepMaterial {
19859                raw: core::ptr::NonNull::new_unchecked(
19860                    ffi::whiteout_m3_M3Model_get_creepMaterials_at(self.raw.as_ptr(), index),
19861                ),
19862            }))
19863        }
19864    }
19865
19866    pub fn creep_materials_mut(
19867        &mut self,
19868        index: usize,
19869    ) -> Option<crate::support::RefMut<'_, CreepMaterial>> {
19870        if index >= self.creep_materials_len() {
19871            return None;
19872        }
19873        // SAFETY: as above; `&mut self` guarantees exclusivity.
19874        unsafe {
19875            Some(crate::support::RefMut::new(CreepMaterial {
19876                raw: core::ptr::NonNull::new_unchecked(
19877                    ffi::whiteout_m3_M3Model_get_creepMaterials_at(self.raw.as_ptr(), index),
19878                ),
19879            }))
19880        }
19881    }
19882
19883    /// Iterate the elements, borrowing each in turn.
19884    pub fn creep_materials_iter(
19885        &self,
19886    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, CreepMaterial>> {
19887        (0..self.creep_materials_len())
19888            .map(move |i| self.creep_materials(i).expect("index below len"))
19889    }
19890
19891    pub fn resize_creep_materials(&mut self, count: usize) {
19892        // SAFETY: exclusive access, so no borrow is outstanding.
19893        unsafe { ffi::whiteout_m3_M3Model_resize_creepMaterials(self.raw.as_ptr(), count) }
19894    }
19895
19896    /// Volume noise materials (VON_, v25+)
19897    pub fn volume_noise_materials_len(&self) -> usize {
19898        // SAFETY: scalar read through a live handle.
19899        unsafe { ffi::whiteout_m3_M3Model_get_volumeNoiseMaterials_count(self.raw.as_ptr()) }
19900    }
19901
19902    /// Borrows element `index` in place. `None` when out of range.
19903    pub fn volume_noise_materials(
19904        &self,
19905        index: usize,
19906    ) -> Option<crate::support::Ref<'_, VolumeNoiseMaterial>> {
19907        if index >= self.volume_noise_materials_len() {
19908            return None;
19909        }
19910        // SAFETY: index checked above; the pointer is interior to `self`.
19911        unsafe {
19912            Some(crate::support::Ref::new(VolumeNoiseMaterial {
19913                raw: core::ptr::NonNull::new_unchecked(
19914                    ffi::whiteout_m3_M3Model_get_volumeNoiseMaterials_at(self.raw.as_ptr(), index),
19915                ),
19916            }))
19917        }
19918    }
19919
19920    pub fn volume_noise_materials_mut(
19921        &mut self,
19922        index: usize,
19923    ) -> Option<crate::support::RefMut<'_, VolumeNoiseMaterial>> {
19924        if index >= self.volume_noise_materials_len() {
19925            return None;
19926        }
19927        // SAFETY: as above; `&mut self` guarantees exclusivity.
19928        unsafe {
19929            Some(crate::support::RefMut::new(VolumeNoiseMaterial {
19930                raw: core::ptr::NonNull::new_unchecked(
19931                    ffi::whiteout_m3_M3Model_get_volumeNoiseMaterials_at(self.raw.as_ptr(), index),
19932                ),
19933            }))
19934        }
19935    }
19936
19937    /// Iterate the elements, borrowing each in turn.
19938    pub fn volume_noise_materials_iter(
19939        &self,
19940    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, VolumeNoiseMaterial>> {
19941        (0..self.volume_noise_materials_len())
19942            .map(move |i| self.volume_noise_materials(i).expect("index below len"))
19943    }
19944
19945    pub fn resize_volume_noise_materials(&mut self, count: usize) {
19946        // SAFETY: exclusive access, so no borrow is outstanding.
19947        unsafe { ffi::whiteout_m3_M3Model_resize_volumeNoiseMaterials(self.raw.as_ptr(), count) }
19948    }
19949
19950    /// Splat terrain bake materials (STBM, v26+)
19951    pub fn stb_materials_len(&self) -> usize {
19952        // SAFETY: scalar read through a live handle.
19953        unsafe { ffi::whiteout_m3_M3Model_get_stbMaterials_count(self.raw.as_ptr()) }
19954    }
19955
19956    /// Borrows element `index` in place. `None` when out of range.
19957    pub fn stb_materials(&self, index: usize) -> Option<crate::support::Ref<'_, STBMaterial>> {
19958        if index >= self.stb_materials_len() {
19959            return None;
19960        }
19961        // SAFETY: index checked above; the pointer is interior to `self`.
19962        unsafe {
19963            Some(crate::support::Ref::new(STBMaterial {
19964                raw: core::ptr::NonNull::new_unchecked(
19965                    ffi::whiteout_m3_M3Model_get_stbMaterials_at(self.raw.as_ptr(), index),
19966                ),
19967            }))
19968        }
19969    }
19970
19971    pub fn stb_materials_mut(
19972        &mut self,
19973        index: usize,
19974    ) -> Option<crate::support::RefMut<'_, STBMaterial>> {
19975        if index >= self.stb_materials_len() {
19976            return None;
19977        }
19978        // SAFETY: as above; `&mut self` guarantees exclusivity.
19979        unsafe {
19980            Some(crate::support::RefMut::new(STBMaterial {
19981                raw: core::ptr::NonNull::new_unchecked(
19982                    ffi::whiteout_m3_M3Model_get_stbMaterials_at(self.raw.as_ptr(), index),
19983                ),
19984            }))
19985        }
19986    }
19987
19988    /// Iterate the elements, borrowing each in turn.
19989    pub fn stb_materials_iter(
19990        &self,
19991    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, STBMaterial>> {
19992        (0..self.stb_materials_len()).map(move |i| self.stb_materials(i).expect("index below len"))
19993    }
19994
19995    pub fn resize_stb_materials(&mut self, count: usize) {
19996        // SAFETY: exclusive access, so no borrow is outstanding.
19997        unsafe { ffi::whiteout_m3_M3Model_resize_stbMaterials(self.raw.as_ptr(), count) }
19998    }
19999
20000    /// Reflection materials (REF_, v28+)
20001    pub fn reflection_materials_len(&self) -> usize {
20002        // SAFETY: scalar read through a live handle.
20003        unsafe { ffi::whiteout_m3_M3Model_get_reflectionMaterials_count(self.raw.as_ptr()) }
20004    }
20005
20006    /// Borrows element `index` in place. `None` when out of range.
20007    pub fn reflection_materials(
20008        &self,
20009        index: usize,
20010    ) -> Option<crate::support::Ref<'_, ReflectionMaterial>> {
20011        if index >= self.reflection_materials_len() {
20012            return None;
20013        }
20014        // SAFETY: index checked above; the pointer is interior to `self`.
20015        unsafe {
20016            Some(crate::support::Ref::new(ReflectionMaterial {
20017                raw: core::ptr::NonNull::new_unchecked(
20018                    ffi::whiteout_m3_M3Model_get_reflectionMaterials_at(self.raw.as_ptr(), index),
20019                ),
20020            }))
20021        }
20022    }
20023
20024    pub fn reflection_materials_mut(
20025        &mut self,
20026        index: usize,
20027    ) -> Option<crate::support::RefMut<'_, ReflectionMaterial>> {
20028        if index >= self.reflection_materials_len() {
20029            return None;
20030        }
20031        // SAFETY: as above; `&mut self` guarantees exclusivity.
20032        unsafe {
20033            Some(crate::support::RefMut::new(ReflectionMaterial {
20034                raw: core::ptr::NonNull::new_unchecked(
20035                    ffi::whiteout_m3_M3Model_get_reflectionMaterials_at(self.raw.as_ptr(), index),
20036                ),
20037            }))
20038        }
20039    }
20040
20041    /// Iterate the elements, borrowing each in turn.
20042    pub fn reflection_materials_iter(
20043        &self,
20044    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, ReflectionMaterial>> {
20045        (0..self.reflection_materials_len())
20046            .map(move |i| self.reflection_materials(i).expect("index below len"))
20047    }
20048
20049    pub fn resize_reflection_materials(&mut self, count: usize) {
20050        // SAFETY: exclusive access, so no borrow is outstanding.
20051        unsafe { ffi::whiteout_m3_M3Model_resize_reflectionMaterials(self.raw.as_ptr(), count) }
20052    }
20053
20054    /// Lens flare materials (LFLR, v29+)
20055    pub fn lens_flare_materials_len(&self) -> usize {
20056        // SAFETY: scalar read through a live handle.
20057        unsafe { ffi::whiteout_m3_M3Model_get_lensFlareMaterials_count(self.raw.as_ptr()) }
20058    }
20059
20060    /// Borrows element `index` in place. `None` when out of range.
20061    pub fn lens_flare_materials(&self, index: usize) -> Option<crate::support::Ref<'_, LensFlare>> {
20062        if index >= self.lens_flare_materials_len() {
20063            return None;
20064        }
20065        // SAFETY: index checked above; the pointer is interior to `self`.
20066        unsafe {
20067            Some(crate::support::Ref::new(LensFlare {
20068                raw: core::ptr::NonNull::new_unchecked(
20069                    ffi::whiteout_m3_M3Model_get_lensFlareMaterials_at(self.raw.as_ptr(), index),
20070                ),
20071            }))
20072        }
20073    }
20074
20075    pub fn lens_flare_materials_mut(
20076        &mut self,
20077        index: usize,
20078    ) -> Option<crate::support::RefMut<'_, LensFlare>> {
20079        if index >= self.lens_flare_materials_len() {
20080            return None;
20081        }
20082        // SAFETY: as above; `&mut self` guarantees exclusivity.
20083        unsafe {
20084            Some(crate::support::RefMut::new(LensFlare {
20085                raw: core::ptr::NonNull::new_unchecked(
20086                    ffi::whiteout_m3_M3Model_get_lensFlareMaterials_at(self.raw.as_ptr(), index),
20087                ),
20088            }))
20089        }
20090    }
20091
20092    /// Iterate the elements, borrowing each in turn.
20093    pub fn lens_flare_materials_iter(
20094        &self,
20095    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, LensFlare>> {
20096        (0..self.lens_flare_materials_len())
20097            .map(move |i| self.lens_flare_materials(i).expect("index below len"))
20098    }
20099
20100    pub fn resize_lens_flare_materials(&mut self, count: usize) {
20101        // SAFETY: exclusive access, so no borrow is outstanding.
20102        unsafe { ffi::whiteout_m3_M3Model_resize_lensFlareMaterials(self.raw.as_ptr(), count) }
20103    }
20104
20105    /// Buffer material data (MADD, v30+)
20106    pub fn material_add_data_len(&self) -> usize {
20107        // SAFETY: scalar read through a live handle.
20108        unsafe { ffi::whiteout_m3_M3Model_get_materialAddData_count(self.raw.as_ptr()) }
20109    }
20110
20111    /// Borrows element `index` in place. `None` when out of range.
20112    pub fn material_add_data(
20113        &self,
20114        index: usize,
20115    ) -> Option<crate::support::Ref<'_, MaterialAddData>> {
20116        if index >= self.material_add_data_len() {
20117            return None;
20118        }
20119        // SAFETY: index checked above; the pointer is interior to `self`.
20120        unsafe {
20121            Some(crate::support::Ref::new(MaterialAddData {
20122                raw: core::ptr::NonNull::new_unchecked(
20123                    ffi::whiteout_m3_M3Model_get_materialAddData_at(self.raw.as_ptr(), index),
20124                ),
20125            }))
20126        }
20127    }
20128
20129    pub fn material_add_data_mut(
20130        &mut self,
20131        index: usize,
20132    ) -> Option<crate::support::RefMut<'_, MaterialAddData>> {
20133        if index >= self.material_add_data_len() {
20134            return None;
20135        }
20136        // SAFETY: as above; `&mut self` guarantees exclusivity.
20137        unsafe {
20138            Some(crate::support::RefMut::new(MaterialAddData {
20139                raw: core::ptr::NonNull::new_unchecked(
20140                    ffi::whiteout_m3_M3Model_get_materialAddData_at(self.raw.as_ptr(), index),
20141                ),
20142            }))
20143        }
20144    }
20145
20146    /// Iterate the elements, borrowing each in turn.
20147    pub fn material_add_data_iter(
20148        &self,
20149    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, MaterialAddData>> {
20150        (0..self.material_add_data_len())
20151            .map(move |i| self.material_add_data(i).expect("index below len"))
20152    }
20153
20154    pub fn resize_material_add_data(&mut self, count: usize) {
20155        // SAFETY: exclusive access, so no borrow is outstanding.
20156        unsafe { ffi::whiteout_m3_M3Model_resize_materialAddData(self.raw.as_ptr(), count) }
20157    }
20158
20159    /// Particle emitters (PAR_)
20160    pub fn particle_emitters_len(&self) -> usize {
20161        // SAFETY: scalar read through a live handle.
20162        unsafe { ffi::whiteout_m3_M3Model_get_particleEmitters_count(self.raw.as_ptr()) }
20163    }
20164
20165    /// Borrows element `index` in place. `None` when out of range.
20166    pub fn particle_emitters(
20167        &self,
20168        index: usize,
20169    ) -> Option<crate::support::Ref<'_, ParticleEmitter>> {
20170        if index >= self.particle_emitters_len() {
20171            return None;
20172        }
20173        // SAFETY: index checked above; the pointer is interior to `self`.
20174        unsafe {
20175            Some(crate::support::Ref::new(ParticleEmitter {
20176                raw: core::ptr::NonNull::new_unchecked(
20177                    ffi::whiteout_m3_M3Model_get_particleEmitters_at(self.raw.as_ptr(), index),
20178                ),
20179            }))
20180        }
20181    }
20182
20183    pub fn particle_emitters_mut(
20184        &mut self,
20185        index: usize,
20186    ) -> Option<crate::support::RefMut<'_, ParticleEmitter>> {
20187        if index >= self.particle_emitters_len() {
20188            return None;
20189        }
20190        // SAFETY: as above; `&mut self` guarantees exclusivity.
20191        unsafe {
20192            Some(crate::support::RefMut::new(ParticleEmitter {
20193                raw: core::ptr::NonNull::new_unchecked(
20194                    ffi::whiteout_m3_M3Model_get_particleEmitters_at(self.raw.as_ptr(), index),
20195                ),
20196            }))
20197        }
20198    }
20199
20200    /// Iterate the elements, borrowing each in turn.
20201    pub fn particle_emitters_iter(
20202        &self,
20203    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, ParticleEmitter>> {
20204        (0..self.particle_emitters_len())
20205            .map(move |i| self.particle_emitters(i).expect("index below len"))
20206    }
20207
20208    pub fn resize_particle_emitters(&mut self, count: usize) {
20209        // SAFETY: exclusive access, so no borrow is outstanding.
20210        unsafe { ffi::whiteout_m3_M3Model_resize_particleEmitters(self.raw.as_ptr(), count) }
20211    }
20212
20213    /// Particle emitter copies (PARC)
20214    pub fn particle_emitter_copies_len(&self) -> usize {
20215        // SAFETY: scalar read through a live handle.
20216        unsafe { ffi::whiteout_m3_M3Model_get_particleEmitterCopies_count(self.raw.as_ptr()) }
20217    }
20218
20219    /// Borrows element `index` in place. `None` when out of range.
20220    pub fn particle_emitter_copies(
20221        &self,
20222        index: usize,
20223    ) -> Option<crate::support::Ref<'_, ParticleEmitterCopy>> {
20224        if index >= self.particle_emitter_copies_len() {
20225            return None;
20226        }
20227        // SAFETY: index checked above; the pointer is interior to `self`.
20228        unsafe {
20229            Some(crate::support::Ref::new(ParticleEmitterCopy {
20230                raw: core::ptr::NonNull::new_unchecked(
20231                    ffi::whiteout_m3_M3Model_get_particleEmitterCopies_at(self.raw.as_ptr(), index),
20232                ),
20233            }))
20234        }
20235    }
20236
20237    pub fn particle_emitter_copies_mut(
20238        &mut self,
20239        index: usize,
20240    ) -> Option<crate::support::RefMut<'_, ParticleEmitterCopy>> {
20241        if index >= self.particle_emitter_copies_len() {
20242            return None;
20243        }
20244        // SAFETY: as above; `&mut self` guarantees exclusivity.
20245        unsafe {
20246            Some(crate::support::RefMut::new(ParticleEmitterCopy {
20247                raw: core::ptr::NonNull::new_unchecked(
20248                    ffi::whiteout_m3_M3Model_get_particleEmitterCopies_at(self.raw.as_ptr(), index),
20249                ),
20250            }))
20251        }
20252    }
20253
20254    /// Iterate the elements, borrowing each in turn.
20255    pub fn particle_emitter_copies_iter(
20256        &self,
20257    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, ParticleEmitterCopy>> {
20258        (0..self.particle_emitter_copies_len())
20259            .map(move |i| self.particle_emitter_copies(i).expect("index below len"))
20260    }
20261
20262    pub fn resize_particle_emitter_copies(&mut self, count: usize) {
20263        // SAFETY: exclusive access, so no borrow is outstanding.
20264        unsafe { ffi::whiteout_m3_M3Model_resize_particleEmitterCopies(self.raw.as_ptr(), count) }
20265    }
20266
20267    /// Ribbon emitters (RIB_)
20268    pub fn ribbon_emitters_len(&self) -> usize {
20269        // SAFETY: scalar read through a live handle.
20270        unsafe { ffi::whiteout_m3_M3Model_get_ribbonEmitters_count(self.raw.as_ptr()) }
20271    }
20272
20273    /// Borrows element `index` in place. `None` when out of range.
20274    pub fn ribbon_emitters(&self, index: usize) -> Option<crate::support::Ref<'_, RibbonEmitter>> {
20275        if index >= self.ribbon_emitters_len() {
20276            return None;
20277        }
20278        // SAFETY: index checked above; the pointer is interior to `self`.
20279        unsafe {
20280            Some(crate::support::Ref::new(RibbonEmitter {
20281                raw: core::ptr::NonNull::new_unchecked(
20282                    ffi::whiteout_m3_M3Model_get_ribbonEmitters_at(self.raw.as_ptr(), index),
20283                ),
20284            }))
20285        }
20286    }
20287
20288    pub fn ribbon_emitters_mut(
20289        &mut self,
20290        index: usize,
20291    ) -> Option<crate::support::RefMut<'_, RibbonEmitter>> {
20292        if index >= self.ribbon_emitters_len() {
20293            return None;
20294        }
20295        // SAFETY: as above; `&mut self` guarantees exclusivity.
20296        unsafe {
20297            Some(crate::support::RefMut::new(RibbonEmitter {
20298                raw: core::ptr::NonNull::new_unchecked(
20299                    ffi::whiteout_m3_M3Model_get_ribbonEmitters_at(self.raw.as_ptr(), index),
20300                ),
20301            }))
20302        }
20303    }
20304
20305    /// Iterate the elements, borrowing each in turn.
20306    pub fn ribbon_emitters_iter(
20307        &self,
20308    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, RibbonEmitter>> {
20309        (0..self.ribbon_emitters_len())
20310            .map(move |i| self.ribbon_emitters(i).expect("index below len"))
20311    }
20312
20313    pub fn resize_ribbon_emitters(&mut self, count: usize) {
20314        // SAFETY: exclusive access, so no borrow is outstanding.
20315        unsafe { ffi::whiteout_m3_M3Model_resize_ribbonEmitters(self.raw.as_ptr(), count) }
20316    }
20317
20318    /// Projectors / decals (PROJ)
20319    pub fn projections_len(&self) -> usize {
20320        // SAFETY: scalar read through a live handle.
20321        unsafe { ffi::whiteout_m3_M3Model_get_projections_count(self.raw.as_ptr()) }
20322    }
20323
20324    /// Borrows element `index` in place. `None` when out of range.
20325    pub fn projections(&self, index: usize) -> Option<crate::support::Ref<'_, Projector>> {
20326        if index >= self.projections_len() {
20327            return None;
20328        }
20329        // SAFETY: index checked above; the pointer is interior to `self`.
20330        unsafe {
20331            Some(crate::support::Ref::new(Projector {
20332                raw: core::ptr::NonNull::new_unchecked(
20333                    ffi::whiteout_m3_M3Model_get_projections_at(self.raw.as_ptr(), index),
20334                ),
20335            }))
20336        }
20337    }
20338
20339    pub fn projections_mut(
20340        &mut self,
20341        index: usize,
20342    ) -> Option<crate::support::RefMut<'_, Projector>> {
20343        if index >= self.projections_len() {
20344            return None;
20345        }
20346        // SAFETY: as above; `&mut self` guarantees exclusivity.
20347        unsafe {
20348            Some(crate::support::RefMut::new(Projector {
20349                raw: core::ptr::NonNull::new_unchecked(
20350                    ffi::whiteout_m3_M3Model_get_projections_at(self.raw.as_ptr(), index),
20351                ),
20352            }))
20353        }
20354    }
20355
20356    /// Iterate the elements, borrowing each in turn.
20357    pub fn projections_iter(
20358        &self,
20359    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, Projector>> {
20360        (0..self.projections_len()).map(move |i| self.projections(i).expect("index below len"))
20361    }
20362
20363    pub fn resize_projections(&mut self, count: usize) {
20364        // SAFETY: exclusive access, so no borrow is outstanding.
20365        unsafe { ffi::whiteout_m3_M3Model_resize_projections(self.raw.as_ptr(), count) }
20366    }
20367
20368    /// Forces (FOR_)
20369    pub fn forces_len(&self) -> usize {
20370        // SAFETY: scalar read through a live handle.
20371        unsafe { ffi::whiteout_m3_M3Model_get_forces_count(self.raw.as_ptr()) }
20372    }
20373
20374    /// Borrows element `index` in place. `None` when out of range.
20375    pub fn forces(&self, index: usize) -> Option<crate::support::Ref<'_, Force>> {
20376        if index >= self.forces_len() {
20377            return None;
20378        }
20379        // SAFETY: index checked above; the pointer is interior to `self`.
20380        unsafe {
20381            Some(crate::support::Ref::new(Force {
20382                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Model_get_forces_at(
20383                    self.raw.as_ptr(),
20384                    index,
20385                )),
20386            }))
20387        }
20388    }
20389
20390    pub fn forces_mut(&mut self, index: usize) -> Option<crate::support::RefMut<'_, Force>> {
20391        if index >= self.forces_len() {
20392            return None;
20393        }
20394        // SAFETY: as above; `&mut self` guarantees exclusivity.
20395        unsafe {
20396            Some(crate::support::RefMut::new(Force {
20397                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Model_get_forces_at(
20398                    self.raw.as_ptr(),
20399                    index,
20400                )),
20401            }))
20402        }
20403    }
20404
20405    /// Iterate the elements, borrowing each in turn.
20406    pub fn forces_iter(&self) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, Force>> {
20407        (0..self.forces_len()).map(move |i| self.forces(i).expect("index below len"))
20408    }
20409
20410    pub fn resize_forces(&mut self, count: usize) {
20411        // SAFETY: exclusive access, so no borrow is outstanding.
20412        unsafe { ffi::whiteout_m3_M3Model_resize_forces(self.raw.as_ptr(), count) }
20413    }
20414
20415    /// Warps (WRP_)
20416    pub fn warps_len(&self) -> usize {
20417        // SAFETY: scalar read through a live handle.
20418        unsafe { ffi::whiteout_m3_M3Model_get_warps_count(self.raw.as_ptr()) }
20419    }
20420
20421    /// Borrows element `index` in place. `None` when out of range.
20422    pub fn warps(&self, index: usize) -> Option<crate::support::Ref<'_, Warp>> {
20423        if index >= self.warps_len() {
20424            return None;
20425        }
20426        // SAFETY: index checked above; the pointer is interior to `self`.
20427        unsafe {
20428            Some(crate::support::Ref::new(Warp {
20429                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Model_get_warps_at(
20430                    self.raw.as_ptr(),
20431                    index,
20432                )),
20433            }))
20434        }
20435    }
20436
20437    pub fn warps_mut(&mut self, index: usize) -> Option<crate::support::RefMut<'_, Warp>> {
20438        if index >= self.warps_len() {
20439            return None;
20440        }
20441        // SAFETY: as above; `&mut self` guarantees exclusivity.
20442        unsafe {
20443            Some(crate::support::RefMut::new(Warp {
20444                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Model_get_warps_at(
20445                    self.raw.as_ptr(),
20446                    index,
20447                )),
20448            }))
20449        }
20450    }
20451
20452    /// Iterate the elements, borrowing each in turn.
20453    pub fn warps_iter(&self) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, Warp>> {
20454        (0..self.warps_len()).map(move |i| self.warps(i).expect("index below len"))
20455    }
20456
20457    pub fn resize_warps(&mut self, count: usize) {
20458        // SAFETY: exclusive access, so no borrow is outstanding.
20459        unsafe { ffi::whiteout_m3_M3Model_resize_warps(self.raw.as_ptr(), count) }
20460    }
20461
20462    /// View volumes (VVOL)
20463    pub fn view_volumes_len(&self) -> usize {
20464        // SAFETY: scalar read through a live handle.
20465        unsafe { ffi::whiteout_m3_M3Model_get_viewVolumes_count(self.raw.as_ptr()) }
20466    }
20467
20468    /// Borrows element `index` in place. `None` when out of range.
20469    pub fn view_volumes(&self, index: usize) -> Option<crate::support::Ref<'_, ViewVolume>> {
20470        if index >= self.view_volumes_len() {
20471            return None;
20472        }
20473        // SAFETY: index checked above; the pointer is interior to `self`.
20474        unsafe {
20475            Some(crate::support::Ref::new(ViewVolume {
20476                raw: core::ptr::NonNull::new_unchecked(
20477                    ffi::whiteout_m3_M3Model_get_viewVolumes_at(self.raw.as_ptr(), index),
20478                ),
20479            }))
20480        }
20481    }
20482
20483    pub fn view_volumes_mut(
20484        &mut self,
20485        index: usize,
20486    ) -> Option<crate::support::RefMut<'_, ViewVolume>> {
20487        if index >= self.view_volumes_len() {
20488            return None;
20489        }
20490        // SAFETY: as above; `&mut self` guarantees exclusivity.
20491        unsafe {
20492            Some(crate::support::RefMut::new(ViewVolume {
20493                raw: core::ptr::NonNull::new_unchecked(
20494                    ffi::whiteout_m3_M3Model_get_viewVolumes_at(self.raw.as_ptr(), index),
20495                ),
20496            }))
20497        }
20498    }
20499
20500    /// Iterate the elements, borrowing each in turn.
20501    pub fn view_volumes_iter(
20502        &self,
20503    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, ViewVolume>> {
20504        (0..self.view_volumes_len()).map(move |i| self.view_volumes(i).expect("index below len"))
20505    }
20506
20507    pub fn resize_view_volumes(&mut self, count: usize) {
20508        // SAFETY: exclusive access, so no borrow is outstanding.
20509        unsafe { ffi::whiteout_m3_M3Model_resize_viewVolumes(self.raw.as_ptr(), count) }
20510    }
20511
20512    /// Rigid bodies (PHRB)
20513    pub fn rigid_bodies_len(&self) -> usize {
20514        // SAFETY: scalar read through a live handle.
20515        unsafe { ffi::whiteout_m3_M3Model_get_rigidBodies_count(self.raw.as_ptr()) }
20516    }
20517
20518    /// Borrows element `index` in place. `None` when out of range.
20519    pub fn rigid_bodies(&self, index: usize) -> Option<crate::support::Ref<'_, RigidBody>> {
20520        if index >= self.rigid_bodies_len() {
20521            return None;
20522        }
20523        // SAFETY: index checked above; the pointer is interior to `self`.
20524        unsafe {
20525            Some(crate::support::Ref::new(RigidBody {
20526                raw: core::ptr::NonNull::new_unchecked(
20527                    ffi::whiteout_m3_M3Model_get_rigidBodies_at(self.raw.as_ptr(), index),
20528                ),
20529            }))
20530        }
20531    }
20532
20533    pub fn rigid_bodies_mut(
20534        &mut self,
20535        index: usize,
20536    ) -> Option<crate::support::RefMut<'_, RigidBody>> {
20537        if index >= self.rigid_bodies_len() {
20538            return None;
20539        }
20540        // SAFETY: as above; `&mut self` guarantees exclusivity.
20541        unsafe {
20542            Some(crate::support::RefMut::new(RigidBody {
20543                raw: core::ptr::NonNull::new_unchecked(
20544                    ffi::whiteout_m3_M3Model_get_rigidBodies_at(self.raw.as_ptr(), index),
20545                ),
20546            }))
20547        }
20548    }
20549
20550    /// Iterate the elements, borrowing each in turn.
20551    pub fn rigid_bodies_iter(
20552        &self,
20553    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, RigidBody>> {
20554        (0..self.rigid_bodies_len()).map(move |i| self.rigid_bodies(i).expect("index below len"))
20555    }
20556
20557    pub fn resize_rigid_bodies(&mut self, count: usize) {
20558        // SAFETY: exclusive access, so no borrow is outstanding.
20559        unsafe { ffi::whiteout_m3_M3Model_resize_rigidBodies(self.raw.as_ptr(), count) }
20560    }
20561
20562    /// Physics constraints (PHCT)
20563    pub fn physics_constraints_len(&self) -> usize {
20564        // SAFETY: scalar read through a live handle.
20565        unsafe { ffi::whiteout_m3_M3Model_get_physicsConstraints_count(self.raw.as_ptr()) }
20566    }
20567
20568    /// Borrows element `index` in place. `None` when out of range.
20569    pub fn physics_constraints(
20570        &self,
20571        index: usize,
20572    ) -> Option<crate::support::Ref<'_, PhysicsConstraint>> {
20573        if index >= self.physics_constraints_len() {
20574            return None;
20575        }
20576        // SAFETY: index checked above; the pointer is interior to `self`.
20577        unsafe {
20578            Some(crate::support::Ref::new(PhysicsConstraint {
20579                raw: core::ptr::NonNull::new_unchecked(
20580                    ffi::whiteout_m3_M3Model_get_physicsConstraints_at(self.raw.as_ptr(), index),
20581                ),
20582            }))
20583        }
20584    }
20585
20586    pub fn physics_constraints_mut(
20587        &mut self,
20588        index: usize,
20589    ) -> Option<crate::support::RefMut<'_, PhysicsConstraint>> {
20590        if index >= self.physics_constraints_len() {
20591            return None;
20592        }
20593        // SAFETY: as above; `&mut self` guarantees exclusivity.
20594        unsafe {
20595            Some(crate::support::RefMut::new(PhysicsConstraint {
20596                raw: core::ptr::NonNull::new_unchecked(
20597                    ffi::whiteout_m3_M3Model_get_physicsConstraints_at(self.raw.as_ptr(), index),
20598                ),
20599            }))
20600        }
20601    }
20602
20603    /// Iterate the elements, borrowing each in turn.
20604    pub fn physics_constraints_iter(
20605        &self,
20606    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, PhysicsConstraint>> {
20607        (0..self.physics_constraints_len())
20608            .map(move |i| self.physics_constraints(i).expect("index below len"))
20609    }
20610
20611    pub fn resize_physics_constraints(&mut self, count: usize) {
20612        // SAFETY: exclusive access, so no borrow is outstanding.
20613        unsafe { ffi::whiteout_m3_M3Model_resize_physicsConstraints(self.raw.as_ptr(), count) }
20614    }
20615
20616    /// Physics joints (PHYJ)
20617    pub fn physics_joints_len(&self) -> usize {
20618        // SAFETY: scalar read through a live handle.
20619        unsafe { ffi::whiteout_m3_M3Model_get_physicsJoints_count(self.raw.as_ptr()) }
20620    }
20621
20622    /// Borrows element `index` in place. `None` when out of range.
20623    pub fn physics_joints(&self, index: usize) -> Option<crate::support::Ref<'_, PhysicsJoint>> {
20624        if index >= self.physics_joints_len() {
20625            return None;
20626        }
20627        // SAFETY: index checked above; the pointer is interior to `self`.
20628        unsafe {
20629            Some(crate::support::Ref::new(PhysicsJoint {
20630                raw: core::ptr::NonNull::new_unchecked(
20631                    ffi::whiteout_m3_M3Model_get_physicsJoints_at(self.raw.as_ptr(), index),
20632                ),
20633            }))
20634        }
20635    }
20636
20637    pub fn physics_joints_mut(
20638        &mut self,
20639        index: usize,
20640    ) -> Option<crate::support::RefMut<'_, PhysicsJoint>> {
20641        if index >= self.physics_joints_len() {
20642            return None;
20643        }
20644        // SAFETY: as above; `&mut self` guarantees exclusivity.
20645        unsafe {
20646            Some(crate::support::RefMut::new(PhysicsJoint {
20647                raw: core::ptr::NonNull::new_unchecked(
20648                    ffi::whiteout_m3_M3Model_get_physicsJoints_at(self.raw.as_ptr(), index),
20649                ),
20650            }))
20651        }
20652    }
20653
20654    /// Iterate the elements, borrowing each in turn.
20655    pub fn physics_joints_iter(
20656        &self,
20657    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, PhysicsJoint>> {
20658        (0..self.physics_joints_len())
20659            .map(move |i| self.physics_joints(i).expect("index below len"))
20660    }
20661
20662    pub fn resize_physics_joints(&mut self, count: usize) {
20663        // SAFETY: exclusive access, so no borrow is outstanding.
20664        unsafe { ffi::whiteout_m3_M3Model_resize_physicsJoints(self.raw.as_ptr(), count) }
20665    }
20666
20667    /// Cloth physics (PHCL, v28+)
20668    pub fn cloth_physics_len(&self) -> usize {
20669        // SAFETY: scalar read through a live handle.
20670        unsafe { ffi::whiteout_m3_M3Model_get_clothPhysics_count(self.raw.as_ptr()) }
20671    }
20672
20673    /// Borrows element `index` in place. `None` when out of range.
20674    pub fn cloth_physics(&self, index: usize) -> Option<crate::support::Ref<'_, ClothPhysics>> {
20675        if index >= self.cloth_physics_len() {
20676            return None;
20677        }
20678        // SAFETY: index checked above; the pointer is interior to `self`.
20679        unsafe {
20680            Some(crate::support::Ref::new(ClothPhysics {
20681                raw: core::ptr::NonNull::new_unchecked(
20682                    ffi::whiteout_m3_M3Model_get_clothPhysics_at(self.raw.as_ptr(), index),
20683                ),
20684            }))
20685        }
20686    }
20687
20688    pub fn cloth_physics_mut(
20689        &mut self,
20690        index: usize,
20691    ) -> Option<crate::support::RefMut<'_, ClothPhysics>> {
20692        if index >= self.cloth_physics_len() {
20693            return None;
20694        }
20695        // SAFETY: as above; `&mut self` guarantees exclusivity.
20696        unsafe {
20697            Some(crate::support::RefMut::new(ClothPhysics {
20698                raw: core::ptr::NonNull::new_unchecked(
20699                    ffi::whiteout_m3_M3Model_get_clothPhysics_at(self.raw.as_ptr(), index),
20700                ),
20701            }))
20702        }
20703    }
20704
20705    /// Iterate the elements, borrowing each in turn.
20706    pub fn cloth_physics_iter(
20707        &self,
20708    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, ClothPhysics>> {
20709        (0..self.cloth_physics_len()).map(move |i| self.cloth_physics(i).expect("index below len"))
20710    }
20711
20712    pub fn resize_cloth_physics(&mut self, count: usize) {
20713        // SAFETY: exclusive access, so no borrow is outstanding.
20714        unsafe { ffi::whiteout_m3_M3Model_resize_clothPhysics(self.raw.as_ptr(), count) }
20715    }
20716
20717    /// Two-joint IK solvers (IK2J)
20718    pub fn ik_two_joints_len(&self) -> usize {
20719        // SAFETY: scalar read through a live handle.
20720        unsafe { ffi::whiteout_m3_M3Model_get_ikTwoJoints_count(self.raw.as_ptr()) }
20721    }
20722
20723    /// Borrows element `index` in place. `None` when out of range.
20724    pub fn ik_two_joints(&self, index: usize) -> Option<crate::support::Ref<'_, IKTwoJoint>> {
20725        if index >= self.ik_two_joints_len() {
20726            return None;
20727        }
20728        // SAFETY: index checked above; the pointer is interior to `self`.
20729        unsafe {
20730            Some(crate::support::Ref::new(IKTwoJoint {
20731                raw: core::ptr::NonNull::new_unchecked(
20732                    ffi::whiteout_m3_M3Model_get_ikTwoJoints_at(self.raw.as_ptr(), index),
20733                ),
20734            }))
20735        }
20736    }
20737
20738    pub fn ik_two_joints_mut(
20739        &mut self,
20740        index: usize,
20741    ) -> Option<crate::support::RefMut<'_, IKTwoJoint>> {
20742        if index >= self.ik_two_joints_len() {
20743            return None;
20744        }
20745        // SAFETY: as above; `&mut self` guarantees exclusivity.
20746        unsafe {
20747            Some(crate::support::RefMut::new(IKTwoJoint {
20748                raw: core::ptr::NonNull::new_unchecked(
20749                    ffi::whiteout_m3_M3Model_get_ikTwoJoints_at(self.raw.as_ptr(), index),
20750                ),
20751            }))
20752        }
20753    }
20754
20755    /// Iterate the elements, borrowing each in turn.
20756    pub fn ik_two_joints_iter(
20757        &self,
20758    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, IKTwoJoint>> {
20759        (0..self.ik_two_joints_len()).map(move |i| self.ik_two_joints(i).expect("index below len"))
20760    }
20761
20762    pub fn resize_ik_two_joints(&mut self, count: usize) {
20763        // SAFETY: exclusive access, so no borrow is outstanding.
20764        unsafe { ffi::whiteout_m3_M3Model_resize_ikTwoJoints(self.raw.as_ptr(), count) }
20765    }
20766
20767    /// CCD IK solvers (IKCC, v24+)
20768    pub fn ik_ccd_len(&self) -> usize {
20769        // SAFETY: scalar read through a live handle.
20770        unsafe { ffi::whiteout_m3_M3Model_get_ikCCD_count(self.raw.as_ptr()) }
20771    }
20772
20773    /// Borrows element `index` in place. `None` when out of range.
20774    pub fn ik_ccd(&self, index: usize) -> Option<crate::support::Ref<'_, IKCCD>> {
20775        if index >= self.ik_ccd_len() {
20776            return None;
20777        }
20778        // SAFETY: index checked above; the pointer is interior to `self`.
20779        unsafe {
20780            Some(crate::support::Ref::new(IKCCD {
20781                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Model_get_ikCCD_at(
20782                    self.raw.as_ptr(),
20783                    index,
20784                )),
20785            }))
20786        }
20787    }
20788
20789    pub fn ik_ccd_mut(&mut self, index: usize) -> Option<crate::support::RefMut<'_, IKCCD>> {
20790        if index >= self.ik_ccd_len() {
20791            return None;
20792        }
20793        // SAFETY: as above; `&mut self` guarantees exclusivity.
20794        unsafe {
20795            Some(crate::support::RefMut::new(IKCCD {
20796                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Model_get_ikCCD_at(
20797                    self.raw.as_ptr(),
20798                    index,
20799                )),
20800            }))
20801        }
20802    }
20803
20804    /// Iterate the elements, borrowing each in turn.
20805    pub fn ik_ccd_iter(&self) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, IKCCD>> {
20806        (0..self.ik_ccd_len()).map(move |i| self.ik_ccd(i).expect("index below len"))
20807    }
20808
20809    pub fn resize_ik_ccd(&mut self, count: usize) {
20810        // SAFETY: exclusive access, so no borrow is outstanding.
20811        unsafe { ffi::whiteout_m3_M3Model_resize_ikCCD(self.raw.as_ptr(), count) }
20812    }
20813
20814    /// IK joints (IKJT)
20815    pub fn ik_joints_len(&self) -> usize {
20816        // SAFETY: scalar read through a live handle.
20817        unsafe { ffi::whiteout_m3_M3Model_get_ikJoints_count(self.raw.as_ptr()) }
20818    }
20819
20820    /// Borrows element `index` in place. `None` when out of range.
20821    pub fn ik_joints(&self, index: usize) -> Option<crate::support::Ref<'_, IKJoint>> {
20822        if index >= self.ik_joints_len() {
20823            return None;
20824        }
20825        // SAFETY: index checked above; the pointer is interior to `self`.
20826        unsafe {
20827            Some(crate::support::Ref::new(IKJoint {
20828                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Model_get_ikJoints_at(
20829                    self.raw.as_ptr(),
20830                    index,
20831                )),
20832            }))
20833        }
20834    }
20835
20836    pub fn ik_joints_mut(&mut self, index: usize) -> Option<crate::support::RefMut<'_, IKJoint>> {
20837        if index >= self.ik_joints_len() {
20838            return None;
20839        }
20840        // SAFETY: as above; `&mut self` guarantees exclusivity.
20841        unsafe {
20842            Some(crate::support::RefMut::new(IKJoint {
20843                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Model_get_ikJoints_at(
20844                    self.raw.as_ptr(),
20845                    index,
20846                )),
20847            }))
20848        }
20849    }
20850
20851    /// Iterate the elements, borrowing each in turn.
20852    pub fn ik_joints_iter(
20853        &self,
20854    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, IKJoint>> {
20855        (0..self.ik_joints_len()).map(move |i| self.ik_joints(i).expect("index below len"))
20856    }
20857
20858    pub fn resize_ik_joints(&mut self, count: usize) {
20859        // SAFETY: exclusive access, so no borrow is outstanding.
20860        unsafe { ffi::whiteout_m3_M3Model_resize_ikJoints(self.raw.as_ptr(), count) }
20861    }
20862
20863    /// One-bone IK solvers (PAOB)
20864    pub fn one_bone_solvers_len(&self) -> usize {
20865        // SAFETY: scalar read through a live handle.
20866        unsafe { ffi::whiteout_m3_M3Model_get_oneBoneSolvers_count(self.raw.as_ptr()) }
20867    }
20868
20869    /// Borrows element `index` in place. `None` when out of range.
20870    pub fn one_bone_solvers(&self, index: usize) -> Option<crate::support::Ref<'_, OneBoneSolver>> {
20871        if index >= self.one_bone_solvers_len() {
20872            return None;
20873        }
20874        // SAFETY: index checked above; the pointer is interior to `self`.
20875        unsafe {
20876            Some(crate::support::Ref::new(OneBoneSolver {
20877                raw: core::ptr::NonNull::new_unchecked(
20878                    ffi::whiteout_m3_M3Model_get_oneBoneSolvers_at(self.raw.as_ptr(), index),
20879                ),
20880            }))
20881        }
20882    }
20883
20884    pub fn one_bone_solvers_mut(
20885        &mut self,
20886        index: usize,
20887    ) -> Option<crate::support::RefMut<'_, OneBoneSolver>> {
20888        if index >= self.one_bone_solvers_len() {
20889            return None;
20890        }
20891        // SAFETY: as above; `&mut self` guarantees exclusivity.
20892        unsafe {
20893            Some(crate::support::RefMut::new(OneBoneSolver {
20894                raw: core::ptr::NonNull::new_unchecked(
20895                    ffi::whiteout_m3_M3Model_get_oneBoneSolvers_at(self.raw.as_ptr(), index),
20896                ),
20897            }))
20898        }
20899    }
20900
20901    /// Iterate the elements, borrowing each in turn.
20902    pub fn one_bone_solvers_iter(
20903        &self,
20904    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, OneBoneSolver>> {
20905        (0..self.one_bone_solvers_len())
20906            .map(move |i| self.one_bone_solvers(i).expect("index below len"))
20907    }
20908
20909    pub fn resize_one_bone_solvers(&mut self, count: usize) {
20910        // SAFETY: exclusive access, so no borrow is outstanding.
20911        unsafe { ffi::whiteout_m3_M3Model_resize_oneBoneSolvers(self.raw.as_ptr(), count) }
20912    }
20913
20914    /// Turret behaviors (PATU)
20915    pub fn turret_behaviors_len(&self) -> usize {
20916        // SAFETY: scalar read through a live handle.
20917        unsafe { ffi::whiteout_m3_M3Model_get_turretBehaviors_count(self.raw.as_ptr()) }
20918    }
20919
20920    /// Borrows element `index` in place. `None` when out of range.
20921    pub fn turret_behaviors(
20922        &self,
20923        index: usize,
20924    ) -> Option<crate::support::Ref<'_, TurretBehavior>> {
20925        if index >= self.turret_behaviors_len() {
20926            return None;
20927        }
20928        // SAFETY: index checked above; the pointer is interior to `self`.
20929        unsafe {
20930            Some(crate::support::Ref::new(TurretBehavior {
20931                raw: core::ptr::NonNull::new_unchecked(
20932                    ffi::whiteout_m3_M3Model_get_turretBehaviors_at(self.raw.as_ptr(), index),
20933                ),
20934            }))
20935        }
20936    }
20937
20938    pub fn turret_behaviors_mut(
20939        &mut self,
20940        index: usize,
20941    ) -> Option<crate::support::RefMut<'_, TurretBehavior>> {
20942        if index >= self.turret_behaviors_len() {
20943            return None;
20944        }
20945        // SAFETY: as above; `&mut self` guarantees exclusivity.
20946        unsafe {
20947            Some(crate::support::RefMut::new(TurretBehavior {
20948                raw: core::ptr::NonNull::new_unchecked(
20949                    ffi::whiteout_m3_M3Model_get_turretBehaviors_at(self.raw.as_ptr(), index),
20950                ),
20951            }))
20952        }
20953    }
20954
20955    /// Iterate the elements, borrowing each in turn.
20956    pub fn turret_behaviors_iter(
20957        &self,
20958    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, TurretBehavior>> {
20959        (0..self.turret_behaviors_len())
20960            .map(move |i| self.turret_behaviors(i).expect("index below len"))
20961    }
20962
20963    pub fn resize_turret_behaviors(&mut self, count: usize) {
20964        // SAFETY: exclusive access, so no borrow is outstanding.
20965        unsafe { ffi::whiteout_m3_M3Model_resize_turretBehaviors(self.raw.as_ptr(), count) }
20966    }
20967
20968    /// Trigger data (TRGD)
20969    pub fn trigger_data_len(&self) -> usize {
20970        // SAFETY: scalar read through a live handle.
20971        unsafe { ffi::whiteout_m3_M3Model_get_triggerData_count(self.raw.as_ptr()) }
20972    }
20973
20974    /// Borrows element `index` in place. `None` when out of range.
20975    pub fn trigger_data(&self, index: usize) -> Option<crate::support::Ref<'_, TriggerData>> {
20976        if index >= self.trigger_data_len() {
20977            return None;
20978        }
20979        // SAFETY: index checked above; the pointer is interior to `self`.
20980        unsafe {
20981            Some(crate::support::Ref::new(TriggerData {
20982                raw: core::ptr::NonNull::new_unchecked(
20983                    ffi::whiteout_m3_M3Model_get_triggerData_at(self.raw.as_ptr(), index),
20984                ),
20985            }))
20986        }
20987    }
20988
20989    pub fn trigger_data_mut(
20990        &mut self,
20991        index: usize,
20992    ) -> Option<crate::support::RefMut<'_, TriggerData>> {
20993        if index >= self.trigger_data_len() {
20994            return None;
20995        }
20996        // SAFETY: as above; `&mut self` guarantees exclusivity.
20997        unsafe {
20998            Some(crate::support::RefMut::new(TriggerData {
20999                raw: core::ptr::NonNull::new_unchecked(
21000                    ffi::whiteout_m3_M3Model_get_triggerData_at(self.raw.as_ptr(), index),
21001                ),
21002            }))
21003        }
21004    }
21005
21006    /// Iterate the elements, borrowing each in turn.
21007    pub fn trigger_data_iter(
21008        &self,
21009    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, TriggerData>> {
21010        (0..self.trigger_data_len()).map(move |i| self.trigger_data(i).expect("index below len"))
21011    }
21012
21013    pub fn resize_trigger_data(&mut self, count: usize) {
21014        // SAFETY: exclusive access, so no borrow is outstanding.
21015        unsafe { ffi::whiteout_m3_M3Model_resize_triggerData(self.raw.as_ptr(), count) }
21016    }
21017
21018    /// Inverse bind-pose matrices (IREF)
21019    pub fn initial_reference_len(&self) -> usize {
21020        // SAFETY: scalar read through a live handle.
21021        unsafe { ffi::whiteout_m3_M3Model_get_initialReference_count(self.raw.as_ptr()) }
21022    }
21023
21024    /// Borrows element `index` in place. `None` when out of range.
21025    pub fn initial_reference(
21026        &self,
21027        index: usize,
21028    ) -> Option<crate::support::Ref<'_, InitialReference>> {
21029        if index >= self.initial_reference_len() {
21030            return None;
21031        }
21032        // SAFETY: index checked above; the pointer is interior to `self`.
21033        unsafe {
21034            Some(crate::support::Ref::new(InitialReference {
21035                raw: core::ptr::NonNull::new_unchecked(
21036                    ffi::whiteout_m3_M3Model_get_initialReference_at(self.raw.as_ptr(), index),
21037                ),
21038            }))
21039        }
21040    }
21041
21042    pub fn initial_reference_mut(
21043        &mut self,
21044        index: usize,
21045    ) -> Option<crate::support::RefMut<'_, InitialReference>> {
21046        if index >= self.initial_reference_len() {
21047            return None;
21048        }
21049        // SAFETY: as above; `&mut self` guarantees exclusivity.
21050        unsafe {
21051            Some(crate::support::RefMut::new(InitialReference {
21052                raw: core::ptr::NonNull::new_unchecked(
21053                    ffi::whiteout_m3_M3Model_get_initialReference_at(self.raw.as_ptr(), index),
21054                ),
21055            }))
21056        }
21057    }
21058
21059    /// Iterate the elements, borrowing each in turn.
21060    pub fn initial_reference_iter(
21061        &self,
21062    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, InitialReference>> {
21063        (0..self.initial_reference_len())
21064            .map(move |i| self.initial_reference(i).expect("index below len"))
21065    }
21066
21067    pub fn resize_initial_reference(&mut self, count: usize) {
21068        // SAFETY: exclusive access, so no borrow is outstanding.
21069        unsafe { ffi::whiteout_m3_M3Model_resize_initialReference(self.raw.as_ptr(), count) }
21070    }
21071
21072    /// Tight hit-test shape (SSGS, inline)
21073    /// Borrows the field in place — no copy, no allocation.
21074    pub fn tight_hit_test_object(&self) -> crate::support::Ref<'_, HitTestShape> {
21075        // SAFETY: an interior pointer into `self`, valid for this
21076        // borrow and never freed by the `Ref`.
21077        unsafe {
21078            crate::support::Ref::new(HitTestShape {
21079                raw: core::ptr::NonNull::new_unchecked(
21080                    ffi::whiteout_m3_M3Model_get_tightHitTestObject(self.raw.as_ptr()),
21081                ),
21082            })
21083        }
21084    }
21085
21086    pub fn tight_hit_test_object_mut(&mut self) -> crate::support::RefMut<'_, HitTestShape> {
21087        // SAFETY: as above; `&mut self` guarantees exclusivity.
21088        unsafe {
21089            crate::support::RefMut::new(HitTestShape {
21090                raw: core::ptr::NonNull::new_unchecked(
21091                    ffi::whiteout_m3_M3Model_get_tightHitTestObject(self.raw.as_ptr()),
21092                ),
21093            })
21094        }
21095    }
21096
21097    /// Fuzzy hit-test shapes (SSGS)
21098    pub fn fuzzy_hit_test_objects_len(&self) -> usize {
21099        // SAFETY: scalar read through a live handle.
21100        unsafe { ffi::whiteout_m3_M3Model_get_fuzzyHitTestObjects_count(self.raw.as_ptr()) }
21101    }
21102
21103    /// Borrows element `index` in place. `None` when out of range.
21104    pub fn fuzzy_hit_test_objects(
21105        &self,
21106        index: usize,
21107    ) -> Option<crate::support::Ref<'_, HitTestShape>> {
21108        if index >= self.fuzzy_hit_test_objects_len() {
21109            return None;
21110        }
21111        // SAFETY: index checked above; the pointer is interior to `self`.
21112        unsafe {
21113            Some(crate::support::Ref::new(HitTestShape {
21114                raw: core::ptr::NonNull::new_unchecked(
21115                    ffi::whiteout_m3_M3Model_get_fuzzyHitTestObjects_at(self.raw.as_ptr(), index),
21116                ),
21117            }))
21118        }
21119    }
21120
21121    pub fn fuzzy_hit_test_objects_mut(
21122        &mut self,
21123        index: usize,
21124    ) -> Option<crate::support::RefMut<'_, HitTestShape>> {
21125        if index >= self.fuzzy_hit_test_objects_len() {
21126            return None;
21127        }
21128        // SAFETY: as above; `&mut self` guarantees exclusivity.
21129        unsafe {
21130            Some(crate::support::RefMut::new(HitTestShape {
21131                raw: core::ptr::NonNull::new_unchecked(
21132                    ffi::whiteout_m3_M3Model_get_fuzzyHitTestObjects_at(self.raw.as_ptr(), index),
21133                ),
21134            }))
21135        }
21136    }
21137
21138    /// Iterate the elements, borrowing each in turn.
21139    pub fn fuzzy_hit_test_objects_iter(
21140        &self,
21141    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, HitTestShape>> {
21142        (0..self.fuzzy_hit_test_objects_len())
21143            .map(move |i| self.fuzzy_hit_test_objects(i).expect("index below len"))
21144    }
21145
21146    pub fn resize_fuzzy_hit_test_objects(&mut self, count: usize) {
21147        // SAFETY: exclusive access, so no borrow is outstanding.
21148        unsafe { ffi::whiteout_m3_M3Model_resize_fuzzyHitTestObjects(self.raw.as_ptr(), count) }
21149    }
21150
21151    /// Attachment volumes (ATVL)
21152    pub fn attachment_volumes_len(&self) -> usize {
21153        // SAFETY: scalar read through a live handle.
21154        unsafe { ffi::whiteout_m3_M3Model_get_attachmentVolumes_count(self.raw.as_ptr()) }
21155    }
21156
21157    /// Borrows element `index` in place. `None` when out of range.
21158    pub fn attachment_volumes(
21159        &self,
21160        index: usize,
21161    ) -> Option<crate::support::Ref<'_, AttachmentVolume>> {
21162        if index >= self.attachment_volumes_len() {
21163            return None;
21164        }
21165        // SAFETY: index checked above; the pointer is interior to `self`.
21166        unsafe {
21167            Some(crate::support::Ref::new(AttachmentVolume {
21168                raw: core::ptr::NonNull::new_unchecked(
21169                    ffi::whiteout_m3_M3Model_get_attachmentVolumes_at(self.raw.as_ptr(), index),
21170                ),
21171            }))
21172        }
21173    }
21174
21175    pub fn attachment_volumes_mut(
21176        &mut self,
21177        index: usize,
21178    ) -> Option<crate::support::RefMut<'_, AttachmentVolume>> {
21179        if index >= self.attachment_volumes_len() {
21180            return None;
21181        }
21182        // SAFETY: as above; `&mut self` guarantees exclusivity.
21183        unsafe {
21184            Some(crate::support::RefMut::new(AttachmentVolume {
21185                raw: core::ptr::NonNull::new_unchecked(
21186                    ffi::whiteout_m3_M3Model_get_attachmentVolumes_at(self.raw.as_ptr(), index),
21187                ),
21188            }))
21189        }
21190    }
21191
21192    /// Iterate the elements, borrowing each in turn.
21193    pub fn attachment_volumes_iter(
21194        &self,
21195    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, AttachmentVolume>> {
21196        (0..self.attachment_volumes_len())
21197            .map(move |i| self.attachment_volumes(i).expect("index below len"))
21198    }
21199
21200    pub fn resize_attachment_volumes(&mut self, count: usize) {
21201        // SAFETY: exclusive access, so no borrow is outstanding.
21202        unsafe { ffi::whiteout_m3_M3Model_resize_attachmentVolumes(self.raw.as_ptr(), count) }
21203    }
21204
21205    /// Attachment volume addon 0 (U16_)
21206    /// Zero-copy view of the underlying `std::vector`.
21207    pub fn attachment_volumes_addon_0(&self) -> &[u16] {
21208        // SAFETY: `_data`/`_count` describe one contiguous C++
21209        // allocation, borrowed for as long as `self` is.
21210        unsafe {
21211            let n = ffi::whiteout_m3_M3Model_get_attachmentVolumesAddon0_count(self.raw.as_ptr());
21212            let p = ffi::whiteout_m3_M3Model_get_attachmentVolumesAddon0_data(self.raw.as_ptr());
21213            if p.is_null() || n == 0 {
21214                &[]
21215            } else {
21216                core::slice::from_raw_parts(p, n)
21217            }
21218        }
21219    }
21220
21221    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
21222    pub fn attachment_volumes_addon_0_mut(&mut self) -> &mut [u16] {
21223        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
21224        unsafe {
21225            let n = ffi::whiteout_m3_M3Model_get_attachmentVolumesAddon0_count(self.raw.as_ptr());
21226            let p = ffi::whiteout_m3_M3Model_get_attachmentVolumesAddon0_data(self.raw.as_ptr())
21227                as *mut u16;
21228            if p.is_null() || n == 0 {
21229                &mut []
21230            } else {
21231                core::slice::from_raw_parts_mut(p, n)
21232            }
21233        }
21234    }
21235
21236    pub fn set_attachment_volumes_addon_0(&mut self, values: &[u16]) {
21237        // SAFETY: the native side copies `values` before returning.
21238        unsafe {
21239            ffi::whiteout_m3_M3Model_assign_attachmentVolumesAddon0(
21240                self.raw.as_ptr(),
21241                values.as_ptr() as *const _,
21242                values.len(),
21243            )
21244        }
21245    }
21246
21247    pub fn resize_attachment_volumes_addon_0(&mut self, count: usize) {
21248        // SAFETY: reallocation is safe here precisely because
21249        // `&mut self` means no slice borrow is outstanding.
21250        unsafe { ffi::whiteout_m3_M3Model_resize_attachmentVolumesAddon0(self.raw.as_ptr(), count) }
21251    }
21252
21253    /// Attachment volume addon 1 (U16_)
21254    /// Zero-copy view of the underlying `std::vector`.
21255    pub fn attachment_volumes_addon_1(&self) -> &[u16] {
21256        // SAFETY: `_data`/`_count` describe one contiguous C++
21257        // allocation, borrowed for as long as `self` is.
21258        unsafe {
21259            let n = ffi::whiteout_m3_M3Model_get_attachmentVolumesAddon1_count(self.raw.as_ptr());
21260            let p = ffi::whiteout_m3_M3Model_get_attachmentVolumesAddon1_data(self.raw.as_ptr());
21261            if p.is_null() || n == 0 {
21262                &[]
21263            } else {
21264                core::slice::from_raw_parts(p, n)
21265            }
21266        }
21267    }
21268
21269    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
21270    pub fn attachment_volumes_addon_1_mut(&mut self) -> &mut [u16] {
21271        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
21272        unsafe {
21273            let n = ffi::whiteout_m3_M3Model_get_attachmentVolumesAddon1_count(self.raw.as_ptr());
21274            let p = ffi::whiteout_m3_M3Model_get_attachmentVolumesAddon1_data(self.raw.as_ptr())
21275                as *mut u16;
21276            if p.is_null() || n == 0 {
21277                &mut []
21278            } else {
21279                core::slice::from_raw_parts_mut(p, n)
21280            }
21281        }
21282    }
21283
21284    pub fn set_attachment_volumes_addon_1(&mut self, values: &[u16]) {
21285        // SAFETY: the native side copies `values` before returning.
21286        unsafe {
21287            ffi::whiteout_m3_M3Model_assign_attachmentVolumesAddon1(
21288                self.raw.as_ptr(),
21289                values.as_ptr() as *const _,
21290                values.len(),
21291            )
21292        }
21293    }
21294
21295    pub fn resize_attachment_volumes_addon_1(&mut self, count: usize) {
21296        // SAFETY: reallocation is safe here precisely because
21297        // `&mut self` means no slice borrow is outstanding.
21298        unsafe { ffi::whiteout_m3_M3Model_resize_attachmentVolumesAddon1(self.raw.as_ptr(), count) }
21299    }
21300
21301    /// Billboard behaviors (BBSC)
21302    pub fn billboard_behaviors_len(&self) -> usize {
21303        // SAFETY: scalar read through a live handle.
21304        unsafe { ffi::whiteout_m3_M3Model_get_billboardBehaviors_count(self.raw.as_ptr()) }
21305    }
21306
21307    /// Borrows element `index` in place. `None` when out of range.
21308    pub fn billboard_behaviors(
21309        &self,
21310        index: usize,
21311    ) -> Option<crate::support::Ref<'_, BillboardBehavior>> {
21312        if index >= self.billboard_behaviors_len() {
21313            return None;
21314        }
21315        // SAFETY: index checked above; the pointer is interior to `self`.
21316        unsafe {
21317            Some(crate::support::Ref::new(BillboardBehavior {
21318                raw: core::ptr::NonNull::new_unchecked(
21319                    ffi::whiteout_m3_M3Model_get_billboardBehaviors_at(self.raw.as_ptr(), index),
21320                ),
21321            }))
21322        }
21323    }
21324
21325    pub fn billboard_behaviors_mut(
21326        &mut self,
21327        index: usize,
21328    ) -> Option<crate::support::RefMut<'_, BillboardBehavior>> {
21329        if index >= self.billboard_behaviors_len() {
21330            return None;
21331        }
21332        // SAFETY: as above; `&mut self` guarantees exclusivity.
21333        unsafe {
21334            Some(crate::support::RefMut::new(BillboardBehavior {
21335                raw: core::ptr::NonNull::new_unchecked(
21336                    ffi::whiteout_m3_M3Model_get_billboardBehaviors_at(self.raw.as_ptr(), index),
21337                ),
21338            }))
21339        }
21340    }
21341
21342    /// Iterate the elements, borrowing each in turn.
21343    pub fn billboard_behaviors_iter(
21344        &self,
21345    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, BillboardBehavior>> {
21346        (0..self.billboard_behaviors_len())
21347            .map(move |i| self.billboard_behaviors(i).expect("index below len"))
21348    }
21349
21350    pub fn resize_billboard_behaviors(&mut self, count: usize) {
21351        // SAFETY: exclusive access, so no borrow is outstanding.
21352        unsafe { ffi::whiteout_m3_M3Model_resize_billboardBehaviors(self.raw.as_ptr(), count) }
21353    }
21354
21355    /// Trailing models (TMD_, defunct)
21356    pub fn trailing_models_len(&self) -> usize {
21357        // SAFETY: scalar read through a live handle.
21358        unsafe { ffi::whiteout_m3_M3Model_get_trailingModels_count(self.raw.as_ptr()) }
21359    }
21360
21361    /// Borrows element `index` in place. `None` when out of range.
21362    pub fn trailing_models(&self, index: usize) -> Option<crate::support::Ref<'_, TrailingModel>> {
21363        if index >= self.trailing_models_len() {
21364            return None;
21365        }
21366        // SAFETY: index checked above; the pointer is interior to `self`.
21367        unsafe {
21368            Some(crate::support::Ref::new(TrailingModel {
21369                raw: core::ptr::NonNull::new_unchecked(
21370                    ffi::whiteout_m3_M3Model_get_trailingModels_at(self.raw.as_ptr(), index),
21371                ),
21372            }))
21373        }
21374    }
21375
21376    pub fn trailing_models_mut(
21377        &mut self,
21378        index: usize,
21379    ) -> Option<crate::support::RefMut<'_, TrailingModel>> {
21380        if index >= self.trailing_models_len() {
21381            return None;
21382        }
21383        // SAFETY: as above; `&mut self` guarantees exclusivity.
21384        unsafe {
21385            Some(crate::support::RefMut::new(TrailingModel {
21386                raw: core::ptr::NonNull::new_unchecked(
21387                    ffi::whiteout_m3_M3Model_get_trailingModels_at(self.raw.as_ptr(), index),
21388                ),
21389            }))
21390        }
21391    }
21392
21393    /// Iterate the elements, borrowing each in turn.
21394    pub fn trailing_models_iter(
21395        &self,
21396    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, TrailingModel>> {
21397        (0..self.trailing_models_len())
21398            .map(move |i| self.trailing_models(i).expect("index below len"))
21399    }
21400
21401    pub fn resize_trailing_models(&mut self, count: usize) {
21402        // SAFETY: exclusive access, so no borrow is outstanding.
21403        unsafe { ffi::whiteout_m3_M3Model_resize_trailingModels(self.raw.as_ptr(), count) }
21404    }
21405
21406    /// Hash for .m3a animation file binding
21407    pub fn m_3a_anim_hash(&self) -> u32 {
21408        // SAFETY: plain scalar read through a live handle.
21409        unsafe { ffi::whiteout_m3_M3Model_get_m3aAnimHash(self.raw.as_ptr()) }
21410    }
21411
21412    pub fn set_m_3a_anim_hash(&mut self, value: u32) {
21413        // SAFETY: plain scalar write through a live handle.
21414        unsafe { ffi::whiteout_m3_M3Model_set_m3aAnimHash(self.raw.as_ptr(), value) }
21415    }
21416
21417    /// Additional .m3a hashes (U32_)
21418    /// Zero-copy view of the underlying `std::vector`.
21419    pub fn m_3a_anim_hashes(&self) -> &[u32] {
21420        // SAFETY: `_data`/`_count` describe one contiguous C++
21421        // allocation, borrowed for as long as `self` is.
21422        unsafe {
21423            let n = ffi::whiteout_m3_M3Model_get_m3aAnimHashes_count(self.raw.as_ptr());
21424            let p = ffi::whiteout_m3_M3Model_get_m3aAnimHashes_data(self.raw.as_ptr());
21425            if p.is_null() || n == 0 {
21426                &[]
21427            } else {
21428                core::slice::from_raw_parts(p, n)
21429            }
21430        }
21431    }
21432
21433    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
21434    pub fn m_3a_anim_hashes_mut(&mut self) -> &mut [u32] {
21435        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
21436        unsafe {
21437            let n = ffi::whiteout_m3_M3Model_get_m3aAnimHashes_count(self.raw.as_ptr());
21438            let p = ffi::whiteout_m3_M3Model_get_m3aAnimHashes_data(self.raw.as_ptr()) as *mut u32;
21439            if p.is_null() || n == 0 {
21440                &mut []
21441            } else {
21442                core::slice::from_raw_parts_mut(p, n)
21443            }
21444        }
21445    }
21446
21447    pub fn set_m_3a_anim_hashes(&mut self, values: &[u32]) {
21448        // SAFETY: the native side copies `values` before returning.
21449        unsafe {
21450            ffi::whiteout_m3_M3Model_assign_m3aAnimHashes(
21451                self.raw.as_ptr(),
21452                values.as_ptr() as *const _,
21453                values.len(),
21454            )
21455        }
21456    }
21457
21458    pub fn resize_m_3a_anim_hashes(&mut self, count: usize) {
21459        // SAFETY: reallocation is safe here precisely because
21460        // `&mut self` means no slice borrow is outstanding.
21461        unsafe { ffi::whiteout_m3_M3Model_resize_m3aAnimHashes(self.raw.as_ptr(), count) }
21462    }
21463}
21464
21465impl Default for Model {
21466    fn default() -> Self {
21467        Self::new()
21468    }
21469}
21470
21471/// Parser for M3 model files
21472///
21473/// The Parser reads binary M3 files and converts them into the Model structure. It supports multiple parsing modes for error handling.
21474///
21475/// Uses the PImpl (Pointer to Implementation) idiom to hide implementation details.
21476pub struct Parser {
21477    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3Parser>,
21478}
21479
21480impl Drop for Parser {
21481    fn drop(&mut self) {
21482        // SAFETY: `raw` came from a native constructor and Drop runs once.
21483        unsafe { ffi::whiteout_m3_M3Parser_delete(self.raw.as_ptr()) }
21484    }
21485}
21486
21487impl Parser {
21488    /// # Safety
21489    /// `raw` must be a live handle this value takes ownership of.
21490    #[allow(dead_code)] // used by whichever methods return this type
21491    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3Parser) -> Option<Self> {
21492        core::ptr::NonNull::new(raw).map(|raw| Parser { raw })
21493    }
21494}
21495
21496// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
21497// is deliberately NOT implemented — the C++ types make no documented
21498// guarantee about concurrent use, and claiming one we haven't verified
21499// would be unsound. See `@bind thread_safe` in the plan.
21500unsafe impl Send for Parser {}
21501
21502impl core::fmt::Debug for Parser {
21503    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
21504        f.debug_struct("Parser").finish_non_exhaustive()
21505    }
21506}
21507
21508impl Parser {
21509    /// # Panics
21510    /// Panics if the native allocation fails.
21511    pub fn new() -> Self {
21512        // SAFETY: the native constructor returns a live handle; a null here
21513        // means the library is unusable.
21514        unsafe {
21515            let raw = ffi::whiteout_m3_M3Parser_new();
21516            Self::from_raw(raw).expect("native Parser allocation failed")
21517        }
21518    }
21519
21520    /// Parse an M3 file from disk @param filePath Path to the M3 file @return Parsed M3 model data @throws std::runtime_error If file cannot be opened or parsing fails in strict mode
21521    pub fn parse_file(&mut self, file_path: &str) -> Option<Model> {
21522        let file_path_cstr = std::ffi::CString::new(file_path).unwrap_or_default();
21523        // SAFETY: handle is live for the duration of the call.
21524        unsafe {
21525            Model::from_raw(ffi::whiteout_m3_M3Parser_parse(
21526                self.raw.as_ptr(),
21527                file_path_cstr.as_ptr(),
21528            ))
21529        }
21530    }
21531
21532    /// Parse an M3 file from memory buffer @param buffer Memory buffer containing M3 data @return Parsed M3 model data @throws std::runtime_error If parsing fails in strict mode
21533    pub fn parse(&mut self, buffer: &[u8]) -> Option<Model> {
21534        // SAFETY: handle is live for the duration of the call.
21535        unsafe {
21536            Model::from_raw(ffi::whiteout_m3_M3Parser_parse_buffer(
21537                self.raw.as_ptr(),
21538                buffer.as_ptr(),
21539                buffer.len(),
21540            ))
21541        }
21542    }
21543
21544    /// Check if parsing encountered any issues @return True if there were warnings or recoverable errors
21545    pub fn has_issues(&self) -> bool {
21546        // SAFETY: handle is live for the duration of the call.
21547        unsafe { ffi::whiteout_m3_M3Parser_hasIssues(self.raw.as_ptr()) != 0 }
21548    }
21549
21550    /// Get list of issues encountered during parsing @return Vector of issue description strings
21551    pub fn issues(&self) -> Vec<String> {
21552        // SAFETY: index stays below the reported count.
21553        unsafe {
21554            let n = ffi::whiteout_m3_M3Parser_getIssues_count(self.raw.as_ptr());
21555            (0..n)
21556                .map(|i| {
21557                    crate::support::take_string(ffi::whiteout_m3_M3Parser_getIssues_at(
21558                        self.raw.as_ptr(),
21559                        i,
21560                    ))
21561                })
21562                .collect()
21563        }
21564    }
21565}
21566
21567impl Default for Parser {
21568    fn default() -> Self {
21569        Self::new()
21570    }
21571}
21572
21573/// Writer for M3 model files
21574///
21575/// Writes Model structures to disk in binary M3 format. Uses the PImpl (Pointer to Implementation) idiom to hide implementation details.
21576pub struct Writer {
21577    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3Writer>,
21578}
21579
21580impl Drop for Writer {
21581    fn drop(&mut self) {
21582        // SAFETY: `raw` came from a native constructor and Drop runs once.
21583        unsafe { ffi::whiteout_m3_M3Writer_delete(self.raw.as_ptr()) }
21584    }
21585}
21586
21587impl Writer {
21588    /// # Safety
21589    /// `raw` must be a live handle this value takes ownership of.
21590    #[allow(dead_code)] // used by whichever methods return this type
21591    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3Writer) -> Option<Self> {
21592        core::ptr::NonNull::new(raw).map(|raw| Writer { raw })
21593    }
21594}
21595
21596// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
21597// is deliberately NOT implemented — the C++ types make no documented
21598// guarantee about concurrent use, and claiming one we haven't verified
21599// would be unsound. See `@bind thread_safe` in the plan.
21600unsafe impl Send for Writer {}
21601
21602impl core::fmt::Debug for Writer {
21603    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
21604        f.debug_struct("Writer").finish_non_exhaustive()
21605    }
21606}
21607
21608impl Writer {
21609    /// # Panics
21610    /// Panics if the native allocation fails.
21611    pub fn new() -> Self {
21612        // SAFETY: the native constructor returns a live handle; a null here
21613        // means the library is unusable.
21614        unsafe {
21615            let raw = ffi::whiteout_m3_M3Writer_new();
21616            Self::from_raw(raw).expect("native Writer allocation failed")
21617        }
21618    }
21619
21620    /// Write an M3 model to a file on disk @param filePath Output file path @param model Model data to serialize @throws std::runtime_error If file cannot be created or writing fails
21621    pub fn write_file(&mut self, file_path: &str, model: &Model) {
21622        let file_path_cstr = std::ffi::CString::new(file_path).unwrap_or_default();
21623        // SAFETY: handle is live for the duration of the call.
21624        unsafe {
21625            ffi::whiteout_m3_M3Writer_write(
21626                self.raw.as_ptr(),
21627                file_path_cstr.as_ptr(),
21628                model.raw.as_ptr(),
21629            );
21630        }
21631    }
21632
21633    /// Write an M3 model to a byte buffer @param model Model data to serialize @return Byte buffer containing the M3 file data
21634    pub fn write(&mut self, model: &Model) -> Bytes {
21635        // SAFETY: handle is live for the duration of the call.
21636        unsafe {
21637            Bytes::from_raw(ffi::whiteout_m3_M3Writer_write_model(
21638                self.raw.as_ptr(),
21639                model.raw.as_ptr(),
21640            ))
21641            .unwrap_or_else(Bytes::empty)
21642        }
21643    }
21644}
21645
21646impl Default for Writer {
21647    fn default() -> Self {
21648        Self::new()
21649    }
21650}
21651
21652/// Animatable reference holding a default value and animation link
21653///
21654/// Holds both a constant default value and a link to keyframed animation data. If animId == 0, the property is not animated — use initValue as a constant. Otherwise, resolve through STC_.animIds to locate keyframe data. Total size depends on sizeof(T): 12 + 2*sizeof(T) + 4 bytes.
21655///
21656/// @tparam T The value type (f32, Vector3f, Quaternion, ColorBGRA, Extent, etc.)
21657pub struct AnimRefF32 {
21658    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3AnimRefF32>,
21659}
21660
21661impl Drop for AnimRefF32 {
21662    fn drop(&mut self) {
21663        // SAFETY: `raw` came from a native constructor and Drop runs once.
21664        unsafe { ffi::whiteout_m3_M3AnimRefF32_delete(self.raw.as_ptr()) }
21665    }
21666}
21667
21668impl AnimRefF32 {
21669    /// # Safety
21670    /// `raw` must be a live handle this value takes ownership of.
21671    #[allow(dead_code)] // used by whichever methods return this type
21672    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3AnimRefF32) -> Option<Self> {
21673        core::ptr::NonNull::new(raw).map(|raw| AnimRefF32 { raw })
21674    }
21675}
21676
21677// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
21678// is deliberately NOT implemented — the C++ types make no documented
21679// guarantee about concurrent use, and claiming one we haven't verified
21680// would be unsound. See `@bind thread_safe` in the plan.
21681unsafe impl Send for AnimRefF32 {}
21682
21683impl core::fmt::Debug for AnimRefF32 {
21684    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
21685        f.debug_struct("AnimRefF32").finish_non_exhaustive()
21686    }
21687}
21688
21689impl AnimRefF32 {
21690    /// # Panics
21691    /// Panics if the native allocation fails.
21692    pub fn new() -> Self {
21693        // SAFETY: the native constructor returns a live handle; a null here
21694        // means the library is unusable.
21695        unsafe {
21696            let raw = ffi::whiteout_m3_M3AnimRefF32_new();
21697            Self::from_raw(raw).expect("native AnimRefF32 allocation failed")
21698        }
21699    }
21700
21701    /// Interpolation: 0=none/step, 1=linear, 2=hermite, 3=bezier
21702    pub fn interp_type(&self) -> u16 {
21703        // SAFETY: plain scalar read through a live handle.
21704        unsafe { ffi::whiteout_m3_M3AnimRefF32_get_interpType(self.raw.as_ptr()) }
21705    }
21706
21707    pub fn set_interp_type(&mut self, value: u16) {
21708        // SAFETY: plain scalar write through a live handle.
21709        unsafe { ffi::whiteout_m3_M3AnimRefF32_set_interpType(self.raw.as_ptr(), value) }
21710    }
21711
21712    /// Animation flags
21713    pub fn flags(&self) -> u16 {
21714        // SAFETY: plain scalar read through a live handle.
21715        unsafe { ffi::whiteout_m3_M3AnimRefF32_get_flags(self.raw.as_ptr()) }
21716    }
21717
21718    pub fn set_flags(&mut self, value: u16) {
21719        // SAFETY: plain scalar write through a live handle.
21720        unsafe { ffi::whiteout_m3_M3AnimRefF32_set_flags(self.raw.as_ptr(), value) }
21721    }
21722
21723    /// Animation identifier (links to STC animation data; 0=not animated)
21724    pub fn anim_id(&self) -> u32 {
21725        // SAFETY: plain scalar read through a live handle.
21726        unsafe { ffi::whiteout_m3_M3AnimRefF32_get_animId(self.raw.as_ptr()) }
21727    }
21728
21729    pub fn set_anim_id(&mut self, value: u32) {
21730        // SAFETY: plain scalar write through a live handle.
21731        unsafe { ffi::whiteout_m3_M3AnimRefF32_set_animId(self.raw.as_ptr(), value) }
21732    }
21733
21734    /// Initial/default value (used when not animated)
21735    pub fn init_value(&self) -> f32 {
21736        // SAFETY: plain scalar read through a live handle.
21737        unsafe { ffi::whiteout_m3_M3AnimRefF32_get_initValue(self.raw.as_ptr()) }
21738    }
21739
21740    pub fn set_init_value(&mut self, value: f32) {
21741        // SAFETY: plain scalar write through a live handle.
21742        unsafe { ffi::whiteout_m3_M3AnimRefF32_set_initValue(self.raw.as_ptr(), value) }
21743    }
21744
21745    /// Null/reset value
21746    pub fn null_value(&self) -> f32 {
21747        // SAFETY: plain scalar read through a live handle.
21748        unsafe { ffi::whiteout_m3_M3AnimRefF32_get_nullValue(self.raw.as_ptr()) }
21749    }
21750
21751    pub fn set_null_value(&mut self, value: f32) {
21752        // SAFETY: plain scalar write through a live handle.
21753        unsafe { ffi::whiteout_m3_M3AnimRefF32_set_nullValue(self.raw.as_ptr(), value) }
21754    }
21755
21756    /// Typically -1
21757    pub fn unused(&self) -> i32 {
21758        // SAFETY: plain scalar read through a live handle.
21759        unsafe { ffi::whiteout_m3_M3AnimRefF32_get_unused(self.raw.as_ptr()) }
21760    }
21761
21762    pub fn set_unused(&mut self, value: i32) {
21763        // SAFETY: plain scalar write through a live handle.
21764        unsafe { ffi::whiteout_m3_M3AnimRefF32_set_unused(self.raw.as_ptr(), value) }
21765    }
21766}
21767
21768impl Default for AnimRefF32 {
21769    fn default() -> Self {
21770        Self::new()
21771    }
21772}
21773
21774/// Animatable reference holding a default value and animation link
21775///
21776/// Holds both a constant default value and a link to keyframed animation data. If animId == 0, the property is not animated — use initValue as a constant. Otherwise, resolve through STC_.animIds to locate keyframe data. Total size depends on sizeof(T): 12 + 2*sizeof(T) + 4 bytes.
21777///
21778/// @tparam T The value type (f32, Vector3f, Quaternion, ColorBGRA, Extent, etc.)
21779pub struct AnimRefVector3f {
21780    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3AnimRefVector3f>,
21781}
21782
21783impl Drop for AnimRefVector3f {
21784    fn drop(&mut self) {
21785        // SAFETY: `raw` came from a native constructor and Drop runs once.
21786        unsafe { ffi::whiteout_m3_M3AnimRefVector3f_delete(self.raw.as_ptr()) }
21787    }
21788}
21789
21790impl AnimRefVector3f {
21791    /// # Safety
21792    /// `raw` must be a live handle this value takes ownership of.
21793    #[allow(dead_code)] // used by whichever methods return this type
21794    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3AnimRefVector3f) -> Option<Self> {
21795        core::ptr::NonNull::new(raw).map(|raw| AnimRefVector3f { raw })
21796    }
21797}
21798
21799// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
21800// is deliberately NOT implemented — the C++ types make no documented
21801// guarantee about concurrent use, and claiming one we haven't verified
21802// would be unsound. See `@bind thread_safe` in the plan.
21803unsafe impl Send for AnimRefVector3f {}
21804
21805impl core::fmt::Debug for AnimRefVector3f {
21806    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
21807        f.debug_struct("AnimRefVector3f").finish_non_exhaustive()
21808    }
21809}
21810
21811impl AnimRefVector3f {
21812    /// # Panics
21813    /// Panics if the native allocation fails.
21814    pub fn new() -> Self {
21815        // SAFETY: the native constructor returns a live handle; a null here
21816        // means the library is unusable.
21817        unsafe {
21818            let raw = ffi::whiteout_m3_M3AnimRefVector3f_new();
21819            Self::from_raw(raw).expect("native AnimRefVector3f allocation failed")
21820        }
21821    }
21822
21823    /// Interpolation: 0=none/step, 1=linear, 2=hermite, 3=bezier
21824    pub fn interp_type(&self) -> u16 {
21825        // SAFETY: plain scalar read through a live handle.
21826        unsafe { ffi::whiteout_m3_M3AnimRefVector3f_get_interpType(self.raw.as_ptr()) }
21827    }
21828
21829    pub fn set_interp_type(&mut self, value: u16) {
21830        // SAFETY: plain scalar write through a live handle.
21831        unsafe { ffi::whiteout_m3_M3AnimRefVector3f_set_interpType(self.raw.as_ptr(), value) }
21832    }
21833
21834    /// Animation flags
21835    pub fn flags(&self) -> u16 {
21836        // SAFETY: plain scalar read through a live handle.
21837        unsafe { ffi::whiteout_m3_M3AnimRefVector3f_get_flags(self.raw.as_ptr()) }
21838    }
21839
21840    pub fn set_flags(&mut self, value: u16) {
21841        // SAFETY: plain scalar write through a live handle.
21842        unsafe { ffi::whiteout_m3_M3AnimRefVector3f_set_flags(self.raw.as_ptr(), value) }
21843    }
21844
21845    /// Animation identifier (links to STC animation data; 0=not animated)
21846    pub fn anim_id(&self) -> u32 {
21847        // SAFETY: plain scalar read through a live handle.
21848        unsafe { ffi::whiteout_m3_M3AnimRefVector3f_get_animId(self.raw.as_ptr()) }
21849    }
21850
21851    pub fn set_anim_id(&mut self, value: u32) {
21852        // SAFETY: plain scalar write through a live handle.
21853        unsafe { ffi::whiteout_m3_M3AnimRefVector3f_set_animId(self.raw.as_ptr(), value) }
21854    }
21855
21856    /// Initial/default value (used when not animated)
21857    pub fn init_value(&self) -> crate::math::Vector3f {
21858        // SAFETY: the getter returns an interior pointer to a
21859        // layout-identical POD; we copy it out immediately.
21860        unsafe {
21861            *(ffi::whiteout_m3_M3AnimRefVector3f_get_initValue(self.raw.as_ptr())
21862                as *const crate::math::Vector3f)
21863        }
21864    }
21865
21866    pub fn set_init_value(&mut self, value: crate::math::Vector3f) {
21867        // SAFETY: as above, in the other direction.
21868        unsafe {
21869            ffi::whiteout_m3_M3AnimRefVector3f_set_initValue(
21870                self.raw.as_ptr(),
21871                &value as *const crate::math::Vector3f as *const _,
21872            )
21873        }
21874    }
21875
21876    /// Null/reset value
21877    pub fn null_value(&self) -> crate::math::Vector3f {
21878        // SAFETY: the getter returns an interior pointer to a
21879        // layout-identical POD; we copy it out immediately.
21880        unsafe {
21881            *(ffi::whiteout_m3_M3AnimRefVector3f_get_nullValue(self.raw.as_ptr())
21882                as *const crate::math::Vector3f)
21883        }
21884    }
21885
21886    pub fn set_null_value(&mut self, value: crate::math::Vector3f) {
21887        // SAFETY: as above, in the other direction.
21888        unsafe {
21889            ffi::whiteout_m3_M3AnimRefVector3f_set_nullValue(
21890                self.raw.as_ptr(),
21891                &value as *const crate::math::Vector3f as *const _,
21892            )
21893        }
21894    }
21895
21896    /// Typically -1
21897    pub fn unused(&self) -> i32 {
21898        // SAFETY: plain scalar read through a live handle.
21899        unsafe { ffi::whiteout_m3_M3AnimRefVector3f_get_unused(self.raw.as_ptr()) }
21900    }
21901
21902    pub fn set_unused(&mut self, value: i32) {
21903        // SAFETY: plain scalar write through a live handle.
21904        unsafe { ffi::whiteout_m3_M3AnimRefVector3f_set_unused(self.raw.as_ptr(), value) }
21905    }
21906}
21907
21908impl Default for AnimRefVector3f {
21909    fn default() -> Self {
21910        Self::new()
21911    }
21912}
21913
21914/// Animatable reference holding a default value and animation link
21915///
21916/// Holds both a constant default value and a link to keyframed animation data. If animId == 0, the property is not animated — use initValue as a constant. Otherwise, resolve through STC_.animIds to locate keyframe data. Total size depends on sizeof(T): 12 + 2*sizeof(T) + 4 bytes.
21917///
21918/// @tparam T The value type (f32, Vector3f, Quaternion, ColorBGRA, Extent, etc.)
21919pub struct AnimRefM3ColorBGRA {
21920    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3AnimRefM3ColorBGRA>,
21921}
21922
21923impl Drop for AnimRefM3ColorBGRA {
21924    fn drop(&mut self) {
21925        // SAFETY: `raw` came from a native constructor and Drop runs once.
21926        unsafe { ffi::whiteout_m3_M3AnimRefM3ColorBGRA_delete(self.raw.as_ptr()) }
21927    }
21928}
21929
21930impl AnimRefM3ColorBGRA {
21931    /// # Safety
21932    /// `raw` must be a live handle this value takes ownership of.
21933    #[allow(dead_code)] // used by whichever methods return this type
21934    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3AnimRefM3ColorBGRA) -> Option<Self> {
21935        core::ptr::NonNull::new(raw).map(|raw| AnimRefM3ColorBGRA { raw })
21936    }
21937}
21938
21939// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
21940// is deliberately NOT implemented — the C++ types make no documented
21941// guarantee about concurrent use, and claiming one we haven't verified
21942// would be unsound. See `@bind thread_safe` in the plan.
21943unsafe impl Send for AnimRefM3ColorBGRA {}
21944
21945impl core::fmt::Debug for AnimRefM3ColorBGRA {
21946    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
21947        f.debug_struct("AnimRefM3ColorBGRA").finish_non_exhaustive()
21948    }
21949}
21950
21951impl AnimRefM3ColorBGRA {
21952    /// # Panics
21953    /// Panics if the native allocation fails.
21954    pub fn new() -> Self {
21955        // SAFETY: the native constructor returns a live handle; a null here
21956        // means the library is unusable.
21957        unsafe {
21958            let raw = ffi::whiteout_m3_M3AnimRefM3ColorBGRA_new();
21959            Self::from_raw(raw).expect("native AnimRefM3ColorBGRA allocation failed")
21960        }
21961    }
21962
21963    /// Interpolation: 0=none/step, 1=linear, 2=hermite, 3=bezier
21964    pub fn interp_type(&self) -> u16 {
21965        // SAFETY: plain scalar read through a live handle.
21966        unsafe { ffi::whiteout_m3_M3AnimRefM3ColorBGRA_get_interpType(self.raw.as_ptr()) }
21967    }
21968
21969    pub fn set_interp_type(&mut self, value: u16) {
21970        // SAFETY: plain scalar write through a live handle.
21971        unsafe { ffi::whiteout_m3_M3AnimRefM3ColorBGRA_set_interpType(self.raw.as_ptr(), value) }
21972    }
21973
21974    /// Animation flags
21975    pub fn flags(&self) -> u16 {
21976        // SAFETY: plain scalar read through a live handle.
21977        unsafe { ffi::whiteout_m3_M3AnimRefM3ColorBGRA_get_flags(self.raw.as_ptr()) }
21978    }
21979
21980    pub fn set_flags(&mut self, value: u16) {
21981        // SAFETY: plain scalar write through a live handle.
21982        unsafe { ffi::whiteout_m3_M3AnimRefM3ColorBGRA_set_flags(self.raw.as_ptr(), value) }
21983    }
21984
21985    /// Animation identifier (links to STC animation data; 0=not animated)
21986    pub fn anim_id(&self) -> u32 {
21987        // SAFETY: plain scalar read through a live handle.
21988        unsafe { ffi::whiteout_m3_M3AnimRefM3ColorBGRA_get_animId(self.raw.as_ptr()) }
21989    }
21990
21991    pub fn set_anim_id(&mut self, value: u32) {
21992        // SAFETY: plain scalar write through a live handle.
21993        unsafe { ffi::whiteout_m3_M3AnimRefM3ColorBGRA_set_animId(self.raw.as_ptr(), value) }
21994    }
21995
21996    /// Initial/default value (used when not animated)
21997    /// Borrows the field in place — no copy, no allocation.
21998    pub fn init_value(&self) -> crate::support::Ref<'_, ColorBGRA> {
21999        // SAFETY: an interior pointer into `self`, valid for this
22000        // borrow and never freed by the `Ref`.
22001        unsafe {
22002            crate::support::Ref::new(ColorBGRA {
22003                raw: core::ptr::NonNull::new_unchecked(
22004                    ffi::whiteout_m3_M3AnimRefM3ColorBGRA_get_initValue(self.raw.as_ptr()),
22005                ),
22006            })
22007        }
22008    }
22009
22010    pub fn init_value_mut(&mut self) -> crate::support::RefMut<'_, ColorBGRA> {
22011        // SAFETY: as above; `&mut self` guarantees exclusivity.
22012        unsafe {
22013            crate::support::RefMut::new(ColorBGRA {
22014                raw: core::ptr::NonNull::new_unchecked(
22015                    ffi::whiteout_m3_M3AnimRefM3ColorBGRA_get_initValue(self.raw.as_ptr()),
22016                ),
22017            })
22018        }
22019    }
22020
22021    /// Null/reset value
22022    /// Borrows the field in place — no copy, no allocation.
22023    pub fn null_value(&self) -> crate::support::Ref<'_, ColorBGRA> {
22024        // SAFETY: an interior pointer into `self`, valid for this
22025        // borrow and never freed by the `Ref`.
22026        unsafe {
22027            crate::support::Ref::new(ColorBGRA {
22028                raw: core::ptr::NonNull::new_unchecked(
22029                    ffi::whiteout_m3_M3AnimRefM3ColorBGRA_get_nullValue(self.raw.as_ptr()),
22030                ),
22031            })
22032        }
22033    }
22034
22035    pub fn null_value_mut(&mut self) -> crate::support::RefMut<'_, ColorBGRA> {
22036        // SAFETY: as above; `&mut self` guarantees exclusivity.
22037        unsafe {
22038            crate::support::RefMut::new(ColorBGRA {
22039                raw: core::ptr::NonNull::new_unchecked(
22040                    ffi::whiteout_m3_M3AnimRefM3ColorBGRA_get_nullValue(self.raw.as_ptr()),
22041                ),
22042            })
22043        }
22044    }
22045
22046    /// Typically -1
22047    pub fn unused(&self) -> i32 {
22048        // SAFETY: plain scalar read through a live handle.
22049        unsafe { ffi::whiteout_m3_M3AnimRefM3ColorBGRA_get_unused(self.raw.as_ptr()) }
22050    }
22051
22052    pub fn set_unused(&mut self, value: i32) {
22053        // SAFETY: plain scalar write through a live handle.
22054        unsafe { ffi::whiteout_m3_M3AnimRefM3ColorBGRA_set_unused(self.raw.as_ptr(), value) }
22055    }
22056}
22057
22058impl Default for AnimRefM3ColorBGRA {
22059    fn default() -> Self {
22060        Self::new()
22061    }
22062}
22063
22064/// Animatable reference holding a default value and animation link
22065///
22066/// Holds both a constant default value and a link to keyframed animation data. If animId == 0, the property is not animated — use initValue as a constant. Otherwise, resolve through STC_.animIds to locate keyframe data. Total size depends on sizeof(T): 12 + 2*sizeof(T) + 4 bytes.
22067///
22068/// @tparam T The value type (f32, Vector3f, Quaternion, ColorBGRA, Extent, etc.)
22069pub struct AnimRefU16 {
22070    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3AnimRefU16>,
22071}
22072
22073impl Drop for AnimRefU16 {
22074    fn drop(&mut self) {
22075        // SAFETY: `raw` came from a native constructor and Drop runs once.
22076        unsafe { ffi::whiteout_m3_M3AnimRefU16_delete(self.raw.as_ptr()) }
22077    }
22078}
22079
22080impl AnimRefU16 {
22081    /// # Safety
22082    /// `raw` must be a live handle this value takes ownership of.
22083    #[allow(dead_code)] // used by whichever methods return this type
22084    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3AnimRefU16) -> Option<Self> {
22085        core::ptr::NonNull::new(raw).map(|raw| AnimRefU16 { raw })
22086    }
22087}
22088
22089// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
22090// is deliberately NOT implemented — the C++ types make no documented
22091// guarantee about concurrent use, and claiming one we haven't verified
22092// would be unsound. See `@bind thread_safe` in the plan.
22093unsafe impl Send for AnimRefU16 {}
22094
22095impl core::fmt::Debug for AnimRefU16 {
22096    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
22097        f.debug_struct("AnimRefU16").finish_non_exhaustive()
22098    }
22099}
22100
22101impl AnimRefU16 {
22102    /// # Panics
22103    /// Panics if the native allocation fails.
22104    pub fn new() -> Self {
22105        // SAFETY: the native constructor returns a live handle; a null here
22106        // means the library is unusable.
22107        unsafe {
22108            let raw = ffi::whiteout_m3_M3AnimRefU16_new();
22109            Self::from_raw(raw).expect("native AnimRefU16 allocation failed")
22110        }
22111    }
22112
22113    /// Interpolation: 0=none/step, 1=linear, 2=hermite, 3=bezier
22114    pub fn interp_type(&self) -> u16 {
22115        // SAFETY: plain scalar read through a live handle.
22116        unsafe { ffi::whiteout_m3_M3AnimRefU16_get_interpType(self.raw.as_ptr()) }
22117    }
22118
22119    pub fn set_interp_type(&mut self, value: u16) {
22120        // SAFETY: plain scalar write through a live handle.
22121        unsafe { ffi::whiteout_m3_M3AnimRefU16_set_interpType(self.raw.as_ptr(), value) }
22122    }
22123
22124    /// Animation flags
22125    pub fn flags(&self) -> u16 {
22126        // SAFETY: plain scalar read through a live handle.
22127        unsafe { ffi::whiteout_m3_M3AnimRefU16_get_flags(self.raw.as_ptr()) }
22128    }
22129
22130    pub fn set_flags(&mut self, value: u16) {
22131        // SAFETY: plain scalar write through a live handle.
22132        unsafe { ffi::whiteout_m3_M3AnimRefU16_set_flags(self.raw.as_ptr(), value) }
22133    }
22134
22135    /// Animation identifier (links to STC animation data; 0=not animated)
22136    pub fn anim_id(&self) -> u32 {
22137        // SAFETY: plain scalar read through a live handle.
22138        unsafe { ffi::whiteout_m3_M3AnimRefU16_get_animId(self.raw.as_ptr()) }
22139    }
22140
22141    pub fn set_anim_id(&mut self, value: u32) {
22142        // SAFETY: plain scalar write through a live handle.
22143        unsafe { ffi::whiteout_m3_M3AnimRefU16_set_animId(self.raw.as_ptr(), value) }
22144    }
22145
22146    /// Initial/default value (used when not animated)
22147    pub fn init_value(&self) -> u16 {
22148        // SAFETY: plain scalar read through a live handle.
22149        unsafe { ffi::whiteout_m3_M3AnimRefU16_get_initValue(self.raw.as_ptr()) }
22150    }
22151
22152    pub fn set_init_value(&mut self, value: u16) {
22153        // SAFETY: plain scalar write through a live handle.
22154        unsafe { ffi::whiteout_m3_M3AnimRefU16_set_initValue(self.raw.as_ptr(), value) }
22155    }
22156
22157    /// Null/reset value
22158    pub fn null_value(&self) -> u16 {
22159        // SAFETY: plain scalar read through a live handle.
22160        unsafe { ffi::whiteout_m3_M3AnimRefU16_get_nullValue(self.raw.as_ptr()) }
22161    }
22162
22163    pub fn set_null_value(&mut self, value: u16) {
22164        // SAFETY: plain scalar write through a live handle.
22165        unsafe { ffi::whiteout_m3_M3AnimRefU16_set_nullValue(self.raw.as_ptr(), value) }
22166    }
22167
22168    /// Typically -1
22169    pub fn unused(&self) -> i32 {
22170        // SAFETY: plain scalar read through a live handle.
22171        unsafe { ffi::whiteout_m3_M3AnimRefU16_get_unused(self.raw.as_ptr()) }
22172    }
22173
22174    pub fn set_unused(&mut self, value: i32) {
22175        // SAFETY: plain scalar write through a live handle.
22176        unsafe { ffi::whiteout_m3_M3AnimRefU16_set_unused(self.raw.as_ptr(), value) }
22177    }
22178}
22179
22180impl Default for AnimRefU16 {
22181    fn default() -> Self {
22182        Self::new()
22183    }
22184}
22185
22186/// Animatable reference holding a default value and animation link
22187///
22188/// Holds both a constant default value and a link to keyframed animation data. If animId == 0, the property is not animated — use initValue as a constant. Otherwise, resolve through STC_.animIds to locate keyframe data. Total size depends on sizeof(T): 12 + 2*sizeof(T) + 4 bytes.
22189///
22190/// @tparam T The value type (f32, Vector3f, Quaternion, ColorBGRA, Extent, etc.)
22191pub struct AnimRefVector2f {
22192    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3AnimRefVector2f>,
22193}
22194
22195impl Drop for AnimRefVector2f {
22196    fn drop(&mut self) {
22197        // SAFETY: `raw` came from a native constructor and Drop runs once.
22198        unsafe { ffi::whiteout_m3_M3AnimRefVector2f_delete(self.raw.as_ptr()) }
22199    }
22200}
22201
22202impl AnimRefVector2f {
22203    /// # Safety
22204    /// `raw` must be a live handle this value takes ownership of.
22205    #[allow(dead_code)] // used by whichever methods return this type
22206    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3AnimRefVector2f) -> Option<Self> {
22207        core::ptr::NonNull::new(raw).map(|raw| AnimRefVector2f { raw })
22208    }
22209}
22210
22211// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
22212// is deliberately NOT implemented — the C++ types make no documented
22213// guarantee about concurrent use, and claiming one we haven't verified
22214// would be unsound. See `@bind thread_safe` in the plan.
22215unsafe impl Send for AnimRefVector2f {}
22216
22217impl core::fmt::Debug for AnimRefVector2f {
22218    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
22219        f.debug_struct("AnimRefVector2f").finish_non_exhaustive()
22220    }
22221}
22222
22223impl AnimRefVector2f {
22224    /// # Panics
22225    /// Panics if the native allocation fails.
22226    pub fn new() -> Self {
22227        // SAFETY: the native constructor returns a live handle; a null here
22228        // means the library is unusable.
22229        unsafe {
22230            let raw = ffi::whiteout_m3_M3AnimRefVector2f_new();
22231            Self::from_raw(raw).expect("native AnimRefVector2f allocation failed")
22232        }
22233    }
22234
22235    /// Interpolation: 0=none/step, 1=linear, 2=hermite, 3=bezier
22236    pub fn interp_type(&self) -> u16 {
22237        // SAFETY: plain scalar read through a live handle.
22238        unsafe { ffi::whiteout_m3_M3AnimRefVector2f_get_interpType(self.raw.as_ptr()) }
22239    }
22240
22241    pub fn set_interp_type(&mut self, value: u16) {
22242        // SAFETY: plain scalar write through a live handle.
22243        unsafe { ffi::whiteout_m3_M3AnimRefVector2f_set_interpType(self.raw.as_ptr(), value) }
22244    }
22245
22246    /// Animation flags
22247    pub fn flags(&self) -> u16 {
22248        // SAFETY: plain scalar read through a live handle.
22249        unsafe { ffi::whiteout_m3_M3AnimRefVector2f_get_flags(self.raw.as_ptr()) }
22250    }
22251
22252    pub fn set_flags(&mut self, value: u16) {
22253        // SAFETY: plain scalar write through a live handle.
22254        unsafe { ffi::whiteout_m3_M3AnimRefVector2f_set_flags(self.raw.as_ptr(), value) }
22255    }
22256
22257    /// Animation identifier (links to STC animation data; 0=not animated)
22258    pub fn anim_id(&self) -> u32 {
22259        // SAFETY: plain scalar read through a live handle.
22260        unsafe { ffi::whiteout_m3_M3AnimRefVector2f_get_animId(self.raw.as_ptr()) }
22261    }
22262
22263    pub fn set_anim_id(&mut self, value: u32) {
22264        // SAFETY: plain scalar write through a live handle.
22265        unsafe { ffi::whiteout_m3_M3AnimRefVector2f_set_animId(self.raw.as_ptr(), value) }
22266    }
22267
22268    /// Initial/default value (used when not animated)
22269    pub fn init_value(&self) -> crate::math::Vector2f {
22270        // SAFETY: the getter returns an interior pointer to a
22271        // layout-identical POD; we copy it out immediately.
22272        unsafe {
22273            *(ffi::whiteout_m3_M3AnimRefVector2f_get_initValue(self.raw.as_ptr())
22274                as *const crate::math::Vector2f)
22275        }
22276    }
22277
22278    pub fn set_init_value(&mut self, value: crate::math::Vector2f) {
22279        // SAFETY: as above, in the other direction.
22280        unsafe {
22281            ffi::whiteout_m3_M3AnimRefVector2f_set_initValue(
22282                self.raw.as_ptr(),
22283                &value as *const crate::math::Vector2f as *const _,
22284            )
22285        }
22286    }
22287
22288    /// Null/reset value
22289    pub fn null_value(&self) -> crate::math::Vector2f {
22290        // SAFETY: the getter returns an interior pointer to a
22291        // layout-identical POD; we copy it out immediately.
22292        unsafe {
22293            *(ffi::whiteout_m3_M3AnimRefVector2f_get_nullValue(self.raw.as_ptr())
22294                as *const crate::math::Vector2f)
22295        }
22296    }
22297
22298    pub fn set_null_value(&mut self, value: crate::math::Vector2f) {
22299        // SAFETY: as above, in the other direction.
22300        unsafe {
22301            ffi::whiteout_m3_M3AnimRefVector2f_set_nullValue(
22302                self.raw.as_ptr(),
22303                &value as *const crate::math::Vector2f as *const _,
22304            )
22305        }
22306    }
22307
22308    /// Typically -1
22309    pub fn unused(&self) -> i32 {
22310        // SAFETY: plain scalar read through a live handle.
22311        unsafe { ffi::whiteout_m3_M3AnimRefVector2f_get_unused(self.raw.as_ptr()) }
22312    }
22313
22314    pub fn set_unused(&mut self, value: i32) {
22315        // SAFETY: plain scalar write through a live handle.
22316        unsafe { ffi::whiteout_m3_M3AnimRefVector2f_set_unused(self.raw.as_ptr(), value) }
22317    }
22318}
22319
22320impl Default for AnimRefVector2f {
22321    fn default() -> Self {
22322        Self::new()
22323    }
22324}
22325
22326/// Animatable reference holding a default value and animation link
22327///
22328/// Holds both a constant default value and a link to keyframed animation data. If animId == 0, the property is not animated — use initValue as a constant. Otherwise, resolve through STC_.animIds to locate keyframe data. Total size depends on sizeof(T): 12 + 2*sizeof(T) + 4 bytes.
22329///
22330/// @tparam T The value type (f32, Vector3f, Quaternion, ColorBGRA, Extent, etc.)
22331pub struct AnimRefU32 {
22332    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3AnimRefU32>,
22333}
22334
22335impl Drop for AnimRefU32 {
22336    fn drop(&mut self) {
22337        // SAFETY: `raw` came from a native constructor and Drop runs once.
22338        unsafe { ffi::whiteout_m3_M3AnimRefU32_delete(self.raw.as_ptr()) }
22339    }
22340}
22341
22342impl AnimRefU32 {
22343    /// # Safety
22344    /// `raw` must be a live handle this value takes ownership of.
22345    #[allow(dead_code)] // used by whichever methods return this type
22346    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3AnimRefU32) -> Option<Self> {
22347        core::ptr::NonNull::new(raw).map(|raw| AnimRefU32 { raw })
22348    }
22349}
22350
22351// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
22352// is deliberately NOT implemented — the C++ types make no documented
22353// guarantee about concurrent use, and claiming one we haven't verified
22354// would be unsound. See `@bind thread_safe` in the plan.
22355unsafe impl Send for AnimRefU32 {}
22356
22357impl core::fmt::Debug for AnimRefU32 {
22358    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
22359        f.debug_struct("AnimRefU32").finish_non_exhaustive()
22360    }
22361}
22362
22363impl AnimRefU32 {
22364    /// # Panics
22365    /// Panics if the native allocation fails.
22366    pub fn new() -> Self {
22367        // SAFETY: the native constructor returns a live handle; a null here
22368        // means the library is unusable.
22369        unsafe {
22370            let raw = ffi::whiteout_m3_M3AnimRefU32_new();
22371            Self::from_raw(raw).expect("native AnimRefU32 allocation failed")
22372        }
22373    }
22374
22375    /// Interpolation: 0=none/step, 1=linear, 2=hermite, 3=bezier
22376    pub fn interp_type(&self) -> u16 {
22377        // SAFETY: plain scalar read through a live handle.
22378        unsafe { ffi::whiteout_m3_M3AnimRefU32_get_interpType(self.raw.as_ptr()) }
22379    }
22380
22381    pub fn set_interp_type(&mut self, value: u16) {
22382        // SAFETY: plain scalar write through a live handle.
22383        unsafe { ffi::whiteout_m3_M3AnimRefU32_set_interpType(self.raw.as_ptr(), value) }
22384    }
22385
22386    /// Animation flags
22387    pub fn flags(&self) -> u16 {
22388        // SAFETY: plain scalar read through a live handle.
22389        unsafe { ffi::whiteout_m3_M3AnimRefU32_get_flags(self.raw.as_ptr()) }
22390    }
22391
22392    pub fn set_flags(&mut self, value: u16) {
22393        // SAFETY: plain scalar write through a live handle.
22394        unsafe { ffi::whiteout_m3_M3AnimRefU32_set_flags(self.raw.as_ptr(), value) }
22395    }
22396
22397    /// Animation identifier (links to STC animation data; 0=not animated)
22398    pub fn anim_id(&self) -> u32 {
22399        // SAFETY: plain scalar read through a live handle.
22400        unsafe { ffi::whiteout_m3_M3AnimRefU32_get_animId(self.raw.as_ptr()) }
22401    }
22402
22403    pub fn set_anim_id(&mut self, value: u32) {
22404        // SAFETY: plain scalar write through a live handle.
22405        unsafe { ffi::whiteout_m3_M3AnimRefU32_set_animId(self.raw.as_ptr(), value) }
22406    }
22407
22408    /// Initial/default value (used when not animated)
22409    pub fn init_value(&self) -> u32 {
22410        // SAFETY: plain scalar read through a live handle.
22411        unsafe { ffi::whiteout_m3_M3AnimRefU32_get_initValue(self.raw.as_ptr()) }
22412    }
22413
22414    pub fn set_init_value(&mut self, value: u32) {
22415        // SAFETY: plain scalar write through a live handle.
22416        unsafe { ffi::whiteout_m3_M3AnimRefU32_set_initValue(self.raw.as_ptr(), value) }
22417    }
22418
22419    /// Null/reset value
22420    pub fn null_value(&self) -> u32 {
22421        // SAFETY: plain scalar read through a live handle.
22422        unsafe { ffi::whiteout_m3_M3AnimRefU32_get_nullValue(self.raw.as_ptr()) }
22423    }
22424
22425    pub fn set_null_value(&mut self, value: u32) {
22426        // SAFETY: plain scalar write through a live handle.
22427        unsafe { ffi::whiteout_m3_M3AnimRefU32_set_nullValue(self.raw.as_ptr(), value) }
22428    }
22429
22430    /// Typically -1
22431    pub fn unused(&self) -> i32 {
22432        // SAFETY: plain scalar read through a live handle.
22433        unsafe { ffi::whiteout_m3_M3AnimRefU32_get_unused(self.raw.as_ptr()) }
22434    }
22435
22436    pub fn set_unused(&mut self, value: i32) {
22437        // SAFETY: plain scalar write through a live handle.
22438        unsafe { ffi::whiteout_m3_M3AnimRefU32_set_unused(self.raw.as_ptr(), value) }
22439    }
22440}
22441
22442impl Default for AnimRefU32 {
22443    fn default() -> Self {
22444        Self::new()
22445    }
22446}
22447
22448/// Animatable reference holding a default value and animation link
22449///
22450/// Holds both a constant default value and a link to keyframed animation data. If animId == 0, the property is not animated — use initValue as a constant. Otherwise, resolve through STC_.animIds to locate keyframe data. Total size depends on sizeof(T): 12 + 2*sizeof(T) + 4 bytes.
22451///
22452/// @tparam T The value type (f32, Vector3f, Quaternion, ColorBGRA, Extent, etc.)
22453pub struct AnimRefQuaternion {
22454    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3AnimRefQuaternion>,
22455}
22456
22457impl Drop for AnimRefQuaternion {
22458    fn drop(&mut self) {
22459        // SAFETY: `raw` came from a native constructor and Drop runs once.
22460        unsafe { ffi::whiteout_m3_M3AnimRefQuaternion_delete(self.raw.as_ptr()) }
22461    }
22462}
22463
22464impl AnimRefQuaternion {
22465    /// # Safety
22466    /// `raw` must be a live handle this value takes ownership of.
22467    #[allow(dead_code)] // used by whichever methods return this type
22468    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3AnimRefQuaternion) -> Option<Self> {
22469        core::ptr::NonNull::new(raw).map(|raw| AnimRefQuaternion { raw })
22470    }
22471}
22472
22473// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
22474// is deliberately NOT implemented — the C++ types make no documented
22475// guarantee about concurrent use, and claiming one we haven't verified
22476// would be unsound. See `@bind thread_safe` in the plan.
22477unsafe impl Send for AnimRefQuaternion {}
22478
22479impl core::fmt::Debug for AnimRefQuaternion {
22480    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
22481        f.debug_struct("AnimRefQuaternion").finish_non_exhaustive()
22482    }
22483}
22484
22485impl AnimRefQuaternion {
22486    /// # Panics
22487    /// Panics if the native allocation fails.
22488    pub fn new() -> Self {
22489        // SAFETY: the native constructor returns a live handle; a null here
22490        // means the library is unusable.
22491        unsafe {
22492            let raw = ffi::whiteout_m3_M3AnimRefQuaternion_new();
22493            Self::from_raw(raw).expect("native AnimRefQuaternion allocation failed")
22494        }
22495    }
22496
22497    /// Interpolation: 0=none/step, 1=linear, 2=hermite, 3=bezier
22498    pub fn interp_type(&self) -> u16 {
22499        // SAFETY: plain scalar read through a live handle.
22500        unsafe { ffi::whiteout_m3_M3AnimRefQuaternion_get_interpType(self.raw.as_ptr()) }
22501    }
22502
22503    pub fn set_interp_type(&mut self, value: u16) {
22504        // SAFETY: plain scalar write through a live handle.
22505        unsafe { ffi::whiteout_m3_M3AnimRefQuaternion_set_interpType(self.raw.as_ptr(), value) }
22506    }
22507
22508    /// Animation flags
22509    pub fn flags(&self) -> u16 {
22510        // SAFETY: plain scalar read through a live handle.
22511        unsafe { ffi::whiteout_m3_M3AnimRefQuaternion_get_flags(self.raw.as_ptr()) }
22512    }
22513
22514    pub fn set_flags(&mut self, value: u16) {
22515        // SAFETY: plain scalar write through a live handle.
22516        unsafe { ffi::whiteout_m3_M3AnimRefQuaternion_set_flags(self.raw.as_ptr(), value) }
22517    }
22518
22519    /// Animation identifier (links to STC animation data; 0=not animated)
22520    pub fn anim_id(&self) -> u32 {
22521        // SAFETY: plain scalar read through a live handle.
22522        unsafe { ffi::whiteout_m3_M3AnimRefQuaternion_get_animId(self.raw.as_ptr()) }
22523    }
22524
22525    pub fn set_anim_id(&mut self, value: u32) {
22526        // SAFETY: plain scalar write through a live handle.
22527        unsafe { ffi::whiteout_m3_M3AnimRefQuaternion_set_animId(self.raw.as_ptr(), value) }
22528    }
22529
22530    /// Initial/default value (used when not animated)
22531    pub fn init_value(&self) -> crate::math::Quaternion {
22532        // SAFETY: the getter returns an interior pointer to a
22533        // layout-identical POD; we copy it out immediately.
22534        unsafe {
22535            *(ffi::whiteout_m3_M3AnimRefQuaternion_get_initValue(self.raw.as_ptr())
22536                as *const crate::math::Quaternion)
22537        }
22538    }
22539
22540    pub fn set_init_value(&mut self, value: crate::math::Quaternion) {
22541        // SAFETY: as above, in the other direction.
22542        unsafe {
22543            ffi::whiteout_m3_M3AnimRefQuaternion_set_initValue(
22544                self.raw.as_ptr(),
22545                &value as *const crate::math::Quaternion as *const _,
22546            )
22547        }
22548    }
22549
22550    /// Null/reset value
22551    pub fn null_value(&self) -> crate::math::Quaternion {
22552        // SAFETY: the getter returns an interior pointer to a
22553        // layout-identical POD; we copy it out immediately.
22554        unsafe {
22555            *(ffi::whiteout_m3_M3AnimRefQuaternion_get_nullValue(self.raw.as_ptr())
22556                as *const crate::math::Quaternion)
22557        }
22558    }
22559
22560    pub fn set_null_value(&mut self, value: crate::math::Quaternion) {
22561        // SAFETY: as above, in the other direction.
22562        unsafe {
22563            ffi::whiteout_m3_M3AnimRefQuaternion_set_nullValue(
22564                self.raw.as_ptr(),
22565                &value as *const crate::math::Quaternion as *const _,
22566            )
22567        }
22568    }
22569
22570    /// Typically -1
22571    pub fn unused(&self) -> i32 {
22572        // SAFETY: plain scalar read through a live handle.
22573        unsafe { ffi::whiteout_m3_M3AnimRefQuaternion_get_unused(self.raw.as_ptr()) }
22574    }
22575
22576    pub fn set_unused(&mut self, value: i32) {
22577        // SAFETY: plain scalar write through a live handle.
22578        unsafe { ffi::whiteout_m3_M3AnimRefQuaternion_set_unused(self.raw.as_ptr(), value) }
22579    }
22580}
22581
22582impl Default for AnimRefQuaternion {
22583    fn default() -> Self {
22584        Self::new()
22585    }
22586}
22587
22588/// Animatable reference holding a default value and animation link
22589///
22590/// Holds both a constant default value and a link to keyframed animation data. If animId == 0, the property is not animated — use initValue as a constant. Otherwise, resolve through STC_.animIds to locate keyframe data. Total size depends on sizeof(T): 12 + 2*sizeof(T) + 4 bytes.
22591///
22592/// @tparam T The value type (f32, Vector3f, Quaternion, ColorBGRA, Extent, etc.)
22593pub struct AnimRefM3Extent {
22594    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3AnimRefM3Extent>,
22595}
22596
22597impl Drop for AnimRefM3Extent {
22598    fn drop(&mut self) {
22599        // SAFETY: `raw` came from a native constructor and Drop runs once.
22600        unsafe { ffi::whiteout_m3_M3AnimRefM3Extent_delete(self.raw.as_ptr()) }
22601    }
22602}
22603
22604impl AnimRefM3Extent {
22605    /// # Safety
22606    /// `raw` must be a live handle this value takes ownership of.
22607    #[allow(dead_code)] // used by whichever methods return this type
22608    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3AnimRefM3Extent) -> Option<Self> {
22609        core::ptr::NonNull::new(raw).map(|raw| AnimRefM3Extent { raw })
22610    }
22611}
22612
22613// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
22614// is deliberately NOT implemented — the C++ types make no documented
22615// guarantee about concurrent use, and claiming one we haven't verified
22616// would be unsound. See `@bind thread_safe` in the plan.
22617unsafe impl Send for AnimRefM3Extent {}
22618
22619impl core::fmt::Debug for AnimRefM3Extent {
22620    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
22621        f.debug_struct("AnimRefM3Extent").finish_non_exhaustive()
22622    }
22623}
22624
22625impl AnimRefM3Extent {
22626    /// # Panics
22627    /// Panics if the native allocation fails.
22628    pub fn new() -> Self {
22629        // SAFETY: the native constructor returns a live handle; a null here
22630        // means the library is unusable.
22631        unsafe {
22632            let raw = ffi::whiteout_m3_M3AnimRefM3Extent_new();
22633            Self::from_raw(raw).expect("native AnimRefM3Extent allocation failed")
22634        }
22635    }
22636
22637    /// Interpolation: 0=none/step, 1=linear, 2=hermite, 3=bezier
22638    pub fn interp_type(&self) -> u16 {
22639        // SAFETY: plain scalar read through a live handle.
22640        unsafe { ffi::whiteout_m3_M3AnimRefM3Extent_get_interpType(self.raw.as_ptr()) }
22641    }
22642
22643    pub fn set_interp_type(&mut self, value: u16) {
22644        // SAFETY: plain scalar write through a live handle.
22645        unsafe { ffi::whiteout_m3_M3AnimRefM3Extent_set_interpType(self.raw.as_ptr(), value) }
22646    }
22647
22648    /// Animation flags
22649    pub fn flags(&self) -> u16 {
22650        // SAFETY: plain scalar read through a live handle.
22651        unsafe { ffi::whiteout_m3_M3AnimRefM3Extent_get_flags(self.raw.as_ptr()) }
22652    }
22653
22654    pub fn set_flags(&mut self, value: u16) {
22655        // SAFETY: plain scalar write through a live handle.
22656        unsafe { ffi::whiteout_m3_M3AnimRefM3Extent_set_flags(self.raw.as_ptr(), value) }
22657    }
22658
22659    /// Animation identifier (links to STC animation data; 0=not animated)
22660    pub fn anim_id(&self) -> u32 {
22661        // SAFETY: plain scalar read through a live handle.
22662        unsafe { ffi::whiteout_m3_M3AnimRefM3Extent_get_animId(self.raw.as_ptr()) }
22663    }
22664
22665    pub fn set_anim_id(&mut self, value: u32) {
22666        // SAFETY: plain scalar write through a live handle.
22667        unsafe { ffi::whiteout_m3_M3AnimRefM3Extent_set_animId(self.raw.as_ptr(), value) }
22668    }
22669
22670    /// Initial/default value (used when not animated)
22671    /// Borrows the field in place — no copy, no allocation.
22672    pub fn init_value(&self) -> crate::support::Ref<'_, Extent> {
22673        // SAFETY: an interior pointer into `self`, valid for this
22674        // borrow and never freed by the `Ref`.
22675        unsafe {
22676            crate::support::Ref::new(Extent {
22677                raw: core::ptr::NonNull::new_unchecked(
22678                    ffi::whiteout_m3_M3AnimRefM3Extent_get_initValue(self.raw.as_ptr()),
22679                ),
22680            })
22681        }
22682    }
22683
22684    pub fn init_value_mut(&mut self) -> crate::support::RefMut<'_, Extent> {
22685        // SAFETY: as above; `&mut self` guarantees exclusivity.
22686        unsafe {
22687            crate::support::RefMut::new(Extent {
22688                raw: core::ptr::NonNull::new_unchecked(
22689                    ffi::whiteout_m3_M3AnimRefM3Extent_get_initValue(self.raw.as_ptr()),
22690                ),
22691            })
22692        }
22693    }
22694
22695    /// Null/reset value
22696    /// Borrows the field in place — no copy, no allocation.
22697    pub fn null_value(&self) -> crate::support::Ref<'_, Extent> {
22698        // SAFETY: an interior pointer into `self`, valid for this
22699        // borrow and never freed by the `Ref`.
22700        unsafe {
22701            crate::support::Ref::new(Extent {
22702                raw: core::ptr::NonNull::new_unchecked(
22703                    ffi::whiteout_m3_M3AnimRefM3Extent_get_nullValue(self.raw.as_ptr()),
22704                ),
22705            })
22706        }
22707    }
22708
22709    pub fn null_value_mut(&mut self) -> crate::support::RefMut<'_, Extent> {
22710        // SAFETY: as above; `&mut self` guarantees exclusivity.
22711        unsafe {
22712            crate::support::RefMut::new(Extent {
22713                raw: core::ptr::NonNull::new_unchecked(
22714                    ffi::whiteout_m3_M3AnimRefM3Extent_get_nullValue(self.raw.as_ptr()),
22715                ),
22716            })
22717        }
22718    }
22719
22720    /// Typically -1
22721    pub fn unused(&self) -> i32 {
22722        // SAFETY: plain scalar read through a live handle.
22723        unsafe { ffi::whiteout_m3_M3AnimRefM3Extent_get_unused(self.raw.as_ptr()) }
22724    }
22725
22726    pub fn set_unused(&mut self, value: i32) {
22727        // SAFETY: plain scalar write through a live handle.
22728        unsafe { ffi::whiteout_m3_M3AnimRefM3Extent_set_unused(self.raw.as_ptr(), value) }
22729    }
22730}
22731
22732impl Default for AnimRefM3Extent {
22733    fn default() -> Self {
22734        Self::new()
22735    }
22736}
22737
22738#[doc(hidden)]
22739pub mod ffi {
22740    #![allow(missing_debug_implementations)]
22741
22742    #[allow(unused_imports)]
22743    use crate::support::{RawBytes, RawCString};
22744
22745    #[repr(C)]
22746    pub struct whiteout_M3ColorBGRA {
22747        _private: [u8; 0],
22748    }
22749    #[repr(C)]
22750    pub struct whiteout_M3ColorBGR {
22751        _private: [u8; 0],
22752    }
22753    #[repr(C)]
22754    pub struct whiteout_M3Extent {
22755        _private: [u8; 0],
22756    }
22757    #[repr(C)]
22758    pub struct whiteout_M3Event {
22759        _private: [u8; 0],
22760    }
22761    #[repr(C)]
22762    pub struct whiteout_M3Sequence {
22763        _private: [u8; 0],
22764    }
22765    #[repr(C)]
22766    pub struct whiteout_M3SubTrackContainer {
22767        _private: [u8; 0],
22768    }
22769    #[repr(C)]
22770    pub struct whiteout_M3AnimationGroup {
22771        _private: [u8; 0],
22772    }
22773    #[repr(C)]
22774    pub struct whiteout_M3AnimationState {
22775        _private: [u8; 0],
22776    }
22777    #[repr(C)]
22778    pub struct whiteout_M3BoneAnimationSet {
22779        _private: [u8; 0],
22780    }
22781    #[repr(C)]
22782    pub struct whiteout_M3ParticleEmitter {
22783        _private: [u8; 0],
22784    }
22785    #[repr(C)]
22786    pub struct whiteout_M3ParticleEmitterCopy {
22787        _private: [u8; 0],
22788    }
22789    #[repr(C)]
22790    pub struct whiteout_M3SplineRibbon {
22791        _private: [u8; 0],
22792    }
22793    #[repr(C)]
22794    pub struct whiteout_M3RibbonEmitter {
22795        _private: [u8; 0],
22796    }
22797    #[repr(C)]
22798    pub struct whiteout_M3Projector {
22799        _private: [u8; 0],
22800    }
22801    #[repr(C)]
22802    pub struct whiteout_M3MaterialMap {
22803        _private: [u8; 0],
22804    }
22805    #[repr(C)]
22806    pub struct whiteout_M3TextureLayer {
22807        _private: [u8; 0],
22808    }
22809    #[repr(C)]
22810    pub struct whiteout_M3StandardMaterial {
22811        _private: [u8; 0],
22812    }
22813    #[repr(C)]
22814    pub struct whiteout_M3DisplacementMaterial {
22815        _private: [u8; 0],
22816    }
22817    #[repr(C)]
22818    pub struct whiteout_M3CompositeSection {
22819        _private: [u8; 0],
22820    }
22821    #[repr(C)]
22822    pub struct whiteout_M3CompositeMaterial {
22823        _private: [u8; 0],
22824    }
22825    #[repr(C)]
22826    pub struct whiteout_M3TerrainMaterial {
22827        _private: [u8; 0],
22828    }
22829    #[repr(C)]
22830    pub struct whiteout_M3VolumeMaterial {
22831        _private: [u8; 0],
22832    }
22833    #[repr(C)]
22834    pub struct whiteout_M3HairMaterial {
22835        _private: [u8; 0],
22836    }
22837    #[repr(C)]
22838    pub struct whiteout_M3VolumeNoiseMaterial {
22839        _private: [u8; 0],
22840    }
22841    #[repr(C)]
22842    pub struct whiteout_M3CreepMaterial {
22843        _private: [u8; 0],
22844    }
22845    #[repr(C)]
22846    pub struct whiteout_M3STBMaterial {
22847        _private: [u8; 0],
22848    }
22849    #[repr(C)]
22850    pub struct whiteout_M3ReflectionMaterial {
22851        _private: [u8; 0],
22852    }
22853    #[repr(C)]
22854    pub struct whiteout_M3SubFlare {
22855        _private: [u8; 0],
22856    }
22857    #[repr(C)]
22858    pub struct whiteout_M3LensFlare {
22859        _private: [u8; 0],
22860    }
22861    #[repr(C)]
22862    pub struct whiteout_M3MaterialAddData {
22863        _private: [u8; 0],
22864    }
22865    #[repr(C)]
22866    pub struct whiteout_M3Bone {
22867        _private: [u8; 0],
22868    }
22869    #[repr(C)]
22870    pub struct whiteout_M3Region {
22871        _private: [u8; 0],
22872    }
22873    #[repr(C)]
22874    pub struct whiteout_M3Batch {
22875        _private: [u8; 0],
22876    }
22877    #[repr(C)]
22878    pub struct whiteout_M3MeshSection {
22879        _private: [u8; 0],
22880    }
22881    #[repr(C)]
22882    pub struct whiteout_M3MeshDivision {
22883        _private: [u8; 0],
22884    }
22885    #[repr(C)]
22886    pub struct whiteout_M3InitialReference {
22887        _private: [u8; 0],
22888    }
22889    #[repr(C)]
22890    pub struct whiteout_M3AttachmentPoint {
22891        _private: [u8; 0],
22892    }
22893    #[repr(C)]
22894    pub struct whiteout_M3HitTestShape {
22895        _private: [u8; 0],
22896    }
22897    #[repr(C)]
22898    pub struct whiteout_M3AttachmentVolume {
22899        _private: [u8; 0],
22900    }
22901    #[repr(C)]
22902    pub struct whiteout_M3TriggerData {
22903        _private: [u8; 0],
22904    }
22905    #[repr(C)]
22906    pub struct whiteout_M3TurretBehavior {
22907        _private: [u8; 0],
22908    }
22909    #[repr(C)]
22910    pub struct whiteout_M3BillboardBehavior {
22911        _private: [u8; 0],
22912    }
22913    #[repr(C)]
22914    pub struct whiteout_M3IKJoint {
22915        _private: [u8; 0],
22916    }
22917    #[repr(C)]
22918    pub struct whiteout_M3IKTwoJoint {
22919        _private: [u8; 0],
22920    }
22921    #[repr(C)]
22922    pub struct whiteout_M3IKCCD {
22923        _private: [u8; 0],
22924    }
22925    #[repr(C)]
22926    pub struct whiteout_M3OneBoneSolver {
22927        _private: [u8; 0],
22928    }
22929    #[repr(C)]
22930    pub struct whiteout_M3ShadowBox {
22931        _private: [u8; 0],
22932    }
22933    #[repr(C)]
22934    pub struct whiteout_M3ViewVolume {
22935        _private: [u8; 0],
22936    }
22937    #[repr(C)]
22938    pub struct whiteout_M3TrailingModel {
22939        _private: [u8; 0],
22940    }
22941    #[repr(C)]
22942    pub struct whiteout_M3Force {
22943        _private: [u8; 0],
22944    }
22945    #[repr(C)]
22946    pub struct whiteout_M3Warp {
22947        _private: [u8; 0],
22948    }
22949    #[repr(C)]
22950    pub struct whiteout_M3ConvexHullHalfEdge {
22951        _private: [u8; 0],
22952    }
22953    #[repr(C)]
22954    pub struct whiteout_M3PhysicsMeshBvhNode {
22955        _private: [u8; 0],
22956    }
22957    #[repr(C)]
22958    pub struct whiteout_M3PhysicsMeshTriangle {
22959        _private: [u8; 0],
22960    }
22961    #[repr(C)]
22962    pub struct whiteout_M3PhysicsMeshEdge {
22963        _private: [u8; 0],
22964    }
22965    #[repr(C)]
22966    pub struct whiteout_M3PhysicsShape {
22967        _private: [u8; 0],
22968    }
22969    #[repr(C)]
22970    pub struct whiteout_M3RigidBody {
22971        _private: [u8; 0],
22972    }
22973    #[repr(C)]
22974    pub struct whiteout_M3PhysicsJoint {
22975        _private: [u8; 0],
22976    }
22977    #[repr(C)]
22978    pub struct whiteout_M3PhysicsConstraint {
22979        _private: [u8; 0],
22980    }
22981    #[repr(C)]
22982    pub struct whiteout_M3ClothCollider {
22983        _private: [u8; 0],
22984    }
22985    #[repr(C)]
22986    pub struct whiteout_M3ClothProxy {
22987        _private: [u8; 0],
22988    }
22989    #[repr(C)]
22990    pub struct whiteout_M3ClothPhysics {
22991        _private: [u8; 0],
22992    }
22993    #[repr(C)]
22994    pub struct whiteout_M3Light {
22995        _private: [u8; 0],
22996    }
22997    #[repr(C)]
22998    pub struct whiteout_M3Camera {
22999        _private: [u8; 0],
23000    }
23001    #[repr(C)]
23002    pub struct whiteout_M3Model {
23003        _private: [u8; 0],
23004    }
23005    #[repr(C)]
23006    pub struct whiteout_M3Parser {
23007        _private: [u8; 0],
23008    }
23009    #[repr(C)]
23010    pub struct whiteout_M3Writer {
23011        _private: [u8; 0],
23012    }
23013    #[repr(C)]
23014    pub struct whiteout_M3AnimRefF32 {
23015        _private: [u8; 0],
23016    }
23017    #[repr(C)]
23018    pub struct whiteout_M3AnimRefVector3f {
23019        _private: [u8; 0],
23020    }
23021    #[repr(C)]
23022    pub struct whiteout_M3AnimRefM3ColorBGRA {
23023        _private: [u8; 0],
23024    }
23025    #[repr(C)]
23026    pub struct whiteout_M3AnimRefU16 {
23027        _private: [u8; 0],
23028    }
23029    #[repr(C)]
23030    pub struct whiteout_M3AnimRefVector2f {
23031        _private: [u8; 0],
23032    }
23033    #[repr(C)]
23034    pub struct whiteout_M3AnimRefU32 {
23035        _private: [u8; 0],
23036    }
23037    #[repr(C)]
23038    pub struct whiteout_M3AnimRefQuaternion {
23039        _private: [u8; 0],
23040    }
23041    #[repr(C)]
23042    pub struct whiteout_M3AnimRefM3Extent {
23043        _private: [u8; 0],
23044    }
23045
23046    extern "C" {
23047        // ColorBGRA
23048        pub fn whiteout_m3_M3ColorBGRA_new() -> *mut whiteout_M3ColorBGRA;
23049        pub fn whiteout_m3_M3ColorBGRA_delete(self_: *mut whiteout_M3ColorBGRA);
23050        pub fn whiteout_m3_M3ColorBGRA_get_b(self_: *mut whiteout_M3ColorBGRA) -> u8;
23051        pub fn whiteout_m3_M3ColorBGRA_set_b(self_: *mut whiteout_M3ColorBGRA, value: u8);
23052        pub fn whiteout_m3_M3ColorBGRA_get_g(self_: *mut whiteout_M3ColorBGRA) -> u8;
23053        pub fn whiteout_m3_M3ColorBGRA_set_g(self_: *mut whiteout_M3ColorBGRA, value: u8);
23054        pub fn whiteout_m3_M3ColorBGRA_get_r(self_: *mut whiteout_M3ColorBGRA) -> u8;
23055        pub fn whiteout_m3_M3ColorBGRA_set_r(self_: *mut whiteout_M3ColorBGRA, value: u8);
23056        pub fn whiteout_m3_M3ColorBGRA_get_a(self_: *mut whiteout_M3ColorBGRA) -> u8;
23057        pub fn whiteout_m3_M3ColorBGRA_set_a(self_: *mut whiteout_M3ColorBGRA, value: u8);
23058        // ColorBGR
23059        pub fn whiteout_m3_M3ColorBGR_new() -> *mut whiteout_M3ColorBGR;
23060        pub fn whiteout_m3_M3ColorBGR_delete(self_: *mut whiteout_M3ColorBGR);
23061        pub fn whiteout_m3_M3ColorBGR_get_b(self_: *mut whiteout_M3ColorBGR) -> u8;
23062        pub fn whiteout_m3_M3ColorBGR_set_b(self_: *mut whiteout_M3ColorBGR, value: u8);
23063        pub fn whiteout_m3_M3ColorBGR_get_g(self_: *mut whiteout_M3ColorBGR) -> u8;
23064        pub fn whiteout_m3_M3ColorBGR_set_g(self_: *mut whiteout_M3ColorBGR, value: u8);
23065        pub fn whiteout_m3_M3ColorBGR_get_r(self_: *mut whiteout_M3ColorBGR) -> u8;
23066        pub fn whiteout_m3_M3ColorBGR_set_r(self_: *mut whiteout_M3ColorBGR, value: u8);
23067        // Extent
23068        pub fn whiteout_m3_M3Extent_new() -> *mut whiteout_M3Extent;
23069        pub fn whiteout_m3_M3Extent_delete(self_: *mut whiteout_M3Extent);
23070        pub fn whiteout_m3_M3Extent_get_min(
23071            self_: *mut whiteout_M3Extent,
23072        ) -> *mut core::ffi::c_void;
23073        pub fn whiteout_m3_M3Extent_set_min(
23074            self_: *mut whiteout_M3Extent,
23075            value: *const core::ffi::c_void,
23076        );
23077        pub fn whiteout_m3_M3Extent_get_max(
23078            self_: *mut whiteout_M3Extent,
23079        ) -> *mut core::ffi::c_void;
23080        pub fn whiteout_m3_M3Extent_set_max(
23081            self_: *mut whiteout_M3Extent,
23082            value: *const core::ffi::c_void,
23083        );
23084        pub fn whiteout_m3_M3Extent_get_radius(self_: *mut whiteout_M3Extent) -> f32;
23085        pub fn whiteout_m3_M3Extent_set_radius(self_: *mut whiteout_M3Extent, value: f32);
23086        // Event
23087        pub fn whiteout_m3_M3Event_new() -> *mut whiteout_M3Event;
23088        pub fn whiteout_m3_M3Event_delete(self_: *mut whiteout_M3Event);
23089        pub fn whiteout_m3_M3Event_get_name(self_: *mut whiteout_M3Event) -> RawCString;
23090        pub fn whiteout_m3_M3Event_set_name(
23091            self_: *mut whiteout_M3Event,
23092            value: *const core::ffi::c_char,
23093        );
23094        pub fn whiteout_m3_M3Event_get_unknown(self_: *mut whiteout_M3Event) -> u32;
23095        pub fn whiteout_m3_M3Event_set_unknown(self_: *mut whiteout_M3Event, value: u32);
23096        pub fn whiteout_m3_M3Event_get_boneIndex(self_: *mut whiteout_M3Event) -> u16;
23097        pub fn whiteout_m3_M3Event_set_boneIndex(self_: *mut whiteout_M3Event, value: u16);
23098        pub fn whiteout_m3_M3Event_get_padding(self_: *mut whiteout_M3Event) -> u16;
23099        pub fn whiteout_m3_M3Event_set_padding(self_: *mut whiteout_M3Event, value: u16);
23100        pub fn whiteout_m3_M3Event_get_eventType(self_: *mut whiteout_M3Event) -> u32;
23101        pub fn whiteout_m3_M3Event_set_eventType(self_: *mut whiteout_M3Event, value: u32);
23102        pub fn whiteout_m3_M3Event_get_optionString(self_: *mut whiteout_M3Event) -> RawCString;
23103        pub fn whiteout_m3_M3Event_set_optionString(
23104            self_: *mut whiteout_M3Event,
23105            value: *const core::ffi::c_char,
23106        );
23107        pub fn whiteout_m3_M3Event_get_rttChannelIndex(self_: *mut whiteout_M3Event) -> u32;
23108        pub fn whiteout_m3_M3Event_set_rttChannelIndex(self_: *mut whiteout_M3Event, value: u32);
23109        pub fn whiteout_m3_M3Event_get_extraParameter(self_: *mut whiteout_M3Event) -> u32;
23110        pub fn whiteout_m3_M3Event_set_extraParameter(self_: *mut whiteout_M3Event, value: u32);
23111        // Sequence
23112        pub fn whiteout_m3_M3Sequence_new() -> *mut whiteout_M3Sequence;
23113        pub fn whiteout_m3_M3Sequence_delete(self_: *mut whiteout_M3Sequence);
23114        pub fn whiteout_m3_M3Sequence_get_id(self_: *mut whiteout_M3Sequence) -> i32;
23115        pub fn whiteout_m3_M3Sequence_set_id(self_: *mut whiteout_M3Sequence, value: i32);
23116        pub fn whiteout_m3_M3Sequence_get_index(self_: *mut whiteout_M3Sequence) -> i32;
23117        pub fn whiteout_m3_M3Sequence_set_index(self_: *mut whiteout_M3Sequence, value: i32);
23118        pub fn whiteout_m3_M3Sequence_get_name(self_: *mut whiteout_M3Sequence) -> RawCString;
23119        pub fn whiteout_m3_M3Sequence_set_name(
23120            self_: *mut whiteout_M3Sequence,
23121            value: *const core::ffi::c_char,
23122        );
23123        pub fn whiteout_m3_M3Sequence_get_startFrame(self_: *mut whiteout_M3Sequence) -> u32;
23124        pub fn whiteout_m3_M3Sequence_set_startFrame(self_: *mut whiteout_M3Sequence, value: u32);
23125        pub fn whiteout_m3_M3Sequence_get_endFrame(self_: *mut whiteout_M3Sequence) -> u32;
23126        pub fn whiteout_m3_M3Sequence_set_endFrame(self_: *mut whiteout_M3Sequence, value: u32);
23127        pub fn whiteout_m3_M3Sequence_get_moveSpeed(self_: *mut whiteout_M3Sequence) -> f32;
23128        pub fn whiteout_m3_M3Sequence_set_moveSpeed(self_: *mut whiteout_M3Sequence, value: f32);
23129        pub fn whiteout_m3_M3Sequence_get_flags(self_: *mut whiteout_M3Sequence) -> i32;
23130        pub fn whiteout_m3_M3Sequence_set_flags(self_: *mut whiteout_M3Sequence, value: i32);
23131        pub fn whiteout_m3_M3Sequence_get_frequency(self_: *mut whiteout_M3Sequence) -> u32;
23132        pub fn whiteout_m3_M3Sequence_set_frequency(self_: *mut whiteout_M3Sequence, value: u32);
23133        pub fn whiteout_m3_M3Sequence_get_replayStart(self_: *mut whiteout_M3Sequence) -> u32;
23134        pub fn whiteout_m3_M3Sequence_set_replayStart(self_: *mut whiteout_M3Sequence, value: u32);
23135        pub fn whiteout_m3_M3Sequence_get_replayEnd(self_: *mut whiteout_M3Sequence) -> u32;
23136        pub fn whiteout_m3_M3Sequence_set_replayEnd(self_: *mut whiteout_M3Sequence, value: u32);
23137        pub fn whiteout_m3_M3Sequence_get_blendTime(self_: *mut whiteout_M3Sequence) -> u32;
23138        pub fn whiteout_m3_M3Sequence_set_blendTime(self_: *mut whiteout_M3Sequence, value: u32);
23139        pub fn whiteout_m3_M3Sequence_get_bounds(
23140            self_: *mut whiteout_M3Sequence,
23141        ) -> *mut whiteout_M3Extent;
23142        pub fn whiteout_m3_M3Sequence_set_bounds(
23143            self_: *mut whiteout_M3Sequence,
23144            value: *const whiteout_M3Extent,
23145        );
23146        pub fn whiteout_m3_M3Sequence_get_animationSets_count(
23147            self_: *mut whiteout_M3Sequence,
23148        ) -> usize;
23149        pub fn whiteout_m3_M3Sequence_resize_animationSets(
23150            self_: *mut whiteout_M3Sequence,
23151            count: usize,
23152        );
23153        pub fn whiteout_m3_M3Sequence_get_animationSets_data(
23154            self_: *mut whiteout_M3Sequence,
23155        ) -> *const u8;
23156        pub fn whiteout_m3_M3Sequence_assign_animationSets(
23157            self_: *mut whiteout_M3Sequence,
23158            data: *const u8,
23159            count: usize,
23160        );
23161        // SubTrackContainer
23162        pub fn whiteout_m3_M3SubTrackContainer_new() -> *mut whiteout_M3SubTrackContainer;
23163        pub fn whiteout_m3_M3SubTrackContainer_delete(self_: *mut whiteout_M3SubTrackContainer);
23164        pub fn whiteout_m3_M3SubTrackContainer_get_name(
23165            self_: *mut whiteout_M3SubTrackContainer,
23166        ) -> RawCString;
23167        pub fn whiteout_m3_M3SubTrackContainer_set_name(
23168            self_: *mut whiteout_M3SubTrackContainer,
23169            value: *const core::ffi::c_char,
23170        );
23171        pub fn whiteout_m3_M3SubTrackContainer_get_runsConcurrent(
23172            self_: *mut whiteout_M3SubTrackContainer,
23173        ) -> u16;
23174        pub fn whiteout_m3_M3SubTrackContainer_set_runsConcurrent(
23175            self_: *mut whiteout_M3SubTrackContainer,
23176            value: u16,
23177        );
23178        pub fn whiteout_m3_M3SubTrackContainer_get_animPriority(
23179            self_: *mut whiteout_M3SubTrackContainer,
23180        ) -> u16;
23181        pub fn whiteout_m3_M3SubTrackContainer_set_animPriority(
23182            self_: *mut whiteout_M3SubTrackContainer,
23183            value: u16,
23184        );
23185        pub fn whiteout_m3_M3SubTrackContainer_get_animationStateIndex(
23186            self_: *mut whiteout_M3SubTrackContainer,
23187        ) -> u16;
23188        pub fn whiteout_m3_M3SubTrackContainer_set_animationStateIndex(
23189            self_: *mut whiteout_M3SubTrackContainer,
23190            value: u16,
23191        );
23192        pub fn whiteout_m3_M3SubTrackContainer_get_padding(
23193            self_: *mut whiteout_M3SubTrackContainer,
23194        ) -> u16;
23195        pub fn whiteout_m3_M3SubTrackContainer_set_padding(
23196            self_: *mut whiteout_M3SubTrackContainer,
23197            value: u16,
23198        );
23199        pub fn whiteout_m3_M3SubTrackContainer_get_animIds_count(
23200            self_: *mut whiteout_M3SubTrackContainer,
23201        ) -> usize;
23202        pub fn whiteout_m3_M3SubTrackContainer_resize_animIds(
23203            self_: *mut whiteout_M3SubTrackContainer,
23204            count: usize,
23205        );
23206        pub fn whiteout_m3_M3SubTrackContainer_get_animIds_data(
23207            self_: *mut whiteout_M3SubTrackContainer,
23208        ) -> *const u32;
23209        pub fn whiteout_m3_M3SubTrackContainer_assign_animIds(
23210            self_: *mut whiteout_M3SubTrackContainer,
23211            data: *const u32,
23212            count: usize,
23213        );
23214        pub fn whiteout_m3_M3SubTrackContainer_get_animRefs_count(
23215            self_: *mut whiteout_M3SubTrackContainer,
23216        ) -> usize;
23217        pub fn whiteout_m3_M3SubTrackContainer_resize_animRefs(
23218            self_: *mut whiteout_M3SubTrackContainer,
23219            count: usize,
23220        );
23221        pub fn whiteout_m3_M3SubTrackContainer_get_animRefs_data(
23222            self_: *mut whiteout_M3SubTrackContainer,
23223        ) -> *const u32;
23224        pub fn whiteout_m3_M3SubTrackContainer_assign_animRefs(
23225            self_: *mut whiteout_M3SubTrackContainer,
23226            data: *const u32,
23227            count: usize,
23228        );
23229        pub fn whiteout_m3_M3SubTrackContainer_get_unknown(
23230            self_: *mut whiteout_M3SubTrackContainer,
23231        ) -> u32;
23232        pub fn whiteout_m3_M3SubTrackContainer_set_unknown(
23233            self_: *mut whiteout_M3SubTrackContainer,
23234            value: u32,
23235        );
23236        // AnimationGroup
23237        pub fn whiteout_m3_M3AnimationGroup_new() -> *mut whiteout_M3AnimationGroup;
23238        pub fn whiteout_m3_M3AnimationGroup_delete(self_: *mut whiteout_M3AnimationGroup);
23239        pub fn whiteout_m3_M3AnimationGroup_get_name(
23240            self_: *mut whiteout_M3AnimationGroup,
23241        ) -> RawCString;
23242        pub fn whiteout_m3_M3AnimationGroup_set_name(
23243            self_: *mut whiteout_M3AnimationGroup,
23244            value: *const core::ffi::c_char,
23245        );
23246        pub fn whiteout_m3_M3AnimationGroup_get_subtrackIndices_count(
23247            self_: *mut whiteout_M3AnimationGroup,
23248        ) -> usize;
23249        pub fn whiteout_m3_M3AnimationGroup_resize_subtrackIndices(
23250            self_: *mut whiteout_M3AnimationGroup,
23251            count: usize,
23252        );
23253        pub fn whiteout_m3_M3AnimationGroup_get_subtrackIndices_data(
23254            self_: *mut whiteout_M3AnimationGroup,
23255        ) -> *const u32;
23256        pub fn whiteout_m3_M3AnimationGroup_assign_subtrackIndices(
23257            self_: *mut whiteout_M3AnimationGroup,
23258            data: *const u32,
23259            count: usize,
23260        );
23261        // AnimationState
23262        pub fn whiteout_m3_M3AnimationState_new() -> *mut whiteout_M3AnimationState;
23263        pub fn whiteout_m3_M3AnimationState_delete(self_: *mut whiteout_M3AnimationState);
23264        pub fn whiteout_m3_M3AnimationState_get_animIds_count(
23265            self_: *mut whiteout_M3AnimationState,
23266        ) -> usize;
23267        pub fn whiteout_m3_M3AnimationState_resize_animIds(
23268            self_: *mut whiteout_M3AnimationState,
23269            count: usize,
23270        );
23271        pub fn whiteout_m3_M3AnimationState_get_animIds_data(
23272            self_: *mut whiteout_M3AnimationState,
23273        ) -> *const u32;
23274        pub fn whiteout_m3_M3AnimationState_assign_animIds(
23275            self_: *mut whiteout_M3AnimationState,
23276            data: *const u32,
23277            count: usize,
23278        );
23279        pub fn whiteout_m3_M3AnimationState_unknown_size() -> usize;
23280        pub fn whiteout_m3_M3AnimationState_get_unknown_at(
23281            self_: *mut whiteout_M3AnimationState,
23282            index: usize,
23283        ) -> u8;
23284        pub fn whiteout_m3_M3AnimationState_set_unknown_at(
23285            self_: *mut whiteout_M3AnimationState,
23286            index: usize,
23287            value: u8,
23288        );
23289        // BoneAnimationSet
23290        pub fn whiteout_m3_M3BoneAnimationSet_new() -> *mut whiteout_M3BoneAnimationSet;
23291        pub fn whiteout_m3_M3BoneAnimationSet_delete(self_: *mut whiteout_M3BoneAnimationSet);
23292        pub fn whiteout_m3_M3BoneAnimationSet_get_animationSequenceIndex(
23293            self_: *mut whiteout_M3BoneAnimationSet,
23294        ) -> u16;
23295        pub fn whiteout_m3_M3BoneAnimationSet_set_animationSequenceIndex(
23296            self_: *mut whiteout_M3BoneAnimationSet,
23297            value: u16,
23298        );
23299        pub fn whiteout_m3_M3BoneAnimationSet_get_fallbackSequenceIndex(
23300            self_: *mut whiteout_M3BoneAnimationSet,
23301        ) -> u16;
23302        pub fn whiteout_m3_M3BoneAnimationSet_set_fallbackSequenceIndex(
23303            self_: *mut whiteout_M3BoneAnimationSet,
23304            value: u16,
23305        );
23306        pub fn whiteout_m3_M3BoneAnimationSet_get_name(
23307            self_: *mut whiteout_M3BoneAnimationSet,
23308        ) -> RawCString;
23309        pub fn whiteout_m3_M3BoneAnimationSet_set_name(
23310            self_: *mut whiteout_M3BoneAnimationSet,
23311            value: *const core::ffi::c_char,
23312        );
23313        pub fn whiteout_m3_M3BoneAnimationSet_get_splitItems_count(
23314            self_: *mut whiteout_M3BoneAnimationSet,
23315        ) -> usize;
23316        pub fn whiteout_m3_M3BoneAnimationSet_resize_splitItems(
23317            self_: *mut whiteout_M3BoneAnimationSet,
23318            count: usize,
23319        );
23320        pub fn whiteout_m3_M3BoneAnimationSet_get_splitItems_data(
23321            self_: *mut whiteout_M3BoneAnimationSet,
23322        ) -> *const u16;
23323        pub fn whiteout_m3_M3BoneAnimationSet_assign_splitItems(
23324            self_: *mut whiteout_M3BoneAnimationSet,
23325            data: *const u16,
23326            count: usize,
23327        );
23328        // ParticleEmitter
23329        pub fn whiteout_m3_M3ParticleEmitter_new() -> *mut whiteout_M3ParticleEmitter;
23330        pub fn whiteout_m3_M3ParticleEmitter_delete(self_: *mut whiteout_M3ParticleEmitter);
23331        pub fn whiteout_m3_M3ParticleEmitter_get_boneIndex(
23332            self_: *mut whiteout_M3ParticleEmitter,
23333        ) -> u32;
23334        pub fn whiteout_m3_M3ParticleEmitter_set_boneIndex(
23335            self_: *mut whiteout_M3ParticleEmitter,
23336            value: u32,
23337        );
23338        pub fn whiteout_m3_M3ParticleEmitter_get_materialIndex(
23339            self_: *mut whiteout_M3ParticleEmitter,
23340        ) -> u32;
23341        pub fn whiteout_m3_M3ParticleEmitter_set_materialIndex(
23342            self_: *mut whiteout_M3ParticleEmitter,
23343            value: u32,
23344        );
23345        pub fn whiteout_m3_M3ParticleEmitter_get_additionalFlags(
23346            self_: *mut whiteout_M3ParticleEmitter,
23347        ) -> i32;
23348        pub fn whiteout_m3_M3ParticleEmitter_set_additionalFlags(
23349            self_: *mut whiteout_M3ParticleEmitter,
23350            value: i32,
23351        );
23352        pub fn whiteout_m3_M3ParticleEmitter_get_initialSpeed(
23353            self_: *mut whiteout_M3ParticleEmitter,
23354        ) -> *mut whiteout_M3AnimRefF32;
23355        pub fn whiteout_m3_M3ParticleEmitter_set_initialSpeed(
23356            self_: *mut whiteout_M3ParticleEmitter,
23357            value: *const whiteout_M3AnimRefF32,
23358        );
23359        pub fn whiteout_m3_M3ParticleEmitter_get_initialSpeedRandom(
23360            self_: *mut whiteout_M3ParticleEmitter,
23361        ) -> *mut whiteout_M3AnimRefF32;
23362        pub fn whiteout_m3_M3ParticleEmitter_set_initialSpeedRandom(
23363            self_: *mut whiteout_M3ParticleEmitter,
23364            value: *const whiteout_M3AnimRefF32,
23365        );
23366        pub fn whiteout_m3_M3ParticleEmitter_get_initialYaw(
23367            self_: *mut whiteout_M3ParticleEmitter,
23368        ) -> *mut whiteout_M3AnimRefF32;
23369        pub fn whiteout_m3_M3ParticleEmitter_set_initialYaw(
23370            self_: *mut whiteout_M3ParticleEmitter,
23371            value: *const whiteout_M3AnimRefF32,
23372        );
23373        pub fn whiteout_m3_M3ParticleEmitter_get_initialPitch(
23374            self_: *mut whiteout_M3ParticleEmitter,
23375        ) -> *mut whiteout_M3AnimRefF32;
23376        pub fn whiteout_m3_M3ParticleEmitter_set_initialPitch(
23377            self_: *mut whiteout_M3ParticleEmitter,
23378            value: *const whiteout_M3AnimRefF32,
23379        );
23380        pub fn whiteout_m3_M3ParticleEmitter_get_initialHorizontal(
23381            self_: *mut whiteout_M3ParticleEmitter,
23382        ) -> *mut whiteout_M3AnimRefF32;
23383        pub fn whiteout_m3_M3ParticleEmitter_set_initialHorizontal(
23384            self_: *mut whiteout_M3ParticleEmitter,
23385            value: *const whiteout_M3AnimRefF32,
23386        );
23387        pub fn whiteout_m3_M3ParticleEmitter_get_initialVertical(
23388            self_: *mut whiteout_M3ParticleEmitter,
23389        ) -> *mut whiteout_M3AnimRefF32;
23390        pub fn whiteout_m3_M3ParticleEmitter_set_initialVertical(
23391            self_: *mut whiteout_M3ParticleEmitter,
23392            value: *const whiteout_M3AnimRefF32,
23393        );
23394        pub fn whiteout_m3_M3ParticleEmitter_get_lifetime(
23395            self_: *mut whiteout_M3ParticleEmitter,
23396        ) -> *mut whiteout_M3AnimRefF32;
23397        pub fn whiteout_m3_M3ParticleEmitter_set_lifetime(
23398            self_: *mut whiteout_M3ParticleEmitter,
23399            value: *const whiteout_M3AnimRefF32,
23400        );
23401        pub fn whiteout_m3_M3ParticleEmitter_get_lifetimeRandom(
23402            self_: *mut whiteout_M3ParticleEmitter,
23403        ) -> *mut whiteout_M3AnimRefF32;
23404        pub fn whiteout_m3_M3ParticleEmitter_set_lifetimeRandom(
23405            self_: *mut whiteout_M3ParticleEmitter,
23406            value: *const whiteout_M3AnimRefF32,
23407        );
23408        pub fn whiteout_m3_M3ParticleEmitter_get_killRadius(
23409            self_: *mut whiteout_M3ParticleEmitter,
23410        ) -> f32;
23411        pub fn whiteout_m3_M3ParticleEmitter_set_killRadius(
23412            self_: *mut whiteout_M3ParticleEmitter,
23413            value: f32,
23414        );
23415        pub fn whiteout_m3_M3ParticleEmitter_get_gravityX(
23416            self_: *mut whiteout_M3ParticleEmitter,
23417        ) -> u32;
23418        pub fn whiteout_m3_M3ParticleEmitter_set_gravityX(
23419            self_: *mut whiteout_M3ParticleEmitter,
23420            value: u32,
23421        );
23422        pub fn whiteout_m3_M3ParticleEmitter_get_gravityY(
23423            self_: *mut whiteout_M3ParticleEmitter,
23424        ) -> u32;
23425        pub fn whiteout_m3_M3ParticleEmitter_set_gravityY(
23426            self_: *mut whiteout_M3ParticleEmitter,
23427            value: u32,
23428        );
23429        pub fn whiteout_m3_M3ParticleEmitter_get_gravity(
23430            self_: *mut whiteout_M3ParticleEmitter,
23431        ) -> f32;
23432        pub fn whiteout_m3_M3ParticleEmitter_set_gravity(
23433            self_: *mut whiteout_M3ParticleEmitter,
23434            value: f32,
23435        );
23436        pub fn whiteout_m3_M3ParticleEmitter_get_sizeMidTime(
23437            self_: *mut whiteout_M3ParticleEmitter,
23438        ) -> f32;
23439        pub fn whiteout_m3_M3ParticleEmitter_set_sizeMidTime(
23440            self_: *mut whiteout_M3ParticleEmitter,
23441            value: f32,
23442        );
23443        pub fn whiteout_m3_M3ParticleEmitter_get_colorMidTime(
23444            self_: *mut whiteout_M3ParticleEmitter,
23445        ) -> f32;
23446        pub fn whiteout_m3_M3ParticleEmitter_set_colorMidTime(
23447            self_: *mut whiteout_M3ParticleEmitter,
23448            value: f32,
23449        );
23450        pub fn whiteout_m3_M3ParticleEmitter_get_alphaMidTime(
23451            self_: *mut whiteout_M3ParticleEmitter,
23452        ) -> f32;
23453        pub fn whiteout_m3_M3ParticleEmitter_set_alphaMidTime(
23454            self_: *mut whiteout_M3ParticleEmitter,
23455            value: f32,
23456        );
23457        pub fn whiteout_m3_M3ParticleEmitter_get_rotationMidTime(
23458            self_: *mut whiteout_M3ParticleEmitter,
23459        ) -> f32;
23460        pub fn whiteout_m3_M3ParticleEmitter_set_rotationMidTime(
23461            self_: *mut whiteout_M3ParticleEmitter,
23462            value: f32,
23463        );
23464        pub fn whiteout_m3_M3ParticleEmitter_get_sizeMidHoldTime(
23465            self_: *mut whiteout_M3ParticleEmitter,
23466        ) -> f32;
23467        pub fn whiteout_m3_M3ParticleEmitter_set_sizeMidHoldTime(
23468            self_: *mut whiteout_M3ParticleEmitter,
23469            value: f32,
23470        );
23471        pub fn whiteout_m3_M3ParticleEmitter_get_colorMidHoldTime(
23472            self_: *mut whiteout_M3ParticleEmitter,
23473        ) -> f32;
23474        pub fn whiteout_m3_M3ParticleEmitter_set_colorMidHoldTime(
23475            self_: *mut whiteout_M3ParticleEmitter,
23476            value: f32,
23477        );
23478        pub fn whiteout_m3_M3ParticleEmitter_get_alphaMidHoldTime(
23479            self_: *mut whiteout_M3ParticleEmitter,
23480        ) -> f32;
23481        pub fn whiteout_m3_M3ParticleEmitter_set_alphaMidHoldTime(
23482            self_: *mut whiteout_M3ParticleEmitter,
23483            value: f32,
23484        );
23485        pub fn whiteout_m3_M3ParticleEmitter_get_rotationMidHoldTime(
23486            self_: *mut whiteout_M3ParticleEmitter,
23487        ) -> f32;
23488        pub fn whiteout_m3_M3ParticleEmitter_set_rotationMidHoldTime(
23489            self_: *mut whiteout_M3ParticleEmitter,
23490            value: f32,
23491        );
23492        pub fn whiteout_m3_M3ParticleEmitter_get_sizeAnimation(
23493            self_: *mut whiteout_M3ParticleEmitter,
23494        ) -> *mut whiteout_M3AnimRefVector3f;
23495        pub fn whiteout_m3_M3ParticleEmitter_set_sizeAnimation(
23496            self_: *mut whiteout_M3ParticleEmitter,
23497            value: *const whiteout_M3AnimRefVector3f,
23498        );
23499        pub fn whiteout_m3_M3ParticleEmitter_get_rotationAnimation(
23500            self_: *mut whiteout_M3ParticleEmitter,
23501        ) -> *mut whiteout_M3AnimRefVector3f;
23502        pub fn whiteout_m3_M3ParticleEmitter_set_rotationAnimation(
23503            self_: *mut whiteout_M3ParticleEmitter,
23504            value: *const whiteout_M3AnimRefVector3f,
23505        );
23506        pub fn whiteout_m3_M3ParticleEmitter_get_colorStart(
23507            self_: *mut whiteout_M3ParticleEmitter,
23508        ) -> *mut whiteout_M3AnimRefM3ColorBGRA;
23509        pub fn whiteout_m3_M3ParticleEmitter_set_colorStart(
23510            self_: *mut whiteout_M3ParticleEmitter,
23511            value: *const whiteout_M3AnimRefM3ColorBGRA,
23512        );
23513        pub fn whiteout_m3_M3ParticleEmitter_get_colorMid(
23514            self_: *mut whiteout_M3ParticleEmitter,
23515        ) -> *mut whiteout_M3AnimRefM3ColorBGRA;
23516        pub fn whiteout_m3_M3ParticleEmitter_set_colorMid(
23517            self_: *mut whiteout_M3ParticleEmitter,
23518            value: *const whiteout_M3AnimRefM3ColorBGRA,
23519        );
23520        pub fn whiteout_m3_M3ParticleEmitter_get_colorEnd(
23521            self_: *mut whiteout_M3ParticleEmitter,
23522        ) -> *mut whiteout_M3AnimRefM3ColorBGRA;
23523        pub fn whiteout_m3_M3ParticleEmitter_set_colorEnd(
23524            self_: *mut whiteout_M3ParticleEmitter,
23525            value: *const whiteout_M3AnimRefM3ColorBGRA,
23526        );
23527        pub fn whiteout_m3_M3ParticleEmitter_get_drag(
23528            self_: *mut whiteout_M3ParticleEmitter,
23529        ) -> f32;
23530        pub fn whiteout_m3_M3ParticleEmitter_set_drag(
23531            self_: *mut whiteout_M3ParticleEmitter,
23532            value: f32,
23533        );
23534        pub fn whiteout_m3_M3ParticleEmitter_get_mass(
23535            self_: *mut whiteout_M3ParticleEmitter,
23536        ) -> f32;
23537        pub fn whiteout_m3_M3ParticleEmitter_set_mass(
23538            self_: *mut whiteout_M3ParticleEmitter,
23539            value: f32,
23540        );
23541        pub fn whiteout_m3_M3ParticleEmitter_get_massRandom(
23542            self_: *mut whiteout_M3ParticleEmitter,
23543        ) -> f32;
23544        pub fn whiteout_m3_M3ParticleEmitter_set_massRandom(
23545            self_: *mut whiteout_M3ParticleEmitter,
23546            value: f32,
23547        );
23548        pub fn whiteout_m3_M3ParticleEmitter_get_massSizeMultiplier(
23549            self_: *mut whiteout_M3ParticleEmitter,
23550        ) -> f32;
23551        pub fn whiteout_m3_M3ParticleEmitter_set_massSizeMultiplier(
23552            self_: *mut whiteout_M3ParticleEmitter,
23553            value: f32,
23554        );
23555        pub fn whiteout_m3_M3ParticleEmitter_get_localForces(
23556            self_: *mut whiteout_M3ParticleEmitter,
23557        ) -> u16;
23558        pub fn whiteout_m3_M3ParticleEmitter_set_localForces(
23559            self_: *mut whiteout_M3ParticleEmitter,
23560            value: u16,
23561        );
23562        pub fn whiteout_m3_M3ParticleEmitter_get_worldForces(
23563            self_: *mut whiteout_M3ParticleEmitter,
23564        ) -> u16;
23565        pub fn whiteout_m3_M3ParticleEmitter_set_worldForces(
23566            self_: *mut whiteout_M3ParticleEmitter,
23567            value: u16,
23568        );
23569        pub fn whiteout_m3_M3ParticleEmitter_get_localForcesFallback(
23570            self_: *mut whiteout_M3ParticleEmitter,
23571        ) -> u16;
23572        pub fn whiteout_m3_M3ParticleEmitter_set_localForcesFallback(
23573            self_: *mut whiteout_M3ParticleEmitter,
23574            value: u16,
23575        );
23576        pub fn whiteout_m3_M3ParticleEmitter_get_worldForcesFallback(
23577            self_: *mut whiteout_M3ParticleEmitter,
23578        ) -> u16;
23579        pub fn whiteout_m3_M3ParticleEmitter_set_worldForcesFallback(
23580            self_: *mut whiteout_M3ParticleEmitter,
23581            value: u16,
23582        );
23583        pub fn whiteout_m3_M3ParticleEmitter_get_worldForcesMassMultiplier(
23584            self_: *mut whiteout_M3ParticleEmitter,
23585        ) -> f32;
23586        pub fn whiteout_m3_M3ParticleEmitter_set_worldForcesMassMultiplier(
23587            self_: *mut whiteout_M3ParticleEmitter,
23588            value: f32,
23589        );
23590        pub fn whiteout_m3_M3ParticleEmitter_get_noiseAmplitude(
23591            self_: *mut whiteout_M3ParticleEmitter,
23592        ) -> f32;
23593        pub fn whiteout_m3_M3ParticleEmitter_set_noiseAmplitude(
23594            self_: *mut whiteout_M3ParticleEmitter,
23595            value: f32,
23596        );
23597        pub fn whiteout_m3_M3ParticleEmitter_get_noiseFrequency(
23598            self_: *mut whiteout_M3ParticleEmitter,
23599        ) -> f32;
23600        pub fn whiteout_m3_M3ParticleEmitter_set_noiseFrequency(
23601            self_: *mut whiteout_M3ParticleEmitter,
23602            value: f32,
23603        );
23604        pub fn whiteout_m3_M3ParticleEmitter_get_noiseCoherence(
23605            self_: *mut whiteout_M3ParticleEmitter,
23606        ) -> f32;
23607        pub fn whiteout_m3_M3ParticleEmitter_set_noiseCoherence(
23608            self_: *mut whiteout_M3ParticleEmitter,
23609            value: f32,
23610        );
23611        pub fn whiteout_m3_M3ParticleEmitter_get_noiseEdge(
23612            self_: *mut whiteout_M3ParticleEmitter,
23613        ) -> f32;
23614        pub fn whiteout_m3_M3ParticleEmitter_set_noiseEdge(
23615            self_: *mut whiteout_M3ParticleEmitter,
23616            value: f32,
23617        );
23618        pub fn whiteout_m3_M3ParticleEmitter_get_indexPlusLength(
23619            self_: *mut whiteout_M3ParticleEmitter,
23620        ) -> u32;
23621        pub fn whiteout_m3_M3ParticleEmitter_set_indexPlusLength(
23622            self_: *mut whiteout_M3ParticleEmitter,
23623            value: u32,
23624        );
23625        pub fn whiteout_m3_M3ParticleEmitter_get_maxParticles(
23626            self_: *mut whiteout_M3ParticleEmitter,
23627        ) -> u32;
23628        pub fn whiteout_m3_M3ParticleEmitter_set_maxParticles(
23629            self_: *mut whiteout_M3ParticleEmitter,
23630            value: u32,
23631        );
23632        pub fn whiteout_m3_M3ParticleEmitter_get_emissionRate(
23633            self_: *mut whiteout_M3ParticleEmitter,
23634        ) -> *mut whiteout_M3AnimRefF32;
23635        pub fn whiteout_m3_M3ParticleEmitter_set_emissionRate(
23636            self_: *mut whiteout_M3ParticleEmitter,
23637            value: *const whiteout_M3AnimRefF32,
23638        );
23639        pub fn whiteout_m3_M3ParticleEmitter_get_emitterShape(
23640            self_: *mut whiteout_M3ParticleEmitter,
23641        ) -> i32;
23642        pub fn whiteout_m3_M3ParticleEmitter_set_emitterShape(
23643            self_: *mut whiteout_M3ParticleEmitter,
23644            value: i32,
23645        );
23646        pub fn whiteout_m3_M3ParticleEmitter_get_shapeOuter(
23647            self_: *mut whiteout_M3ParticleEmitter,
23648        ) -> *mut whiteout_M3AnimRefVector3f;
23649        pub fn whiteout_m3_M3ParticleEmitter_set_shapeOuter(
23650            self_: *mut whiteout_M3ParticleEmitter,
23651            value: *const whiteout_M3AnimRefVector3f,
23652        );
23653        pub fn whiteout_m3_M3ParticleEmitter_get_shapeInner(
23654            self_: *mut whiteout_M3ParticleEmitter,
23655        ) -> *mut whiteout_M3AnimRefVector3f;
23656        pub fn whiteout_m3_M3ParticleEmitter_set_shapeInner(
23657            self_: *mut whiteout_M3ParticleEmitter,
23658            value: *const whiteout_M3AnimRefVector3f,
23659        );
23660        pub fn whiteout_m3_M3ParticleEmitter_get_outerRadius(
23661            self_: *mut whiteout_M3ParticleEmitter,
23662        ) -> *mut whiteout_M3AnimRefF32;
23663        pub fn whiteout_m3_M3ParticleEmitter_set_outerRadius(
23664            self_: *mut whiteout_M3ParticleEmitter,
23665            value: *const whiteout_M3AnimRefF32,
23666        );
23667        pub fn whiteout_m3_M3ParticleEmitter_get_innerRadius(
23668            self_: *mut whiteout_M3ParticleEmitter,
23669        ) -> *mut whiteout_M3AnimRefF32;
23670        pub fn whiteout_m3_M3ParticleEmitter_set_innerRadius(
23671            self_: *mut whiteout_M3ParticleEmitter,
23672            value: *const whiteout_M3AnimRefF32,
23673        );
23674        pub fn whiteout_m3_M3ParticleEmitter_get_shapeRegions_count(
23675            self_: *mut whiteout_M3ParticleEmitter,
23676        ) -> usize;
23677        pub fn whiteout_m3_M3ParticleEmitter_resize_shapeRegions(
23678            self_: *mut whiteout_M3ParticleEmitter,
23679            count: usize,
23680        );
23681        pub fn whiteout_m3_M3ParticleEmitter_get_shapeRegions_data(
23682            self_: *mut whiteout_M3ParticleEmitter,
23683        ) -> *const u32;
23684        pub fn whiteout_m3_M3ParticleEmitter_assign_shapeRegions(
23685            self_: *mut whiteout_M3ParticleEmitter,
23686            data: *const u32,
23687            count: usize,
23688        );
23689        pub fn whiteout_m3_M3ParticleEmitter_get_velocityType(
23690            self_: *mut whiteout_M3ParticleEmitter,
23691        ) -> u32;
23692        pub fn whiteout_m3_M3ParticleEmitter_set_velocityType(
23693            self_: *mut whiteout_M3ParticleEmitter,
23694            value: u32,
23695        );
23696        pub fn whiteout_m3_M3ParticleEmitter_get_sizeRandomEnable(
23697            self_: *mut whiteout_M3ParticleEmitter,
23698        ) -> u32;
23699        pub fn whiteout_m3_M3ParticleEmitter_set_sizeRandomEnable(
23700            self_: *mut whiteout_M3ParticleEmitter,
23701            value: u32,
23702        );
23703        pub fn whiteout_m3_M3ParticleEmitter_get_sizeRandomAnimation(
23704            self_: *mut whiteout_M3ParticleEmitter,
23705        ) -> *mut whiteout_M3AnimRefVector3f;
23706        pub fn whiteout_m3_M3ParticleEmitter_set_sizeRandomAnimation(
23707            self_: *mut whiteout_M3ParticleEmitter,
23708            value: *const whiteout_M3AnimRefVector3f,
23709        );
23710        pub fn whiteout_m3_M3ParticleEmitter_get_rotationRandomEnable(
23711            self_: *mut whiteout_M3ParticleEmitter,
23712        ) -> u32;
23713        pub fn whiteout_m3_M3ParticleEmitter_set_rotationRandomEnable(
23714            self_: *mut whiteout_M3ParticleEmitter,
23715            value: u32,
23716        );
23717        pub fn whiteout_m3_M3ParticleEmitter_get_rotationRandomAnimation(
23718            self_: *mut whiteout_M3ParticleEmitter,
23719        ) -> *mut whiteout_M3AnimRefVector3f;
23720        pub fn whiteout_m3_M3ParticleEmitter_set_rotationRandomAnimation(
23721            self_: *mut whiteout_M3ParticleEmitter,
23722            value: *const whiteout_M3AnimRefVector3f,
23723        );
23724        pub fn whiteout_m3_M3ParticleEmitter_get_colorRandomEnable(
23725            self_: *mut whiteout_M3ParticleEmitter,
23726        ) -> u32;
23727        pub fn whiteout_m3_M3ParticleEmitter_set_colorRandomEnable(
23728            self_: *mut whiteout_M3ParticleEmitter,
23729            value: u32,
23730        );
23731        pub fn whiteout_m3_M3ParticleEmitter_get_colorStartRandom(
23732            self_: *mut whiteout_M3ParticleEmitter,
23733        ) -> *mut whiteout_M3AnimRefM3ColorBGRA;
23734        pub fn whiteout_m3_M3ParticleEmitter_set_colorStartRandom(
23735            self_: *mut whiteout_M3ParticleEmitter,
23736            value: *const whiteout_M3AnimRefM3ColorBGRA,
23737        );
23738        pub fn whiteout_m3_M3ParticleEmitter_get_colorMidRandom(
23739            self_: *mut whiteout_M3ParticleEmitter,
23740        ) -> *mut whiteout_M3AnimRefM3ColorBGRA;
23741        pub fn whiteout_m3_M3ParticleEmitter_set_colorMidRandom(
23742            self_: *mut whiteout_M3ParticleEmitter,
23743            value: *const whiteout_M3AnimRefM3ColorBGRA,
23744        );
23745        pub fn whiteout_m3_M3ParticleEmitter_get_colorEndRandom(
23746            self_: *mut whiteout_M3ParticleEmitter,
23747        ) -> *mut whiteout_M3AnimRefM3ColorBGRA;
23748        pub fn whiteout_m3_M3ParticleEmitter_set_colorEndRandom(
23749            self_: *mut whiteout_M3ParticleEmitter,
23750            value: *const whiteout_M3AnimRefM3ColorBGRA,
23751        );
23752        pub fn whiteout_m3_M3ParticleEmitter_get_alphaRandomEnable(
23753            self_: *mut whiteout_M3ParticleEmitter,
23754        ) -> u32;
23755        pub fn whiteout_m3_M3ParticleEmitter_set_alphaRandomEnable(
23756            self_: *mut whiteout_M3ParticleEmitter,
23757            value: u32,
23758        );
23759        pub fn whiteout_m3_M3ParticleEmitter_get_squirtAmount(
23760            self_: *mut whiteout_M3ParticleEmitter,
23761        ) -> *mut whiteout_M3AnimRefU16;
23762        pub fn whiteout_m3_M3ParticleEmitter_set_squirtAmount(
23763            self_: *mut whiteout_M3ParticleEmitter,
23764            value: *const whiteout_M3AnimRefU16,
23765        );
23766        pub fn whiteout_m3_M3ParticleEmitter_get_flipbookStartInitIndex(
23767            self_: *mut whiteout_M3ParticleEmitter,
23768        ) -> u8;
23769        pub fn whiteout_m3_M3ParticleEmitter_set_flipbookStartInitIndex(
23770            self_: *mut whiteout_M3ParticleEmitter,
23771            value: u8,
23772        );
23773        pub fn whiteout_m3_M3ParticleEmitter_get_flipbookStartStopIndex(
23774            self_: *mut whiteout_M3ParticleEmitter,
23775        ) -> u8;
23776        pub fn whiteout_m3_M3ParticleEmitter_set_flipbookStartStopIndex(
23777            self_: *mut whiteout_M3ParticleEmitter,
23778            value: u8,
23779        );
23780        pub fn whiteout_m3_M3ParticleEmitter_get_flipbookEndInitIndex(
23781            self_: *mut whiteout_M3ParticleEmitter,
23782        ) -> u8;
23783        pub fn whiteout_m3_M3ParticleEmitter_set_flipbookEndInitIndex(
23784            self_: *mut whiteout_M3ParticleEmitter,
23785            value: u8,
23786        );
23787        pub fn whiteout_m3_M3ParticleEmitter_get_flipbookEndStopIndex(
23788            self_: *mut whiteout_M3ParticleEmitter,
23789        ) -> u8;
23790        pub fn whiteout_m3_M3ParticleEmitter_set_flipbookEndStopIndex(
23791            self_: *mut whiteout_M3ParticleEmitter,
23792            value: u8,
23793        );
23794        pub fn whiteout_m3_M3ParticleEmitter_get_flipbookMidTime(
23795            self_: *mut whiteout_M3ParticleEmitter,
23796        ) -> f32;
23797        pub fn whiteout_m3_M3ParticleEmitter_set_flipbookMidTime(
23798            self_: *mut whiteout_M3ParticleEmitter,
23799            value: f32,
23800        );
23801        pub fn whiteout_m3_M3ParticleEmitter_get_flipbookColumns(
23802            self_: *mut whiteout_M3ParticleEmitter,
23803        ) -> u16;
23804        pub fn whiteout_m3_M3ParticleEmitter_set_flipbookColumns(
23805            self_: *mut whiteout_M3ParticleEmitter,
23806            value: u16,
23807        );
23808        pub fn whiteout_m3_M3ParticleEmitter_get_flipbookRows(
23809            self_: *mut whiteout_M3ParticleEmitter,
23810        ) -> u16;
23811        pub fn whiteout_m3_M3ParticleEmitter_set_flipbookRows(
23812            self_: *mut whiteout_M3ParticleEmitter,
23813            value: u16,
23814        );
23815        pub fn whiteout_m3_M3ParticleEmitter_get_flipbookColumnFraction(
23816            self_: *mut whiteout_M3ParticleEmitter,
23817        ) -> f32;
23818        pub fn whiteout_m3_M3ParticleEmitter_set_flipbookColumnFraction(
23819            self_: *mut whiteout_M3ParticleEmitter,
23820            value: f32,
23821        );
23822        pub fn whiteout_m3_M3ParticleEmitter_get_flipbookRowFraction(
23823            self_: *mut whiteout_M3ParticleEmitter,
23824        ) -> f32;
23825        pub fn whiteout_m3_M3ParticleEmitter_set_flipbookRowFraction(
23826            self_: *mut whiteout_M3ParticleEmitter,
23827            value: f32,
23828        );
23829        pub fn whiteout_m3_M3ParticleEmitter_get_bounce(
23830            self_: *mut whiteout_M3ParticleEmitter,
23831        ) -> f32;
23832        pub fn whiteout_m3_M3ParticleEmitter_set_bounce(
23833            self_: *mut whiteout_M3ParticleEmitter,
23834            value: f32,
23835        );
23836        pub fn whiteout_m3_M3ParticleEmitter_get_friction(
23837            self_: *mut whiteout_M3ParticleEmitter,
23838        ) -> f32;
23839        pub fn whiteout_m3_M3ParticleEmitter_set_friction(
23840            self_: *mut whiteout_M3ParticleEmitter,
23841            value: f32,
23842        );
23843        pub fn whiteout_m3_M3ParticleEmitter_get_collisionSpawnIndex(
23844            self_: *mut whiteout_M3ParticleEmitter,
23845        ) -> i32;
23846        pub fn whiteout_m3_M3ParticleEmitter_set_collisionSpawnIndex(
23847            self_: *mut whiteout_M3ParticleEmitter,
23848            value: i32,
23849        );
23850        pub fn whiteout_m3_M3ParticleEmitter_get_collisionSpawnMin(
23851            self_: *mut whiteout_M3ParticleEmitter,
23852        ) -> u32;
23853        pub fn whiteout_m3_M3ParticleEmitter_set_collisionSpawnMin(
23854            self_: *mut whiteout_M3ParticleEmitter,
23855            value: u32,
23856        );
23857        pub fn whiteout_m3_M3ParticleEmitter_get_collisionSpawnMax(
23858            self_: *mut whiteout_M3ParticleEmitter,
23859        ) -> u32;
23860        pub fn whiteout_m3_M3ParticleEmitter_set_collisionSpawnMax(
23861            self_: *mut whiteout_M3ParticleEmitter,
23862            value: u32,
23863        );
23864        pub fn whiteout_m3_M3ParticleEmitter_get_collisionSpawnChance(
23865            self_: *mut whiteout_M3ParticleEmitter,
23866        ) -> f32;
23867        pub fn whiteout_m3_M3ParticleEmitter_set_collisionSpawnChance(
23868            self_: *mut whiteout_M3ParticleEmitter,
23869            value: f32,
23870        );
23871        pub fn whiteout_m3_M3ParticleEmitter_get_collisionSpawnEnergy(
23872            self_: *mut whiteout_M3ParticleEmitter,
23873        ) -> f32;
23874        pub fn whiteout_m3_M3ParticleEmitter_set_collisionSpawnEnergy(
23875            self_: *mut whiteout_M3ParticleEmitter,
23876            value: f32,
23877        );
23878        pub fn whiteout_m3_M3ParticleEmitter_get_collisionDieBounce(
23879            self_: *mut whiteout_M3ParticleEmitter,
23880        ) -> u32;
23881        pub fn whiteout_m3_M3ParticleEmitter_set_collisionDieBounce(
23882            self_: *mut whiteout_M3ParticleEmitter,
23883            value: u32,
23884        );
23885        pub fn whiteout_m3_M3ParticleEmitter_get_instanceType(
23886            self_: *mut whiteout_M3ParticleEmitter,
23887        ) -> i32;
23888        pub fn whiteout_m3_M3ParticleEmitter_set_instanceType(
23889            self_: *mut whiteout_M3ParticleEmitter,
23890            value: i32,
23891        );
23892        pub fn whiteout_m3_M3ParticleEmitter_get_tailLength(
23893            self_: *mut whiteout_M3ParticleEmitter,
23894        ) -> f32;
23895        pub fn whiteout_m3_M3ParticleEmitter_set_tailLength(
23896            self_: *mut whiteout_M3ParticleEmitter,
23897            value: f32,
23898        );
23899        pub fn whiteout_m3_M3ParticleEmitter_get_instanceAngle(
23900            self_: *mut whiteout_M3ParticleEmitter,
23901        ) -> *mut core::ffi::c_void;
23902        pub fn whiteout_m3_M3ParticleEmitter_set_instanceAngle(
23903            self_: *mut whiteout_M3ParticleEmitter,
23904            value: *const core::ffi::c_void,
23905        );
23906        pub fn whiteout_m3_M3ParticleEmitter_get_instanceDistance(
23907            self_: *mut whiteout_M3ParticleEmitter,
23908        ) -> f32;
23909        pub fn whiteout_m3_M3ParticleEmitter_set_instanceDistance(
23910            self_: *mut whiteout_M3ParticleEmitter,
23911            value: f32,
23912        );
23913        pub fn whiteout_m3_M3ParticleEmitter_get_pitchType(
23914            self_: *mut whiteout_M3ParticleEmitter,
23915        ) -> u32;
23916        pub fn whiteout_m3_M3ParticleEmitter_set_pitchType(
23917            self_: *mut whiteout_M3ParticleEmitter,
23918            value: u32,
23919        );
23920        pub fn whiteout_m3_M3ParticleEmitter_get_pitchAmplitude(
23921            self_: *mut whiteout_M3ParticleEmitter,
23922        ) -> *mut whiteout_M3AnimRefF32;
23923        pub fn whiteout_m3_M3ParticleEmitter_set_pitchAmplitude(
23924            self_: *mut whiteout_M3ParticleEmitter,
23925            value: *const whiteout_M3AnimRefF32,
23926        );
23927        pub fn whiteout_m3_M3ParticleEmitter_get_pitchFrequency(
23928            self_: *mut whiteout_M3ParticleEmitter,
23929        ) -> *mut whiteout_M3AnimRefF32;
23930        pub fn whiteout_m3_M3ParticleEmitter_set_pitchFrequency(
23931            self_: *mut whiteout_M3ParticleEmitter,
23932            value: *const whiteout_M3AnimRefF32,
23933        );
23934        pub fn whiteout_m3_M3ParticleEmitter_get_yawType(
23935            self_: *mut whiteout_M3ParticleEmitter,
23936        ) -> u32;
23937        pub fn whiteout_m3_M3ParticleEmitter_set_yawType(
23938            self_: *mut whiteout_M3ParticleEmitter,
23939            value: u32,
23940        );
23941        pub fn whiteout_m3_M3ParticleEmitter_get_yawAmplitude(
23942            self_: *mut whiteout_M3ParticleEmitter,
23943        ) -> *mut whiteout_M3AnimRefF32;
23944        pub fn whiteout_m3_M3ParticleEmitter_set_yawAmplitude(
23945            self_: *mut whiteout_M3ParticleEmitter,
23946            value: *const whiteout_M3AnimRefF32,
23947        );
23948        pub fn whiteout_m3_M3ParticleEmitter_get_yawFrequency(
23949            self_: *mut whiteout_M3ParticleEmitter,
23950        ) -> *mut whiteout_M3AnimRefF32;
23951        pub fn whiteout_m3_M3ParticleEmitter_set_yawFrequency(
23952            self_: *mut whiteout_M3ParticleEmitter,
23953            value: *const whiteout_M3AnimRefF32,
23954        );
23955        pub fn whiteout_m3_M3ParticleEmitter_get_speedType(
23956            self_: *mut whiteout_M3ParticleEmitter,
23957        ) -> u32;
23958        pub fn whiteout_m3_M3ParticleEmitter_set_speedType(
23959            self_: *mut whiteout_M3ParticleEmitter,
23960            value: u32,
23961        );
23962        pub fn whiteout_m3_M3ParticleEmitter_get_speedAmplitude(
23963            self_: *mut whiteout_M3ParticleEmitter,
23964        ) -> *mut whiteout_M3AnimRefF32;
23965        pub fn whiteout_m3_M3ParticleEmitter_set_speedAmplitude(
23966            self_: *mut whiteout_M3ParticleEmitter,
23967            value: *const whiteout_M3AnimRefF32,
23968        );
23969        pub fn whiteout_m3_M3ParticleEmitter_get_speedFrequency(
23970            self_: *mut whiteout_M3ParticleEmitter,
23971        ) -> *mut whiteout_M3AnimRefF32;
23972        pub fn whiteout_m3_M3ParticleEmitter_set_speedFrequency(
23973            self_: *mut whiteout_M3ParticleEmitter,
23974            value: *const whiteout_M3AnimRefF32,
23975        );
23976        pub fn whiteout_m3_M3ParticleEmitter_get_sizeType(
23977            self_: *mut whiteout_M3ParticleEmitter,
23978        ) -> u32;
23979        pub fn whiteout_m3_M3ParticleEmitter_set_sizeType(
23980            self_: *mut whiteout_M3ParticleEmitter,
23981            value: u32,
23982        );
23983        pub fn whiteout_m3_M3ParticleEmitter_get_sizeAmplitude(
23984            self_: *mut whiteout_M3ParticleEmitter,
23985        ) -> *mut whiteout_M3AnimRefF32;
23986        pub fn whiteout_m3_M3ParticleEmitter_set_sizeAmplitude(
23987            self_: *mut whiteout_M3ParticleEmitter,
23988            value: *const whiteout_M3AnimRefF32,
23989        );
23990        pub fn whiteout_m3_M3ParticleEmitter_get_sizeFrequency(
23991            self_: *mut whiteout_M3ParticleEmitter,
23992        ) -> *mut whiteout_M3AnimRefF32;
23993        pub fn whiteout_m3_M3ParticleEmitter_set_sizeFrequency(
23994            self_: *mut whiteout_M3ParticleEmitter,
23995            value: *const whiteout_M3AnimRefF32,
23996        );
23997        pub fn whiteout_m3_M3ParticleEmitter_get_alphaType(
23998            self_: *mut whiteout_M3ParticleEmitter,
23999        ) -> u32;
24000        pub fn whiteout_m3_M3ParticleEmitter_set_alphaType(
24001            self_: *mut whiteout_M3ParticleEmitter,
24002            value: u32,
24003        );
24004        pub fn whiteout_m3_M3ParticleEmitter_get_alphaAmplitude(
24005            self_: *mut whiteout_M3ParticleEmitter,
24006        ) -> *mut whiteout_M3AnimRefF32;
24007        pub fn whiteout_m3_M3ParticleEmitter_set_alphaAmplitude(
24008            self_: *mut whiteout_M3ParticleEmitter,
24009            value: *const whiteout_M3AnimRefF32,
24010        );
24011        pub fn whiteout_m3_M3ParticleEmitter_get_alphaFrequency(
24012            self_: *mut whiteout_M3ParticleEmitter,
24013        ) -> *mut whiteout_M3AnimRefF32;
24014        pub fn whiteout_m3_M3ParticleEmitter_set_alphaFrequency(
24015            self_: *mut whiteout_M3ParticleEmitter,
24016            value: *const whiteout_M3AnimRefF32,
24017        );
24018        pub fn whiteout_m3_M3ParticleEmitter_get_colorType(
24019            self_: *mut whiteout_M3ParticleEmitter,
24020        ) -> u32;
24021        pub fn whiteout_m3_M3ParticleEmitter_set_colorType(
24022            self_: *mut whiteout_M3ParticleEmitter,
24023            value: u32,
24024        );
24025        pub fn whiteout_m3_M3ParticleEmitter_get_colorAmplitude(
24026            self_: *mut whiteout_M3ParticleEmitter,
24027        ) -> *mut whiteout_M3AnimRefF32;
24028        pub fn whiteout_m3_M3ParticleEmitter_set_colorAmplitude(
24029            self_: *mut whiteout_M3ParticleEmitter,
24030            value: *const whiteout_M3AnimRefF32,
24031        );
24032        pub fn whiteout_m3_M3ParticleEmitter_get_colorFrequency(
24033            self_: *mut whiteout_M3ParticleEmitter,
24034        ) -> *mut whiteout_M3AnimRefF32;
24035        pub fn whiteout_m3_M3ParticleEmitter_set_colorFrequency(
24036            self_: *mut whiteout_M3ParticleEmitter,
24037            value: *const whiteout_M3AnimRefF32,
24038        );
24039        pub fn whiteout_m3_M3ParticleEmitter_get_rotationType(
24040            self_: *mut whiteout_M3ParticleEmitter,
24041        ) -> u32;
24042        pub fn whiteout_m3_M3ParticleEmitter_set_rotationType(
24043            self_: *mut whiteout_M3ParticleEmitter,
24044            value: u32,
24045        );
24046        pub fn whiteout_m3_M3ParticleEmitter_get_rotationAmplitude(
24047            self_: *mut whiteout_M3ParticleEmitter,
24048        ) -> *mut whiteout_M3AnimRefF32;
24049        pub fn whiteout_m3_M3ParticleEmitter_set_rotationAmplitude(
24050            self_: *mut whiteout_M3ParticleEmitter,
24051            value: *const whiteout_M3AnimRefF32,
24052        );
24053        pub fn whiteout_m3_M3ParticleEmitter_get_rotationFrequency(
24054            self_: *mut whiteout_M3ParticleEmitter,
24055        ) -> *mut whiteout_M3AnimRefF32;
24056        pub fn whiteout_m3_M3ParticleEmitter_set_rotationFrequency(
24057            self_: *mut whiteout_M3ParticleEmitter,
24058            value: *const whiteout_M3AnimRefF32,
24059        );
24060        pub fn whiteout_m3_M3ParticleEmitter_get_horizontalType(
24061            self_: *mut whiteout_M3ParticleEmitter,
24062        ) -> u32;
24063        pub fn whiteout_m3_M3ParticleEmitter_set_horizontalType(
24064            self_: *mut whiteout_M3ParticleEmitter,
24065            value: u32,
24066        );
24067        pub fn whiteout_m3_M3ParticleEmitter_get_horizontalAmplitude(
24068            self_: *mut whiteout_M3ParticleEmitter,
24069        ) -> *mut whiteout_M3AnimRefF32;
24070        pub fn whiteout_m3_M3ParticleEmitter_set_horizontalAmplitude(
24071            self_: *mut whiteout_M3ParticleEmitter,
24072            value: *const whiteout_M3AnimRefF32,
24073        );
24074        pub fn whiteout_m3_M3ParticleEmitter_get_horizontalFrequency(
24075            self_: *mut whiteout_M3ParticleEmitter,
24076        ) -> *mut whiteout_M3AnimRefF32;
24077        pub fn whiteout_m3_M3ParticleEmitter_set_horizontalFrequency(
24078            self_: *mut whiteout_M3ParticleEmitter,
24079            value: *const whiteout_M3AnimRefF32,
24080        );
24081        pub fn whiteout_m3_M3ParticleEmitter_get_verticalType(
24082            self_: *mut whiteout_M3ParticleEmitter,
24083        ) -> u32;
24084        pub fn whiteout_m3_M3ParticleEmitter_set_verticalType(
24085            self_: *mut whiteout_M3ParticleEmitter,
24086            value: u32,
24087        );
24088        pub fn whiteout_m3_M3ParticleEmitter_get_verticalAmplitude(
24089            self_: *mut whiteout_M3ParticleEmitter,
24090        ) -> *mut whiteout_M3AnimRefF32;
24091        pub fn whiteout_m3_M3ParticleEmitter_set_verticalAmplitude(
24092            self_: *mut whiteout_M3ParticleEmitter,
24093            value: *const whiteout_M3AnimRefF32,
24094        );
24095        pub fn whiteout_m3_M3ParticleEmitter_get_verticalFrequency(
24096            self_: *mut whiteout_M3ParticleEmitter,
24097        ) -> *mut whiteout_M3AnimRefF32;
24098        pub fn whiteout_m3_M3ParticleEmitter_set_verticalFrequency(
24099            self_: *mut whiteout_M3ParticleEmitter,
24100            value: *const whiteout_M3AnimRefF32,
24101        );
24102        pub fn whiteout_m3_M3ParticleEmitter_get_particleVelocity(
24103            self_: *mut whiteout_M3ParticleEmitter,
24104        ) -> *mut whiteout_M3AnimRefF32;
24105        pub fn whiteout_m3_M3ParticleEmitter_set_particleVelocity(
24106            self_: *mut whiteout_M3ParticleEmitter,
24107            value: *const whiteout_M3AnimRefF32,
24108        );
24109        pub fn whiteout_m3_M3ParticleEmitter_get_phaseShift(
24110            self_: *mut whiteout_M3ParticleEmitter,
24111        ) -> *mut whiteout_M3AnimRefF32;
24112        pub fn whiteout_m3_M3ParticleEmitter_set_phaseShift(
24113            self_: *mut whiteout_M3ParticleEmitter,
24114            value: *const whiteout_M3AnimRefF32,
24115        );
24116        pub fn whiteout_m3_M3ParticleEmitter_get_flags(
24117            self_: *mut whiteout_M3ParticleEmitter,
24118        ) -> i32;
24119        pub fn whiteout_m3_M3ParticleEmitter_set_flags(
24120            self_: *mut whiteout_M3ParticleEmitter,
24121            value: i32,
24122        );
24123        pub fn whiteout_m3_M3ParticleEmitter_get_rotationFlags(
24124            self_: *mut whiteout_M3ParticleEmitter,
24125        ) -> i32;
24126        pub fn whiteout_m3_M3ParticleEmitter_set_rotationFlags(
24127            self_: *mut whiteout_M3ParticleEmitter,
24128            value: i32,
24129        );
24130        pub fn whiteout_m3_M3ParticleEmitter_get_colorSmoothing(
24131            self_: *mut whiteout_M3ParticleEmitter,
24132        ) -> i32;
24133        pub fn whiteout_m3_M3ParticleEmitter_set_colorSmoothing(
24134            self_: *mut whiteout_M3ParticleEmitter,
24135            value: i32,
24136        );
24137        pub fn whiteout_m3_M3ParticleEmitter_get_sizeSmoothing(
24138            self_: *mut whiteout_M3ParticleEmitter,
24139        ) -> i32;
24140        pub fn whiteout_m3_M3ParticleEmitter_set_sizeSmoothing(
24141            self_: *mut whiteout_M3ParticleEmitter,
24142            value: i32,
24143        );
24144        pub fn whiteout_m3_M3ParticleEmitter_get_rotationSmoothing(
24145            self_: *mut whiteout_M3ParticleEmitter,
24146        ) -> i32;
24147        pub fn whiteout_m3_M3ParticleEmitter_set_rotationSmoothing(
24148            self_: *mut whiteout_M3ParticleEmitter,
24149            value: i32,
24150        );
24151        pub fn whiteout_m3_M3ParticleEmitter_get_alphaThreshold(
24152            self_: *mut whiteout_M3ParticleEmitter,
24153        ) -> *mut whiteout_M3AnimRefF32;
24154        pub fn whiteout_m3_M3ParticleEmitter_set_alphaThreshold(
24155            self_: *mut whiteout_M3ParticleEmitter,
24156            value: *const whiteout_M3AnimRefF32,
24157        );
24158        pub fn whiteout_m3_M3ParticleEmitter_get_uvOffset(
24159            self_: *mut whiteout_M3ParticleEmitter,
24160        ) -> *mut whiteout_M3AnimRefVector2f;
24161        pub fn whiteout_m3_M3ParticleEmitter_set_uvOffset(
24162            self_: *mut whiteout_M3ParticleEmitter,
24163            value: *const whiteout_M3AnimRefVector2f,
24164        );
24165        pub fn whiteout_m3_M3ParticleEmitter_get_uvAngle(
24166            self_: *mut whiteout_M3ParticleEmitter,
24167        ) -> *mut whiteout_M3AnimRefVector3f;
24168        pub fn whiteout_m3_M3ParticleEmitter_set_uvAngle(
24169            self_: *mut whiteout_M3ParticleEmitter,
24170            value: *const whiteout_M3AnimRefVector3f,
24171        );
24172        pub fn whiteout_m3_M3ParticleEmitter_get_uvTiling(
24173            self_: *mut whiteout_M3ParticleEmitter,
24174        ) -> *mut whiteout_M3AnimRefVector2f;
24175        pub fn whiteout_m3_M3ParticleEmitter_set_uvTiling(
24176            self_: *mut whiteout_M3ParticleEmitter,
24177            value: *const whiteout_M3AnimRefVector2f,
24178        );
24179        pub fn whiteout_m3_M3ParticleEmitter_get_splineLineData_count(
24180            self_: *mut whiteout_M3ParticleEmitter,
24181        ) -> usize;
24182        pub fn whiteout_m3_M3ParticleEmitter_resize_splineLineData(
24183            self_: *mut whiteout_M3ParticleEmitter,
24184            count: usize,
24185        );
24186        pub fn whiteout_m3_M3ParticleEmitter_get_splineLineData_at(
24187            self_: *mut whiteout_M3ParticleEmitter,
24188            index: usize,
24189        ) -> *mut whiteout_M3AnimRefVector3f;
24190        pub fn whiteout_m3_M3ParticleEmitter_get_windMultiplier(
24191            self_: *mut whiteout_M3ParticleEmitter,
24192        ) -> f32;
24193        pub fn whiteout_m3_M3ParticleEmitter_set_windMultiplier(
24194            self_: *mut whiteout_M3ParticleEmitter,
24195            value: f32,
24196        );
24197        pub fn whiteout_m3_M3ParticleEmitter_get_lodReduce(
24198            self_: *mut whiteout_M3ParticleEmitter,
24199        ) -> u32;
24200        pub fn whiteout_m3_M3ParticleEmitter_set_lodReduce(
24201            self_: *mut whiteout_M3ParticleEmitter,
24202            value: u32,
24203        );
24204        pub fn whiteout_m3_M3ParticleEmitter_get_lodCut(
24205            self_: *mut whiteout_M3ParticleEmitter,
24206        ) -> u32;
24207        pub fn whiteout_m3_M3ParticleEmitter_set_lodCut(
24208            self_: *mut whiteout_M3ParticleEmitter,
24209            value: u32,
24210        );
24211        pub fn whiteout_m3_M3ParticleEmitter_get_lowerBound(
24212            self_: *mut whiteout_M3ParticleEmitter,
24213        ) -> *mut whiteout_M3AnimRefF32;
24214        pub fn whiteout_m3_M3ParticleEmitter_set_lowerBound(
24215            self_: *mut whiteout_M3ParticleEmitter,
24216            value: *const whiteout_M3AnimRefF32,
24217        );
24218        pub fn whiteout_m3_M3ParticleEmitter_get_upperBound(
24219            self_: *mut whiteout_M3ParticleEmitter,
24220        ) -> *mut whiteout_M3AnimRefF32;
24221        pub fn whiteout_m3_M3ParticleEmitter_set_upperBound(
24222            self_: *mut whiteout_M3ParticleEmitter,
24223            value: *const whiteout_M3AnimRefF32,
24224        );
24225        pub fn whiteout_m3_M3ParticleEmitter_get_trailLinkIndex(
24226            self_: *mut whiteout_M3ParticleEmitter,
24227        ) -> i32;
24228        pub fn whiteout_m3_M3ParticleEmitter_set_trailLinkIndex(
24229            self_: *mut whiteout_M3ParticleEmitter,
24230            value: i32,
24231        );
24232        pub fn whiteout_m3_M3ParticleEmitter_get_trailChance(
24233            self_: *mut whiteout_M3ParticleEmitter,
24234        ) -> f32;
24235        pub fn whiteout_m3_M3ParticleEmitter_set_trailChance(
24236            self_: *mut whiteout_M3ParticleEmitter,
24237            value: f32,
24238        );
24239        pub fn whiteout_m3_M3ParticleEmitter_get_trailEmissionRate(
24240            self_: *mut whiteout_M3ParticleEmitter,
24241        ) -> *mut whiteout_M3AnimRefF32;
24242        pub fn whiteout_m3_M3ParticleEmitter_set_trailEmissionRate(
24243            self_: *mut whiteout_M3ParticleEmitter,
24244            value: *const whiteout_M3AnimRefF32,
24245        );
24246        pub fn whiteout_m3_M3ParticleEmitter_get_splatProjectionIndex(
24247            self_: *mut whiteout_M3ParticleEmitter,
24248        ) -> i32;
24249        pub fn whiteout_m3_M3ParticleEmitter_set_splatProjectionIndex(
24250            self_: *mut whiteout_M3ParticleEmitter,
24251            value: i32,
24252        );
24253        pub fn whiteout_m3_M3ParticleEmitter_get_splatChance(
24254            self_: *mut whiteout_M3ParticleEmitter,
24255        ) -> f32;
24256        pub fn whiteout_m3_M3ParticleEmitter_set_splatChance(
24257            self_: *mut whiteout_M3ParticleEmitter,
24258            value: f32,
24259        );
24260        pub fn whiteout_m3_M3ParticleEmitter_get_copyIndices_count(
24261            self_: *mut whiteout_M3ParticleEmitter,
24262        ) -> usize;
24263        pub fn whiteout_m3_M3ParticleEmitter_resize_copyIndices(
24264            self_: *mut whiteout_M3ParticleEmitter,
24265            count: usize,
24266        );
24267        pub fn whiteout_m3_M3ParticleEmitter_get_copyIndices_data(
24268            self_: *mut whiteout_M3ParticleEmitter,
24269        ) -> *const u32;
24270        pub fn whiteout_m3_M3ParticleEmitter_assign_copyIndices(
24271            self_: *mut whiteout_M3ParticleEmitter,
24272            data: *const u32,
24273            count: usize,
24274        );
24275        pub fn whiteout_m3_M3ParticleEmitter_get_spawnRibbonOnBounceChance(
24276            self_: *mut whiteout_M3ParticleEmitter,
24277        ) -> f32;
24278        pub fn whiteout_m3_M3ParticleEmitter_set_spawnRibbonOnBounceChance(
24279            self_: *mut whiteout_M3ParticleEmitter,
24280            value: f32,
24281        );
24282        pub fn whiteout_m3_M3ParticleEmitter_get_ribbonLinkIndex(
24283            self_: *mut whiteout_M3ParticleEmitter,
24284        ) -> i32;
24285        pub fn whiteout_m3_M3ParticleEmitter_set_ribbonLinkIndex(
24286            self_: *mut whiteout_M3ParticleEmitter,
24287            value: i32,
24288        );
24289        // ParticleEmitterCopy
24290        pub fn whiteout_m3_M3ParticleEmitterCopy_new() -> *mut whiteout_M3ParticleEmitterCopy;
24291        pub fn whiteout_m3_M3ParticleEmitterCopy_delete(self_: *mut whiteout_M3ParticleEmitterCopy);
24292        pub fn whiteout_m3_M3ParticleEmitterCopy_get_emissionRate(
24293            self_: *mut whiteout_M3ParticleEmitterCopy,
24294        ) -> *mut whiteout_M3AnimRefF32;
24295        pub fn whiteout_m3_M3ParticleEmitterCopy_set_emissionRate(
24296            self_: *mut whiteout_M3ParticleEmitterCopy,
24297            value: *const whiteout_M3AnimRefF32,
24298        );
24299        pub fn whiteout_m3_M3ParticleEmitterCopy_get_squirtAmount(
24300            self_: *mut whiteout_M3ParticleEmitterCopy,
24301        ) -> *mut whiteout_M3AnimRefU16;
24302        pub fn whiteout_m3_M3ParticleEmitterCopy_set_squirtAmount(
24303            self_: *mut whiteout_M3ParticleEmitterCopy,
24304            value: *const whiteout_M3AnimRefU16,
24305        );
24306        pub fn whiteout_m3_M3ParticleEmitterCopy_get_boneIndex(
24307            self_: *mut whiteout_M3ParticleEmitterCopy,
24308        ) -> u32;
24309        pub fn whiteout_m3_M3ParticleEmitterCopy_set_boneIndex(
24310            self_: *mut whiteout_M3ParticleEmitterCopy,
24311            value: u32,
24312        );
24313        // SplineRibbon
24314        pub fn whiteout_m3_M3SplineRibbon_new() -> *mut whiteout_M3SplineRibbon;
24315        pub fn whiteout_m3_M3SplineRibbon_delete(self_: *mut whiteout_M3SplineRibbon);
24316        pub fn whiteout_m3_M3SplineRibbon_get_emissionOffset(
24317            self_: *mut whiteout_M3SplineRibbon,
24318        ) -> *mut core::ffi::c_void;
24319        pub fn whiteout_m3_M3SplineRibbon_set_emissionOffset(
24320            self_: *mut whiteout_M3SplineRibbon,
24321            value: *const core::ffi::c_void,
24322        );
24323        pub fn whiteout_m3_M3SplineRibbon_get_emissionVector(
24324            self_: *mut whiteout_M3SplineRibbon,
24325        ) -> *mut core::ffi::c_void;
24326        pub fn whiteout_m3_M3SplineRibbon_set_emissionVector(
24327            self_: *mut whiteout_M3SplineRibbon,
24328            value: *const core::ffi::c_void,
24329        );
24330        pub fn whiteout_m3_M3SplineRibbon_get_velocity(
24331            self_: *mut whiteout_M3SplineRibbon,
24332        ) -> *mut whiteout_M3AnimRefF32;
24333        pub fn whiteout_m3_M3SplineRibbon_set_velocity(
24334            self_: *mut whiteout_M3SplineRibbon,
24335            value: *const whiteout_M3AnimRefF32,
24336        );
24337        pub fn whiteout_m3_M3SplineRibbon_get_reserved(self_: *mut whiteout_M3SplineRibbon) -> u32;
24338        pub fn whiteout_m3_M3SplineRibbon_set_reserved(
24339            self_: *mut whiteout_M3SplineRibbon,
24340            value: u32,
24341        );
24342        pub fn whiteout_m3_M3SplineRibbon_get_boneIndex(self_: *mut whiteout_M3SplineRibbon)
24343            -> u32;
24344        pub fn whiteout_m3_M3SplineRibbon_set_boneIndex(
24345            self_: *mut whiteout_M3SplineRibbon,
24346            value: u32,
24347        );
24348        pub fn whiteout_m3_M3SplineRibbon_get_velocityBaseFactor(
24349            self_: *mut whiteout_M3SplineRibbon,
24350        ) -> *mut whiteout_M3AnimRefF32;
24351        pub fn whiteout_m3_M3SplineRibbon_set_velocityBaseFactor(
24352            self_: *mut whiteout_M3SplineRibbon,
24353            value: *const whiteout_M3AnimRefF32,
24354        );
24355        pub fn whiteout_m3_M3SplineRibbon_get_velocityEndFactor(
24356            self_: *mut whiteout_M3SplineRibbon,
24357        ) -> *mut whiteout_M3AnimRefF32;
24358        pub fn whiteout_m3_M3SplineRibbon_set_velocityEndFactor(
24359            self_: *mut whiteout_M3SplineRibbon,
24360            value: *const whiteout_M3AnimRefF32,
24361        );
24362        pub fn whiteout_m3_M3SplineRibbon_get_yawType(self_: *mut whiteout_M3SplineRibbon) -> u32;
24363        pub fn whiteout_m3_M3SplineRibbon_set_yawType(
24364            self_: *mut whiteout_M3SplineRibbon,
24365            value: u32,
24366        );
24367        pub fn whiteout_m3_M3SplineRibbon_get_yawAmplitude(
24368            self_: *mut whiteout_M3SplineRibbon,
24369        ) -> *mut whiteout_M3AnimRefF32;
24370        pub fn whiteout_m3_M3SplineRibbon_set_yawAmplitude(
24371            self_: *mut whiteout_M3SplineRibbon,
24372            value: *const whiteout_M3AnimRefF32,
24373        );
24374        pub fn whiteout_m3_M3SplineRibbon_get_yawFrequency(
24375            self_: *mut whiteout_M3SplineRibbon,
24376        ) -> *mut whiteout_M3AnimRefF32;
24377        pub fn whiteout_m3_M3SplineRibbon_set_yawFrequency(
24378            self_: *mut whiteout_M3SplineRibbon,
24379            value: *const whiteout_M3AnimRefF32,
24380        );
24381        pub fn whiteout_m3_M3SplineRibbon_get_pitchType(self_: *mut whiteout_M3SplineRibbon)
24382            -> u32;
24383        pub fn whiteout_m3_M3SplineRibbon_set_pitchType(
24384            self_: *mut whiteout_M3SplineRibbon,
24385            value: u32,
24386        );
24387        pub fn whiteout_m3_M3SplineRibbon_get_pitchAmplitude(
24388            self_: *mut whiteout_M3SplineRibbon,
24389        ) -> *mut whiteout_M3AnimRefF32;
24390        pub fn whiteout_m3_M3SplineRibbon_set_pitchAmplitude(
24391            self_: *mut whiteout_M3SplineRibbon,
24392            value: *const whiteout_M3AnimRefF32,
24393        );
24394        pub fn whiteout_m3_M3SplineRibbon_get_pitchFrequency(
24395            self_: *mut whiteout_M3SplineRibbon,
24396        ) -> *mut whiteout_M3AnimRefF32;
24397        pub fn whiteout_m3_M3SplineRibbon_set_pitchFrequency(
24398            self_: *mut whiteout_M3SplineRibbon,
24399            value: *const whiteout_M3AnimRefF32,
24400        );
24401        pub fn whiteout_m3_M3SplineRibbon_get_velocityType(
24402            self_: *mut whiteout_M3SplineRibbon,
24403        ) -> u32;
24404        pub fn whiteout_m3_M3SplineRibbon_set_velocityType(
24405            self_: *mut whiteout_M3SplineRibbon,
24406            value: u32,
24407        );
24408        pub fn whiteout_m3_M3SplineRibbon_get_velocityAmplitude(
24409            self_: *mut whiteout_M3SplineRibbon,
24410        ) -> *mut whiteout_M3AnimRefF32;
24411        pub fn whiteout_m3_M3SplineRibbon_set_velocityAmplitude(
24412            self_: *mut whiteout_M3SplineRibbon,
24413            value: *const whiteout_M3AnimRefF32,
24414        );
24415        pub fn whiteout_m3_M3SplineRibbon_get_velocityFrequency(
24416            self_: *mut whiteout_M3SplineRibbon,
24417        ) -> *mut whiteout_M3AnimRefF32;
24418        pub fn whiteout_m3_M3SplineRibbon_set_velocityFrequency(
24419            self_: *mut whiteout_M3SplineRibbon,
24420            value: *const whiteout_M3AnimRefF32,
24421        );
24422        pub fn whiteout_m3_M3SplineRibbon_get_yaw(
24423            self_: *mut whiteout_M3SplineRibbon,
24424        ) -> *mut whiteout_M3AnimRefF32;
24425        pub fn whiteout_m3_M3SplineRibbon_set_yaw(
24426            self_: *mut whiteout_M3SplineRibbon,
24427            value: *const whiteout_M3AnimRefF32,
24428        );
24429        pub fn whiteout_m3_M3SplineRibbon_get_pitch(
24430            self_: *mut whiteout_M3SplineRibbon,
24431        ) -> *mut whiteout_M3AnimRefF32;
24432        pub fn whiteout_m3_M3SplineRibbon_set_pitch(
24433            self_: *mut whiteout_M3SplineRibbon,
24434            value: *const whiteout_M3AnimRefF32,
24435        );
24436        pub fn whiteout_m3_M3SplineRibbon_get_emissionVectorNormFactor(
24437            self_: *mut whiteout_M3SplineRibbon,
24438        ) -> f32;
24439        pub fn whiteout_m3_M3SplineRibbon_set_emissionVectorNormFactor(
24440            self_: *mut whiteout_M3SplineRibbon,
24441            value: f32,
24442        );
24443        pub fn whiteout_m3_M3SplineRibbon_get_velocityNormFactor(
24444            self_: *mut whiteout_M3SplineRibbon,
24445        ) -> f32;
24446        pub fn whiteout_m3_M3SplineRibbon_set_velocityNormFactor(
24447            self_: *mut whiteout_M3SplineRibbon,
24448            value: f32,
24449        );
24450        // RibbonEmitter
24451        pub fn whiteout_m3_M3RibbonEmitter_new() -> *mut whiteout_M3RibbonEmitter;
24452        pub fn whiteout_m3_M3RibbonEmitter_delete(self_: *mut whiteout_M3RibbonEmitter);
24453        pub fn whiteout_m3_M3RibbonEmitter_get_boneIndex(
24454            self_: *mut whiteout_M3RibbonEmitter,
24455        ) -> u16;
24456        pub fn whiteout_m3_M3RibbonEmitter_set_boneIndex(
24457            self_: *mut whiteout_M3RibbonEmitter,
24458            value: u16,
24459        );
24460        pub fn whiteout_m3_M3RibbonEmitter_get_boneIndexFallback(
24461            self_: *mut whiteout_M3RibbonEmitter,
24462        ) -> u16;
24463        pub fn whiteout_m3_M3RibbonEmitter_set_boneIndexFallback(
24464            self_: *mut whiteout_M3RibbonEmitter,
24465            value: u16,
24466        );
24467        pub fn whiteout_m3_M3RibbonEmitter_get_materialIndex(
24468            self_: *mut whiteout_M3RibbonEmitter,
24469        ) -> u32;
24470        pub fn whiteout_m3_M3RibbonEmitter_set_materialIndex(
24471            self_: *mut whiteout_M3RibbonEmitter,
24472            value: u32,
24473        );
24474        pub fn whiteout_m3_M3RibbonEmitter_get_additionalFlags(
24475            self_: *mut whiteout_M3RibbonEmitter,
24476        ) -> i32;
24477        pub fn whiteout_m3_M3RibbonEmitter_set_additionalFlags(
24478            self_: *mut whiteout_M3RibbonEmitter,
24479            value: i32,
24480        );
24481        pub fn whiteout_m3_M3RibbonEmitter_get_initialSpeed(
24482            self_: *mut whiteout_M3RibbonEmitter,
24483        ) -> *mut whiteout_M3AnimRefF32;
24484        pub fn whiteout_m3_M3RibbonEmitter_set_initialSpeed(
24485            self_: *mut whiteout_M3RibbonEmitter,
24486            value: *const whiteout_M3AnimRefF32,
24487        );
24488        pub fn whiteout_m3_M3RibbonEmitter_get_initialSpeedRandom(
24489            self_: *mut whiteout_M3RibbonEmitter,
24490        ) -> *mut whiteout_M3AnimRefF32;
24491        pub fn whiteout_m3_M3RibbonEmitter_set_initialSpeedRandom(
24492            self_: *mut whiteout_M3RibbonEmitter,
24493            value: *const whiteout_M3AnimRefF32,
24494        );
24495        pub fn whiteout_m3_M3RibbonEmitter_get_initialYaw(
24496            self_: *mut whiteout_M3RibbonEmitter,
24497        ) -> *mut whiteout_M3AnimRefF32;
24498        pub fn whiteout_m3_M3RibbonEmitter_set_initialYaw(
24499            self_: *mut whiteout_M3RibbonEmitter,
24500            value: *const whiteout_M3AnimRefF32,
24501        );
24502        pub fn whiteout_m3_M3RibbonEmitter_get_initialPitch(
24503            self_: *mut whiteout_M3RibbonEmitter,
24504        ) -> *mut whiteout_M3AnimRefF32;
24505        pub fn whiteout_m3_M3RibbonEmitter_set_initialPitch(
24506            self_: *mut whiteout_M3RibbonEmitter,
24507            value: *const whiteout_M3AnimRefF32,
24508        );
24509        pub fn whiteout_m3_M3RibbonEmitter_get_initialHorizontal(
24510            self_: *mut whiteout_M3RibbonEmitter,
24511        ) -> *mut whiteout_M3AnimRefF32;
24512        pub fn whiteout_m3_M3RibbonEmitter_set_initialHorizontal(
24513            self_: *mut whiteout_M3RibbonEmitter,
24514            value: *const whiteout_M3AnimRefF32,
24515        );
24516        pub fn whiteout_m3_M3RibbonEmitter_get_initialVertical(
24517            self_: *mut whiteout_M3RibbonEmitter,
24518        ) -> *mut whiteout_M3AnimRefF32;
24519        pub fn whiteout_m3_M3RibbonEmitter_set_initialVertical(
24520            self_: *mut whiteout_M3RibbonEmitter,
24521            value: *const whiteout_M3AnimRefF32,
24522        );
24523        pub fn whiteout_m3_M3RibbonEmitter_get_lifetime(
24524            self_: *mut whiteout_M3RibbonEmitter,
24525        ) -> *mut whiteout_M3AnimRefF32;
24526        pub fn whiteout_m3_M3RibbonEmitter_set_lifetime(
24527            self_: *mut whiteout_M3RibbonEmitter,
24528            value: *const whiteout_M3AnimRefF32,
24529        );
24530        pub fn whiteout_m3_M3RibbonEmitter_get_lifetimeRandom(
24531            self_: *mut whiteout_M3RibbonEmitter,
24532        ) -> *mut whiteout_M3AnimRefF32;
24533        pub fn whiteout_m3_M3RibbonEmitter_set_lifetimeRandom(
24534            self_: *mut whiteout_M3RibbonEmitter,
24535            value: *const whiteout_M3AnimRefF32,
24536        );
24537        pub fn whiteout_m3_M3RibbonEmitter_get_killRadius(
24538            self_: *mut whiteout_M3RibbonEmitter,
24539        ) -> u32;
24540        pub fn whiteout_m3_M3RibbonEmitter_set_killRadius(
24541            self_: *mut whiteout_M3RibbonEmitter,
24542            value: u32,
24543        );
24544        pub fn whiteout_m3_M3RibbonEmitter_get_gravityX(
24545            self_: *mut whiteout_M3RibbonEmitter,
24546        ) -> f32;
24547        pub fn whiteout_m3_M3RibbonEmitter_set_gravityX(
24548            self_: *mut whiteout_M3RibbonEmitter,
24549            value: f32,
24550        );
24551        pub fn whiteout_m3_M3RibbonEmitter_get_gravityY(
24552            self_: *mut whiteout_M3RibbonEmitter,
24553        ) -> f32;
24554        pub fn whiteout_m3_M3RibbonEmitter_set_gravityY(
24555            self_: *mut whiteout_M3RibbonEmitter,
24556            value: f32,
24557        );
24558        pub fn whiteout_m3_M3RibbonEmitter_get_gravity(self_: *mut whiteout_M3RibbonEmitter)
24559            -> f32;
24560        pub fn whiteout_m3_M3RibbonEmitter_set_gravity(
24561            self_: *mut whiteout_M3RibbonEmitter,
24562            value: f32,
24563        );
24564        pub fn whiteout_m3_M3RibbonEmitter_get_sizeMidTime(
24565            self_: *mut whiteout_M3RibbonEmitter,
24566        ) -> f32;
24567        pub fn whiteout_m3_M3RibbonEmitter_set_sizeMidTime(
24568            self_: *mut whiteout_M3RibbonEmitter,
24569            value: f32,
24570        );
24571        pub fn whiteout_m3_M3RibbonEmitter_get_colorMidTime(
24572            self_: *mut whiteout_M3RibbonEmitter,
24573        ) -> f32;
24574        pub fn whiteout_m3_M3RibbonEmitter_set_colorMidTime(
24575            self_: *mut whiteout_M3RibbonEmitter,
24576            value: f32,
24577        );
24578        pub fn whiteout_m3_M3RibbonEmitter_get_alphaMidTime(
24579            self_: *mut whiteout_M3RibbonEmitter,
24580        ) -> f32;
24581        pub fn whiteout_m3_M3RibbonEmitter_set_alphaMidTime(
24582            self_: *mut whiteout_M3RibbonEmitter,
24583            value: f32,
24584        );
24585        pub fn whiteout_m3_M3RibbonEmitter_get_rotationMidTime(
24586            self_: *mut whiteout_M3RibbonEmitter,
24587        ) -> f32;
24588        pub fn whiteout_m3_M3RibbonEmitter_set_rotationMidTime(
24589            self_: *mut whiteout_M3RibbonEmitter,
24590            value: f32,
24591        );
24592        pub fn whiteout_m3_M3RibbonEmitter_get_sizeMidHoldTime(
24593            self_: *mut whiteout_M3RibbonEmitter,
24594        ) -> f32;
24595        pub fn whiteout_m3_M3RibbonEmitter_set_sizeMidHoldTime(
24596            self_: *mut whiteout_M3RibbonEmitter,
24597            value: f32,
24598        );
24599        pub fn whiteout_m3_M3RibbonEmitter_get_colorMidHoldTime(
24600            self_: *mut whiteout_M3RibbonEmitter,
24601        ) -> f32;
24602        pub fn whiteout_m3_M3RibbonEmitter_set_colorMidHoldTime(
24603            self_: *mut whiteout_M3RibbonEmitter,
24604            value: f32,
24605        );
24606        pub fn whiteout_m3_M3RibbonEmitter_get_alphaMidHoldTime(
24607            self_: *mut whiteout_M3RibbonEmitter,
24608        ) -> f32;
24609        pub fn whiteout_m3_M3RibbonEmitter_set_alphaMidHoldTime(
24610            self_: *mut whiteout_M3RibbonEmitter,
24611            value: f32,
24612        );
24613        pub fn whiteout_m3_M3RibbonEmitter_get_rotationMidHoldTime(
24614            self_: *mut whiteout_M3RibbonEmitter,
24615        ) -> f32;
24616        pub fn whiteout_m3_M3RibbonEmitter_set_rotationMidHoldTime(
24617            self_: *mut whiteout_M3RibbonEmitter,
24618            value: f32,
24619        );
24620        pub fn whiteout_m3_M3RibbonEmitter_get_sizeAnimation(
24621            self_: *mut whiteout_M3RibbonEmitter,
24622        ) -> *mut whiteout_M3AnimRefVector3f;
24623        pub fn whiteout_m3_M3RibbonEmitter_set_sizeAnimation(
24624            self_: *mut whiteout_M3RibbonEmitter,
24625            value: *const whiteout_M3AnimRefVector3f,
24626        );
24627        pub fn whiteout_m3_M3RibbonEmitter_get_rotationAnimation(
24628            self_: *mut whiteout_M3RibbonEmitter,
24629        ) -> *mut whiteout_M3AnimRefVector3f;
24630        pub fn whiteout_m3_M3RibbonEmitter_set_rotationAnimation(
24631            self_: *mut whiteout_M3RibbonEmitter,
24632            value: *const whiteout_M3AnimRefVector3f,
24633        );
24634        pub fn whiteout_m3_M3RibbonEmitter_get_colorStart(
24635            self_: *mut whiteout_M3RibbonEmitter,
24636        ) -> *mut whiteout_M3AnimRefM3ColorBGRA;
24637        pub fn whiteout_m3_M3RibbonEmitter_set_colorStart(
24638            self_: *mut whiteout_M3RibbonEmitter,
24639            value: *const whiteout_M3AnimRefM3ColorBGRA,
24640        );
24641        pub fn whiteout_m3_M3RibbonEmitter_get_colorMid(
24642            self_: *mut whiteout_M3RibbonEmitter,
24643        ) -> *mut whiteout_M3AnimRefM3ColorBGRA;
24644        pub fn whiteout_m3_M3RibbonEmitter_set_colorMid(
24645            self_: *mut whiteout_M3RibbonEmitter,
24646            value: *const whiteout_M3AnimRefM3ColorBGRA,
24647        );
24648        pub fn whiteout_m3_M3RibbonEmitter_get_colorEnd(
24649            self_: *mut whiteout_M3RibbonEmitter,
24650        ) -> *mut whiteout_M3AnimRefM3ColorBGRA;
24651        pub fn whiteout_m3_M3RibbonEmitter_set_colorEnd(
24652            self_: *mut whiteout_M3RibbonEmitter,
24653            value: *const whiteout_M3AnimRefM3ColorBGRA,
24654        );
24655        pub fn whiteout_m3_M3RibbonEmitter_get_drag(self_: *mut whiteout_M3RibbonEmitter) -> f32;
24656        pub fn whiteout_m3_M3RibbonEmitter_set_drag(
24657            self_: *mut whiteout_M3RibbonEmitter,
24658            value: f32,
24659        );
24660        pub fn whiteout_m3_M3RibbonEmitter_get_mass(self_: *mut whiteout_M3RibbonEmitter) -> f32;
24661        pub fn whiteout_m3_M3RibbonEmitter_set_mass(
24662            self_: *mut whiteout_M3RibbonEmitter,
24663            value: f32,
24664        );
24665        pub fn whiteout_m3_M3RibbonEmitter_get_massRandom(
24666            self_: *mut whiteout_M3RibbonEmitter,
24667        ) -> f32;
24668        pub fn whiteout_m3_M3RibbonEmitter_set_massRandom(
24669            self_: *mut whiteout_M3RibbonEmitter,
24670            value: f32,
24671        );
24672        pub fn whiteout_m3_M3RibbonEmitter_get_massSizeMultiplier(
24673            self_: *mut whiteout_M3RibbonEmitter,
24674        ) -> f32;
24675        pub fn whiteout_m3_M3RibbonEmitter_set_massSizeMultiplier(
24676            self_: *mut whiteout_M3RibbonEmitter,
24677            value: f32,
24678        );
24679        pub fn whiteout_m3_M3RibbonEmitter_get_localForces(
24680            self_: *mut whiteout_M3RibbonEmitter,
24681        ) -> u16;
24682        pub fn whiteout_m3_M3RibbonEmitter_set_localForces(
24683            self_: *mut whiteout_M3RibbonEmitter,
24684            value: u16,
24685        );
24686        pub fn whiteout_m3_M3RibbonEmitter_get_worldForces(
24687            self_: *mut whiteout_M3RibbonEmitter,
24688        ) -> u16;
24689        pub fn whiteout_m3_M3RibbonEmitter_set_worldForces(
24690            self_: *mut whiteout_M3RibbonEmitter,
24691            value: u16,
24692        );
24693        pub fn whiteout_m3_M3RibbonEmitter_get_localForcesFallback(
24694            self_: *mut whiteout_M3RibbonEmitter,
24695        ) -> u16;
24696        pub fn whiteout_m3_M3RibbonEmitter_set_localForcesFallback(
24697            self_: *mut whiteout_M3RibbonEmitter,
24698            value: u16,
24699        );
24700        pub fn whiteout_m3_M3RibbonEmitter_get_worldForcesFallback(
24701            self_: *mut whiteout_M3RibbonEmitter,
24702        ) -> u16;
24703        pub fn whiteout_m3_M3RibbonEmitter_set_worldForcesFallback(
24704            self_: *mut whiteout_M3RibbonEmitter,
24705            value: u16,
24706        );
24707        pub fn whiteout_m3_M3RibbonEmitter_get_worldForcesMassMultiplier(
24708            self_: *mut whiteout_M3RibbonEmitter,
24709        ) -> f32;
24710        pub fn whiteout_m3_M3RibbonEmitter_set_worldForcesMassMultiplier(
24711            self_: *mut whiteout_M3RibbonEmitter,
24712            value: f32,
24713        );
24714        pub fn whiteout_m3_M3RibbonEmitter_get_noiseAmplitude(
24715            self_: *mut whiteout_M3RibbonEmitter,
24716        ) -> f32;
24717        pub fn whiteout_m3_M3RibbonEmitter_set_noiseAmplitude(
24718            self_: *mut whiteout_M3RibbonEmitter,
24719            value: f32,
24720        );
24721        pub fn whiteout_m3_M3RibbonEmitter_get_noiseFrequency(
24722            self_: *mut whiteout_M3RibbonEmitter,
24723        ) -> f32;
24724        pub fn whiteout_m3_M3RibbonEmitter_set_noiseFrequency(
24725            self_: *mut whiteout_M3RibbonEmitter,
24726            value: f32,
24727        );
24728        pub fn whiteout_m3_M3RibbonEmitter_get_noiseCoherence(
24729            self_: *mut whiteout_M3RibbonEmitter,
24730        ) -> f32;
24731        pub fn whiteout_m3_M3RibbonEmitter_set_noiseCoherence(
24732            self_: *mut whiteout_M3RibbonEmitter,
24733            value: f32,
24734        );
24735        pub fn whiteout_m3_M3RibbonEmitter_get_noiseEdge(
24736            self_: *mut whiteout_M3RibbonEmitter,
24737        ) -> f32;
24738        pub fn whiteout_m3_M3RibbonEmitter_set_noiseEdge(
24739            self_: *mut whiteout_M3RibbonEmitter,
24740            value: f32,
24741        );
24742        pub fn whiteout_m3_M3RibbonEmitter_get_indexPlusLength(
24743            self_: *mut whiteout_M3RibbonEmitter,
24744        ) -> u32;
24745        pub fn whiteout_m3_M3RibbonEmitter_set_indexPlusLength(
24746            self_: *mut whiteout_M3RibbonEmitter,
24747            value: u32,
24748        );
24749        pub fn whiteout_m3_M3RibbonEmitter_get_emitterShape(
24750            self_: *mut whiteout_M3RibbonEmitter,
24751        ) -> u32;
24752        pub fn whiteout_m3_M3RibbonEmitter_set_emitterShape(
24753            self_: *mut whiteout_M3RibbonEmitter,
24754            value: u32,
24755        );
24756        pub fn whiteout_m3_M3RibbonEmitter_get_ribbonType(
24757            self_: *mut whiteout_M3RibbonEmitter,
24758        ) -> i32;
24759        pub fn whiteout_m3_M3RibbonEmitter_set_ribbonType(
24760            self_: *mut whiteout_M3RibbonEmitter,
24761            value: i32,
24762        );
24763        pub fn whiteout_m3_M3RibbonEmitter_get_divisions(
24764            self_: *mut whiteout_M3RibbonEmitter,
24765        ) -> f32;
24766        pub fn whiteout_m3_M3RibbonEmitter_set_divisions(
24767            self_: *mut whiteout_M3RibbonEmitter,
24768            value: f32,
24769        );
24770        pub fn whiteout_m3_M3RibbonEmitter_get_edges(self_: *mut whiteout_M3RibbonEmitter) -> u32;
24771        pub fn whiteout_m3_M3RibbonEmitter_set_edges(
24772            self_: *mut whiteout_M3RibbonEmitter,
24773            value: u32,
24774        );
24775        pub fn whiteout_m3_M3RibbonEmitter_get_innerRadius(
24776            self_: *mut whiteout_M3RibbonEmitter,
24777        ) -> f32;
24778        pub fn whiteout_m3_M3RibbonEmitter_set_innerRadius(
24779            self_: *mut whiteout_M3RibbonEmitter,
24780            value: f32,
24781        );
24782        pub fn whiteout_m3_M3RibbonEmitter_get_maxLength(
24783            self_: *mut whiteout_M3RibbonEmitter,
24784        ) -> *mut whiteout_M3AnimRefF32;
24785        pub fn whiteout_m3_M3RibbonEmitter_set_maxLength(
24786            self_: *mut whiteout_M3RibbonEmitter,
24787            value: *const whiteout_M3AnimRefF32,
24788        );
24789        pub fn whiteout_m3_M3RibbonEmitter_get_splineRibbons_count(
24790            self_: *mut whiteout_M3RibbonEmitter,
24791        ) -> usize;
24792        pub fn whiteout_m3_M3RibbonEmitter_resize_splineRibbons(
24793            self_: *mut whiteout_M3RibbonEmitter,
24794            count: usize,
24795        );
24796        pub fn whiteout_m3_M3RibbonEmitter_get_splineRibbons_at(
24797            self_: *mut whiteout_M3RibbonEmitter,
24798            index: usize,
24799        ) -> *mut whiteout_M3SplineRibbon;
24800        pub fn whiteout_m3_M3RibbonEmitter_get_active(
24801            self_: *mut whiteout_M3RibbonEmitter,
24802        ) -> *mut whiteout_M3AnimRefU32;
24803        pub fn whiteout_m3_M3RibbonEmitter_set_active(
24804            self_: *mut whiteout_M3RibbonEmitter,
24805            value: *const whiteout_M3AnimRefU32,
24806        );
24807        pub fn whiteout_m3_M3RibbonEmitter_get_flags(self_: *mut whiteout_M3RibbonEmitter) -> i32;
24808        pub fn whiteout_m3_M3RibbonEmitter_set_flags(
24809            self_: *mut whiteout_M3RibbonEmitter,
24810            value: i32,
24811        );
24812        pub fn whiteout_m3_M3RibbonEmitter_get_sizeSmoothing(
24813            self_: *mut whiteout_M3RibbonEmitter,
24814        ) -> i32;
24815        pub fn whiteout_m3_M3RibbonEmitter_set_sizeSmoothing(
24816            self_: *mut whiteout_M3RibbonEmitter,
24817            value: i32,
24818        );
24819        pub fn whiteout_m3_M3RibbonEmitter_get_colorSmoothing(
24820            self_: *mut whiteout_M3RibbonEmitter,
24821        ) -> i32;
24822        pub fn whiteout_m3_M3RibbonEmitter_set_colorSmoothing(
24823            self_: *mut whiteout_M3RibbonEmitter,
24824            value: i32,
24825        );
24826        pub fn whiteout_m3_M3RibbonEmitter_get_friction(
24827            self_: *mut whiteout_M3RibbonEmitter,
24828        ) -> f32;
24829        pub fn whiteout_m3_M3RibbonEmitter_set_friction(
24830            self_: *mut whiteout_M3RibbonEmitter,
24831            value: f32,
24832        );
24833        pub fn whiteout_m3_M3RibbonEmitter_get_bounce(self_: *mut whiteout_M3RibbonEmitter) -> f32;
24834        pub fn whiteout_m3_M3RibbonEmitter_set_bounce(
24835            self_: *mut whiteout_M3RibbonEmitter,
24836            value: f32,
24837        );
24838        pub fn whiteout_m3_M3RibbonEmitter_get_lodReduce(
24839            self_: *mut whiteout_M3RibbonEmitter,
24840        ) -> u32;
24841        pub fn whiteout_m3_M3RibbonEmitter_set_lodReduce(
24842            self_: *mut whiteout_M3RibbonEmitter,
24843            value: u32,
24844        );
24845        pub fn whiteout_m3_M3RibbonEmitter_get_lodCut(self_: *mut whiteout_M3RibbonEmitter) -> u32;
24846        pub fn whiteout_m3_M3RibbonEmitter_set_lodCut(
24847            self_: *mut whiteout_M3RibbonEmitter,
24848            value: u32,
24849        );
24850        pub fn whiteout_m3_M3RibbonEmitter_get_yawType(self_: *mut whiteout_M3RibbonEmitter)
24851            -> u32;
24852        pub fn whiteout_m3_M3RibbonEmitter_set_yawType(
24853            self_: *mut whiteout_M3RibbonEmitter,
24854            value: u32,
24855        );
24856        pub fn whiteout_m3_M3RibbonEmitter_get_yawAmplitude(
24857            self_: *mut whiteout_M3RibbonEmitter,
24858        ) -> *mut whiteout_M3AnimRefF32;
24859        pub fn whiteout_m3_M3RibbonEmitter_set_yawAmplitude(
24860            self_: *mut whiteout_M3RibbonEmitter,
24861            value: *const whiteout_M3AnimRefF32,
24862        );
24863        pub fn whiteout_m3_M3RibbonEmitter_get_yawFrequency(
24864            self_: *mut whiteout_M3RibbonEmitter,
24865        ) -> *mut whiteout_M3AnimRefF32;
24866        pub fn whiteout_m3_M3RibbonEmitter_set_yawFrequency(
24867            self_: *mut whiteout_M3RibbonEmitter,
24868            value: *const whiteout_M3AnimRefF32,
24869        );
24870        pub fn whiteout_m3_M3RibbonEmitter_get_pitchType(
24871            self_: *mut whiteout_M3RibbonEmitter,
24872        ) -> u32;
24873        pub fn whiteout_m3_M3RibbonEmitter_set_pitchType(
24874            self_: *mut whiteout_M3RibbonEmitter,
24875            value: u32,
24876        );
24877        pub fn whiteout_m3_M3RibbonEmitter_get_pitchAmplitude(
24878            self_: *mut whiteout_M3RibbonEmitter,
24879        ) -> *mut whiteout_M3AnimRefF32;
24880        pub fn whiteout_m3_M3RibbonEmitter_set_pitchAmplitude(
24881            self_: *mut whiteout_M3RibbonEmitter,
24882            value: *const whiteout_M3AnimRefF32,
24883        );
24884        pub fn whiteout_m3_M3RibbonEmitter_get_pitchFrequency(
24885            self_: *mut whiteout_M3RibbonEmitter,
24886        ) -> *mut whiteout_M3AnimRefF32;
24887        pub fn whiteout_m3_M3RibbonEmitter_set_pitchFrequency(
24888            self_: *mut whiteout_M3RibbonEmitter,
24889            value: *const whiteout_M3AnimRefF32,
24890        );
24891        pub fn whiteout_m3_M3RibbonEmitter_get_speedType(
24892            self_: *mut whiteout_M3RibbonEmitter,
24893        ) -> u32;
24894        pub fn whiteout_m3_M3RibbonEmitter_set_speedType(
24895            self_: *mut whiteout_M3RibbonEmitter,
24896            value: u32,
24897        );
24898        pub fn whiteout_m3_M3RibbonEmitter_get_speedAmplitude(
24899            self_: *mut whiteout_M3RibbonEmitter,
24900        ) -> *mut whiteout_M3AnimRefF32;
24901        pub fn whiteout_m3_M3RibbonEmitter_set_speedAmplitude(
24902            self_: *mut whiteout_M3RibbonEmitter,
24903            value: *const whiteout_M3AnimRefF32,
24904        );
24905        pub fn whiteout_m3_M3RibbonEmitter_get_speedFrequency(
24906            self_: *mut whiteout_M3RibbonEmitter,
24907        ) -> *mut whiteout_M3AnimRefF32;
24908        pub fn whiteout_m3_M3RibbonEmitter_set_speedFrequency(
24909            self_: *mut whiteout_M3RibbonEmitter,
24910            value: *const whiteout_M3AnimRefF32,
24911        );
24912        pub fn whiteout_m3_M3RibbonEmitter_get_sizeType(
24913            self_: *mut whiteout_M3RibbonEmitter,
24914        ) -> u32;
24915        pub fn whiteout_m3_M3RibbonEmitter_set_sizeType(
24916            self_: *mut whiteout_M3RibbonEmitter,
24917            value: u32,
24918        );
24919        pub fn whiteout_m3_M3RibbonEmitter_get_sizeAmplitude(
24920            self_: *mut whiteout_M3RibbonEmitter,
24921        ) -> *mut whiteout_M3AnimRefF32;
24922        pub fn whiteout_m3_M3RibbonEmitter_set_sizeAmplitude(
24923            self_: *mut whiteout_M3RibbonEmitter,
24924            value: *const whiteout_M3AnimRefF32,
24925        );
24926        pub fn whiteout_m3_M3RibbonEmitter_get_sizeFrequency(
24927            self_: *mut whiteout_M3RibbonEmitter,
24928        ) -> *mut whiteout_M3AnimRefF32;
24929        pub fn whiteout_m3_M3RibbonEmitter_set_sizeFrequency(
24930            self_: *mut whiteout_M3RibbonEmitter,
24931            value: *const whiteout_M3AnimRefF32,
24932        );
24933        pub fn whiteout_m3_M3RibbonEmitter_get_alphaType(
24934            self_: *mut whiteout_M3RibbonEmitter,
24935        ) -> u32;
24936        pub fn whiteout_m3_M3RibbonEmitter_set_alphaType(
24937            self_: *mut whiteout_M3RibbonEmitter,
24938            value: u32,
24939        );
24940        pub fn whiteout_m3_M3RibbonEmitter_get_alphaAmplitude(
24941            self_: *mut whiteout_M3RibbonEmitter,
24942        ) -> *mut whiteout_M3AnimRefF32;
24943        pub fn whiteout_m3_M3RibbonEmitter_set_alphaAmplitude(
24944            self_: *mut whiteout_M3RibbonEmitter,
24945            value: *const whiteout_M3AnimRefF32,
24946        );
24947        pub fn whiteout_m3_M3RibbonEmitter_get_alphaFrequency(
24948            self_: *mut whiteout_M3RibbonEmitter,
24949        ) -> *mut whiteout_M3AnimRefF32;
24950        pub fn whiteout_m3_M3RibbonEmitter_set_alphaFrequency(
24951            self_: *mut whiteout_M3RibbonEmitter,
24952            value: *const whiteout_M3AnimRefF32,
24953        );
24954        pub fn whiteout_m3_M3RibbonEmitter_get_particleVelocity(
24955            self_: *mut whiteout_M3RibbonEmitter,
24956        ) -> *mut whiteout_M3AnimRefF32;
24957        pub fn whiteout_m3_M3RibbonEmitter_set_particleVelocity(
24958            self_: *mut whiteout_M3RibbonEmitter,
24959            value: *const whiteout_M3AnimRefF32,
24960        );
24961        pub fn whiteout_m3_M3RibbonEmitter_get_overlay(
24962            self_: *mut whiteout_M3RibbonEmitter,
24963        ) -> *mut whiteout_M3AnimRefF32;
24964        pub fn whiteout_m3_M3RibbonEmitter_set_overlay(
24965            self_: *mut whiteout_M3RibbonEmitter,
24966            value: *const whiteout_M3AnimRefF32,
24967        );
24968        // Projector
24969        pub fn whiteout_m3_M3Projector_new() -> *mut whiteout_M3Projector;
24970        pub fn whiteout_m3_M3Projector_delete(self_: *mut whiteout_M3Projector);
24971        pub fn whiteout_m3_M3Projector_get_projectionType(self_: *mut whiteout_M3Projector) -> i32;
24972        pub fn whiteout_m3_M3Projector_set_projectionType(
24973            self_: *mut whiteout_M3Projector,
24974            value: i32,
24975        );
24976        pub fn whiteout_m3_M3Projector_get_bone(self_: *mut whiteout_M3Projector) -> u32;
24977        pub fn whiteout_m3_M3Projector_set_bone(self_: *mut whiteout_M3Projector, value: u32);
24978        pub fn whiteout_m3_M3Projector_get_materialReferenceIndex(
24979            self_: *mut whiteout_M3Projector,
24980        ) -> u32;
24981        pub fn whiteout_m3_M3Projector_set_materialReferenceIndex(
24982            self_: *mut whiteout_M3Projector,
24983            value: u32,
24984        );
24985        pub fn whiteout_m3_M3Projector_get_offset(
24986            self_: *mut whiteout_M3Projector,
24987        ) -> *mut whiteout_M3AnimRefVector3f;
24988        pub fn whiteout_m3_M3Projector_set_offset(
24989            self_: *mut whiteout_M3Projector,
24990            value: *const whiteout_M3AnimRefVector3f,
24991        );
24992        pub fn whiteout_m3_M3Projector_get_pitch(
24993            self_: *mut whiteout_M3Projector,
24994        ) -> *mut whiteout_M3AnimRefF32;
24995        pub fn whiteout_m3_M3Projector_set_pitch(
24996            self_: *mut whiteout_M3Projector,
24997            value: *const whiteout_M3AnimRefF32,
24998        );
24999        pub fn whiteout_m3_M3Projector_get_yaw(
25000            self_: *mut whiteout_M3Projector,
25001        ) -> *mut whiteout_M3AnimRefF32;
25002        pub fn whiteout_m3_M3Projector_set_yaw(
25003            self_: *mut whiteout_M3Projector,
25004            value: *const whiteout_M3AnimRefF32,
25005        );
25006        pub fn whiteout_m3_M3Projector_get_roll(
25007            self_: *mut whiteout_M3Projector,
25008        ) -> *mut whiteout_M3AnimRefF32;
25009        pub fn whiteout_m3_M3Projector_set_roll(
25010            self_: *mut whiteout_M3Projector,
25011            value: *const whiteout_M3AnimRefF32,
25012        );
25013        pub fn whiteout_m3_M3Projector_get_fieldOfView(
25014            self_: *mut whiteout_M3Projector,
25015        ) -> *mut whiteout_M3AnimRefF32;
25016        pub fn whiteout_m3_M3Projector_set_fieldOfView(
25017            self_: *mut whiteout_M3Projector,
25018            value: *const whiteout_M3AnimRefF32,
25019        );
25020        pub fn whiteout_m3_M3Projector_get_aspectRatio(
25021            self_: *mut whiteout_M3Projector,
25022        ) -> *mut whiteout_M3AnimRefF32;
25023        pub fn whiteout_m3_M3Projector_set_aspectRatio(
25024            self_: *mut whiteout_M3Projector,
25025            value: *const whiteout_M3AnimRefF32,
25026        );
25027        pub fn whiteout_m3_M3Projector_get_near(
25028            self_: *mut whiteout_M3Projector,
25029        ) -> *mut whiteout_M3AnimRefF32;
25030        pub fn whiteout_m3_M3Projector_set_near(
25031            self_: *mut whiteout_M3Projector,
25032            value: *const whiteout_M3AnimRefF32,
25033        );
25034        pub fn whiteout_m3_M3Projector_get_far(
25035            self_: *mut whiteout_M3Projector,
25036        ) -> *mut whiteout_M3AnimRefF32;
25037        pub fn whiteout_m3_M3Projector_set_far(
25038            self_: *mut whiteout_M3Projector,
25039            value: *const whiteout_M3AnimRefF32,
25040        );
25041        pub fn whiteout_m3_M3Projector_get_boxOffsetZBottom(
25042            self_: *mut whiteout_M3Projector,
25043        ) -> *mut whiteout_M3AnimRefF32;
25044        pub fn whiteout_m3_M3Projector_set_boxOffsetZBottom(
25045            self_: *mut whiteout_M3Projector,
25046            value: *const whiteout_M3AnimRefF32,
25047        );
25048        pub fn whiteout_m3_M3Projector_get_boxOffsetZTop(
25049            self_: *mut whiteout_M3Projector,
25050        ) -> *mut whiteout_M3AnimRefF32;
25051        pub fn whiteout_m3_M3Projector_set_boxOffsetZTop(
25052            self_: *mut whiteout_M3Projector,
25053            value: *const whiteout_M3AnimRefF32,
25054        );
25055        pub fn whiteout_m3_M3Projector_get_boxOffsetXLeft(
25056            self_: *mut whiteout_M3Projector,
25057        ) -> *mut whiteout_M3AnimRefF32;
25058        pub fn whiteout_m3_M3Projector_set_boxOffsetXLeft(
25059            self_: *mut whiteout_M3Projector,
25060            value: *const whiteout_M3AnimRefF32,
25061        );
25062        pub fn whiteout_m3_M3Projector_get_boxOffsetXRight(
25063            self_: *mut whiteout_M3Projector,
25064        ) -> *mut whiteout_M3AnimRefF32;
25065        pub fn whiteout_m3_M3Projector_set_boxOffsetXRight(
25066            self_: *mut whiteout_M3Projector,
25067            value: *const whiteout_M3AnimRefF32,
25068        );
25069        pub fn whiteout_m3_M3Projector_get_boxOffsetYFront(
25070            self_: *mut whiteout_M3Projector,
25071        ) -> *mut whiteout_M3AnimRefF32;
25072        pub fn whiteout_m3_M3Projector_set_boxOffsetYFront(
25073            self_: *mut whiteout_M3Projector,
25074            value: *const whiteout_M3AnimRefF32,
25075        );
25076        pub fn whiteout_m3_M3Projector_get_boxOffsetYBack(
25077            self_: *mut whiteout_M3Projector,
25078        ) -> *mut whiteout_M3AnimRefF32;
25079        pub fn whiteout_m3_M3Projector_set_boxOffsetYBack(
25080            self_: *mut whiteout_M3Projector,
25081            value: *const whiteout_M3AnimRefF32,
25082        );
25083        pub fn whiteout_m3_M3Projector_get_falloff(self_: *mut whiteout_M3Projector) -> f32;
25084        pub fn whiteout_m3_M3Projector_set_falloff(self_: *mut whiteout_M3Projector, value: f32);
25085        pub fn whiteout_m3_M3Projector_get_alphaInit(self_: *mut whiteout_M3Projector) -> f32;
25086        pub fn whiteout_m3_M3Projector_set_alphaInit(self_: *mut whiteout_M3Projector, value: f32);
25087        pub fn whiteout_m3_M3Projector_get_alphaMid(self_: *mut whiteout_M3Projector) -> f32;
25088        pub fn whiteout_m3_M3Projector_set_alphaMid(self_: *mut whiteout_M3Projector, value: f32);
25089        pub fn whiteout_m3_M3Projector_get_alphaEnd(self_: *mut whiteout_M3Projector) -> f32;
25090        pub fn whiteout_m3_M3Projector_set_alphaEnd(self_: *mut whiteout_M3Projector, value: f32);
25091        pub fn whiteout_m3_M3Projector_get_lifetimeAttack(self_: *mut whiteout_M3Projector) -> f32;
25092        pub fn whiteout_m3_M3Projector_set_lifetimeAttack(
25093            self_: *mut whiteout_M3Projector,
25094            value: f32,
25095        );
25096        pub fn whiteout_m3_M3Projector_get_lifetimeAttackTo(
25097            self_: *mut whiteout_M3Projector,
25098        ) -> f32;
25099        pub fn whiteout_m3_M3Projector_set_lifetimeAttackTo(
25100            self_: *mut whiteout_M3Projector,
25101            value: f32,
25102        );
25103        pub fn whiteout_m3_M3Projector_get_lifetimeHold(self_: *mut whiteout_M3Projector) -> f32;
25104        pub fn whiteout_m3_M3Projector_set_lifetimeHold(
25105            self_: *mut whiteout_M3Projector,
25106            value: f32,
25107        );
25108        pub fn whiteout_m3_M3Projector_get_lifetimeHoldTo(self_: *mut whiteout_M3Projector) -> f32;
25109        pub fn whiteout_m3_M3Projector_set_lifetimeHoldTo(
25110            self_: *mut whiteout_M3Projector,
25111            value: f32,
25112        );
25113        pub fn whiteout_m3_M3Projector_get_lifetimeDecay(self_: *mut whiteout_M3Projector) -> f32;
25114        pub fn whiteout_m3_M3Projector_set_lifetimeDecay(
25115            self_: *mut whiteout_M3Projector,
25116            value: f32,
25117        );
25118        pub fn whiteout_m3_M3Projector_get_lifetimeDecayTo(self_: *mut whiteout_M3Projector)
25119            -> f32;
25120        pub fn whiteout_m3_M3Projector_set_lifetimeDecayTo(
25121            self_: *mut whiteout_M3Projector,
25122            value: f32,
25123        );
25124        pub fn whiteout_m3_M3Projector_get_attenuationDistance(
25125            self_: *mut whiteout_M3Projector,
25126        ) -> f32;
25127        pub fn whiteout_m3_M3Projector_set_attenuationDistance(
25128            self_: *mut whiteout_M3Projector,
25129            value: f32,
25130        );
25131        pub fn whiteout_m3_M3Projector_get_active(
25132            self_: *mut whiteout_M3Projector,
25133        ) -> *mut whiteout_M3AnimRefU32;
25134        pub fn whiteout_m3_M3Projector_set_active(
25135            self_: *mut whiteout_M3Projector,
25136            value: *const whiteout_M3AnimRefU32,
25137        );
25138        pub fn whiteout_m3_M3Projector_get_layer(self_: *mut whiteout_M3Projector) -> u32;
25139        pub fn whiteout_m3_M3Projector_set_layer(self_: *mut whiteout_M3Projector, value: u32);
25140        pub fn whiteout_m3_M3Projector_get_lodReduce(self_: *mut whiteout_M3Projector) -> u32;
25141        pub fn whiteout_m3_M3Projector_set_lodReduce(self_: *mut whiteout_M3Projector, value: u32);
25142        pub fn whiteout_m3_M3Projector_get_lodCut(self_: *mut whiteout_M3Projector) -> u32;
25143        pub fn whiteout_m3_M3Projector_set_lodCut(self_: *mut whiteout_M3Projector, value: u32);
25144        pub fn whiteout_m3_M3Projector_get_flags(self_: *mut whiteout_M3Projector) -> i32;
25145        pub fn whiteout_m3_M3Projector_set_flags(self_: *mut whiteout_M3Projector, value: i32);
25146        // MaterialMap
25147        pub fn whiteout_m3_M3MaterialMap_new() -> *mut whiteout_M3MaterialMap;
25148        pub fn whiteout_m3_M3MaterialMap_delete(self_: *mut whiteout_M3MaterialMap);
25149        pub fn whiteout_m3_M3MaterialMap_get_materialType(
25150            self_: *mut whiteout_M3MaterialMap,
25151        ) -> i32;
25152        pub fn whiteout_m3_M3MaterialMap_set_materialType(
25153            self_: *mut whiteout_M3MaterialMap,
25154            value: i32,
25155        );
25156        pub fn whiteout_m3_M3MaterialMap_get_materialIndex(
25157            self_: *mut whiteout_M3MaterialMap,
25158        ) -> u32;
25159        pub fn whiteout_m3_M3MaterialMap_set_materialIndex(
25160            self_: *mut whiteout_M3MaterialMap,
25161            value: u32,
25162        );
25163        // TextureLayer
25164        pub fn whiteout_m3_M3TextureLayer_new() -> *mut whiteout_M3TextureLayer;
25165        pub fn whiteout_m3_M3TextureLayer_delete(self_: *mut whiteout_M3TextureLayer);
25166        pub fn whiteout_m3_M3TextureLayer_get_id(self_: *mut whiteout_M3TextureLayer) -> u32;
25167        pub fn whiteout_m3_M3TextureLayer_set_id(self_: *mut whiteout_M3TextureLayer, value: u32);
25168        pub fn whiteout_m3_M3TextureLayer_get_texturePath(
25169            self_: *mut whiteout_M3TextureLayer,
25170        ) -> RawCString;
25171        pub fn whiteout_m3_M3TextureLayer_set_texturePath(
25172            self_: *mut whiteout_M3TextureLayer,
25173            value: *const core::ffi::c_char,
25174        );
25175        pub fn whiteout_m3_M3TextureLayer_get_color(
25176            self_: *mut whiteout_M3TextureLayer,
25177        ) -> *mut whiteout_M3AnimRefM3ColorBGRA;
25178        pub fn whiteout_m3_M3TextureLayer_set_color(
25179            self_: *mut whiteout_M3TextureLayer,
25180            value: *const whiteout_M3AnimRefM3ColorBGRA,
25181        );
25182        pub fn whiteout_m3_M3TextureLayer_get_flags(self_: *mut whiteout_M3TextureLayer) -> i32;
25183        pub fn whiteout_m3_M3TextureLayer_set_flags(
25184            self_: *mut whiteout_M3TextureLayer,
25185            value: i32,
25186        );
25187        pub fn whiteout_m3_M3TextureLayer_get_uvMapping(self_: *mut whiteout_M3TextureLayer)
25188            -> i32;
25189        pub fn whiteout_m3_M3TextureLayer_set_uvMapping(
25190            self_: *mut whiteout_M3TextureLayer,
25191            value: i32,
25192        );
25193        pub fn whiteout_m3_M3TextureLayer_get_colorType(self_: *mut whiteout_M3TextureLayer)
25194            -> i32;
25195        pub fn whiteout_m3_M3TextureLayer_set_colorType(
25196            self_: *mut whiteout_M3TextureLayer,
25197            value: i32,
25198        );
25199        pub fn whiteout_m3_M3TextureLayer_get_rgbMultiply(
25200            self_: *mut whiteout_M3TextureLayer,
25201        ) -> *mut whiteout_M3AnimRefF32;
25202        pub fn whiteout_m3_M3TextureLayer_set_rgbMultiply(
25203            self_: *mut whiteout_M3TextureLayer,
25204            value: *const whiteout_M3AnimRefF32,
25205        );
25206        pub fn whiteout_m3_M3TextureLayer_get_rgbAdd(
25207            self_: *mut whiteout_M3TextureLayer,
25208        ) -> *mut whiteout_M3AnimRefF32;
25209        pub fn whiteout_m3_M3TextureLayer_set_rgbAdd(
25210            self_: *mut whiteout_M3TextureLayer,
25211            value: *const whiteout_M3AnimRefF32,
25212        );
25213        pub fn whiteout_m3_M3TextureLayer_get_pocTexture(
25214            self_: *mut whiteout_M3TextureLayer,
25215        ) -> u32;
25216        pub fn whiteout_m3_M3TextureLayer_set_pocTexture(
25217            self_: *mut whiteout_M3TextureLayer,
25218            value: u32,
25219        );
25220        pub fn whiteout_m3_M3TextureLayer_get_noiseAmplitude(
25221            self_: *mut whiteout_M3TextureLayer,
25222        ) -> f32;
25223        pub fn whiteout_m3_M3TextureLayer_set_noiseAmplitude(
25224            self_: *mut whiteout_M3TextureLayer,
25225            value: f32,
25226        );
25227        pub fn whiteout_m3_M3TextureLayer_get_noiseFrequency(
25228            self_: *mut whiteout_M3TextureLayer,
25229        ) -> f32;
25230        pub fn whiteout_m3_M3TextureLayer_set_noiseFrequency(
25231            self_: *mut whiteout_M3TextureLayer,
25232            value: f32,
25233        );
25234        pub fn whiteout_m3_M3TextureLayer_get_textureSource(
25235            self_: *mut whiteout_M3TextureLayer,
25236        ) -> u32;
25237        pub fn whiteout_m3_M3TextureLayer_set_textureSource(
25238            self_: *mut whiteout_M3TextureLayer,
25239            value: u32,
25240        );
25241        pub fn whiteout_m3_M3TextureLayer_get_aviFrameRate(
25242            self_: *mut whiteout_M3TextureLayer,
25243        ) -> u32;
25244        pub fn whiteout_m3_M3TextureLayer_set_aviFrameRate(
25245            self_: *mut whiteout_M3TextureLayer,
25246            value: u32,
25247        );
25248        pub fn whiteout_m3_M3TextureLayer_get_aviStart(self_: *mut whiteout_M3TextureLayer) -> u32;
25249        pub fn whiteout_m3_M3TextureLayer_set_aviStart(
25250            self_: *mut whiteout_M3TextureLayer,
25251            value: u32,
25252        );
25253        pub fn whiteout_m3_M3TextureLayer_get_aviStop(self_: *mut whiteout_M3TextureLayer) -> u32;
25254        pub fn whiteout_m3_M3TextureLayer_set_aviStop(
25255            self_: *mut whiteout_M3TextureLayer,
25256            value: u32,
25257        );
25258        pub fn whiteout_m3_M3TextureLayer_get_aviLoop(self_: *mut whiteout_M3TextureLayer) -> u32;
25259        pub fn whiteout_m3_M3TextureLayer_set_aviLoop(
25260            self_: *mut whiteout_M3TextureLayer,
25261            value: u32,
25262        );
25263        pub fn whiteout_m3_M3TextureLayer_get_aviSync(self_: *mut whiteout_M3TextureLayer) -> u32;
25264        pub fn whiteout_m3_M3TextureLayer_set_aviSync(
25265            self_: *mut whiteout_M3TextureLayer,
25266            value: u32,
25267        );
25268        pub fn whiteout_m3_M3TextureLayer_get_aviPlay(
25269            self_: *mut whiteout_M3TextureLayer,
25270        ) -> *mut whiteout_M3AnimRefU32;
25271        pub fn whiteout_m3_M3TextureLayer_set_aviPlay(
25272            self_: *mut whiteout_M3TextureLayer,
25273            value: *const whiteout_M3AnimRefU32,
25274        );
25275        pub fn whiteout_m3_M3TextureLayer_get_aviRestart(
25276            self_: *mut whiteout_M3TextureLayer,
25277        ) -> *mut whiteout_M3AnimRefU32;
25278        pub fn whiteout_m3_M3TextureLayer_set_aviRestart(
25279            self_: *mut whiteout_M3TextureLayer,
25280            value: *const whiteout_M3AnimRefU32,
25281        );
25282        pub fn whiteout_m3_M3TextureLayer_get_flipbookRows(
25283            self_: *mut whiteout_M3TextureLayer,
25284        ) -> u32;
25285        pub fn whiteout_m3_M3TextureLayer_set_flipbookRows(
25286            self_: *mut whiteout_M3TextureLayer,
25287            value: u32,
25288        );
25289        pub fn whiteout_m3_M3TextureLayer_get_flipbookColumns(
25290            self_: *mut whiteout_M3TextureLayer,
25291        ) -> u32;
25292        pub fn whiteout_m3_M3TextureLayer_set_flipbookColumns(
25293            self_: *mut whiteout_M3TextureLayer,
25294            value: u32,
25295        );
25296        pub fn whiteout_m3_M3TextureLayer_get_currentFrame(
25297            self_: *mut whiteout_M3TextureLayer,
25298        ) -> *mut whiteout_M3AnimRefU16;
25299        pub fn whiteout_m3_M3TextureLayer_set_currentFrame(
25300            self_: *mut whiteout_M3TextureLayer,
25301            value: *const whiteout_M3AnimRefU16,
25302        );
25303        pub fn whiteout_m3_M3TextureLayer_get_uvOffset(
25304            self_: *mut whiteout_M3TextureLayer,
25305        ) -> *mut whiteout_M3AnimRefVector2f;
25306        pub fn whiteout_m3_M3TextureLayer_set_uvOffset(
25307            self_: *mut whiteout_M3TextureLayer,
25308            value: *const whiteout_M3AnimRefVector2f,
25309        );
25310        pub fn whiteout_m3_M3TextureLayer_get_uvAngle(
25311            self_: *mut whiteout_M3TextureLayer,
25312        ) -> *mut whiteout_M3AnimRefVector3f;
25313        pub fn whiteout_m3_M3TextureLayer_set_uvAngle(
25314            self_: *mut whiteout_M3TextureLayer,
25315            value: *const whiteout_M3AnimRefVector3f,
25316        );
25317        pub fn whiteout_m3_M3TextureLayer_get_uvTiling(
25318            self_: *mut whiteout_M3TextureLayer,
25319        ) -> *mut whiteout_M3AnimRefVector2f;
25320        pub fn whiteout_m3_M3TextureLayer_set_uvTiling(
25321            self_: *mut whiteout_M3TextureLayer,
25322            value: *const whiteout_M3AnimRefVector2f,
25323        );
25324        pub fn whiteout_m3_M3TextureLayer_get_wOffset(
25325            self_: *mut whiteout_M3TextureLayer,
25326        ) -> *mut whiteout_M3AnimRefF32;
25327        pub fn whiteout_m3_M3TextureLayer_set_wOffset(
25328            self_: *mut whiteout_M3TextureLayer,
25329            value: *const whiteout_M3AnimRefF32,
25330        );
25331        pub fn whiteout_m3_M3TextureLayer_get_wTiling(
25332            self_: *mut whiteout_M3TextureLayer,
25333        ) -> *mut whiteout_M3AnimRefF32;
25334        pub fn whiteout_m3_M3TextureLayer_set_wTiling(
25335            self_: *mut whiteout_M3TextureLayer,
25336            value: *const whiteout_M3AnimRefF32,
25337        );
25338        pub fn whiteout_m3_M3TextureLayer_get_mapAlpha(
25339            self_: *mut whiteout_M3TextureLayer,
25340        ) -> *mut whiteout_M3AnimRefF32;
25341        pub fn whiteout_m3_M3TextureLayer_set_mapAlpha(
25342            self_: *mut whiteout_M3TextureLayer,
25343            value: *const whiteout_M3AnimRefF32,
25344        );
25345        pub fn whiteout_m3_M3TextureLayer_get_triplanarOffset(
25346            self_: *mut whiteout_M3TextureLayer,
25347        ) -> *mut whiteout_M3AnimRefVector3f;
25348        pub fn whiteout_m3_M3TextureLayer_set_triplanarOffset(
25349            self_: *mut whiteout_M3TextureLayer,
25350            value: *const whiteout_M3AnimRefVector3f,
25351        );
25352        pub fn whiteout_m3_M3TextureLayer_get_triplanarScale(
25353            self_: *mut whiteout_M3TextureLayer,
25354        ) -> *mut whiteout_M3AnimRefVector3f;
25355        pub fn whiteout_m3_M3TextureLayer_set_triplanarScale(
25356            self_: *mut whiteout_M3TextureLayer,
25357            value: *const whiteout_M3AnimRefVector3f,
25358        );
25359        pub fn whiteout_m3_M3TextureLayer_get_uvSourceRelated(
25360            self_: *mut whiteout_M3TextureLayer,
25361        ) -> u32;
25362        pub fn whiteout_m3_M3TextureLayer_set_uvSourceRelated(
25363            self_: *mut whiteout_M3TextureLayer,
25364            value: u32,
25365        );
25366        pub fn whiteout_m3_M3TextureLayer_get_fresnelMode(
25367            self_: *mut whiteout_M3TextureLayer,
25368        ) -> i32;
25369        pub fn whiteout_m3_M3TextureLayer_set_fresnelMode(
25370            self_: *mut whiteout_M3TextureLayer,
25371            value: i32,
25372        );
25373        pub fn whiteout_m3_M3TextureLayer_get_fresnelExponent(
25374            self_: *mut whiteout_M3TextureLayer,
25375        ) -> f32;
25376        pub fn whiteout_m3_M3TextureLayer_set_fresnelExponent(
25377            self_: *mut whiteout_M3TextureLayer,
25378            value: f32,
25379        );
25380        pub fn whiteout_m3_M3TextureLayer_get_fresnelMin(
25381            self_: *mut whiteout_M3TextureLayer,
25382        ) -> f32;
25383        pub fn whiteout_m3_M3TextureLayer_set_fresnelMin(
25384            self_: *mut whiteout_M3TextureLayer,
25385            value: f32,
25386        );
25387        pub fn whiteout_m3_M3TextureLayer_get_fresnelMax(
25388            self_: *mut whiteout_M3TextureLayer,
25389        ) -> f32;
25390        pub fn whiteout_m3_M3TextureLayer_set_fresnelMax(
25391            self_: *mut whiteout_M3TextureLayer,
25392            value: f32,
25393        );
25394        pub fn whiteout_m3_M3TextureLayer_get_fresnelTranslation(
25395            self_: *mut whiteout_M3TextureLayer,
25396        ) -> *mut core::ffi::c_void;
25397        pub fn whiteout_m3_M3TextureLayer_set_fresnelTranslation(
25398            self_: *mut whiteout_M3TextureLayer,
25399            value: *const core::ffi::c_void,
25400        );
25401        pub fn whiteout_m3_M3TextureLayer_get_fresnelMask(
25402            self_: *mut whiteout_M3TextureLayer,
25403        ) -> *mut core::ffi::c_void;
25404        pub fn whiteout_m3_M3TextureLayer_set_fresnelMask(
25405            self_: *mut whiteout_M3TextureLayer,
25406            value: *const core::ffi::c_void,
25407        );
25408        pub fn whiteout_m3_M3TextureLayer_get_fresnelRotation(
25409            self_: *mut whiteout_M3TextureLayer,
25410        ) -> *mut core::ffi::c_void;
25411        pub fn whiteout_m3_M3TextureLayer_set_fresnelRotation(
25412            self_: *mut whiteout_M3TextureLayer,
25413            value: *const core::ffi::c_void,
25414        );
25415        pub fn whiteout_m3_M3TextureLayer_get_uvDensity(self_: *mut whiteout_M3TextureLayer)
25416            -> u32;
25417        pub fn whiteout_m3_M3TextureLayer_set_uvDensity(
25418            self_: *mut whiteout_M3TextureLayer,
25419            value: u32,
25420        );
25421        // StandardMaterial
25422        pub fn whiteout_m3_M3StandardMaterial_new() -> *mut whiteout_M3StandardMaterial;
25423        pub fn whiteout_m3_M3StandardMaterial_delete(self_: *mut whiteout_M3StandardMaterial);
25424        pub fn whiteout_m3_M3StandardMaterial_get_name(
25425            self_: *mut whiteout_M3StandardMaterial,
25426        ) -> RawCString;
25427        pub fn whiteout_m3_M3StandardMaterial_set_name(
25428            self_: *mut whiteout_M3StandardMaterial,
25429            value: *const core::ffi::c_char,
25430        );
25431        pub fn whiteout_m3_M3StandardMaterial_get_additionalFlags(
25432            self_: *mut whiteout_M3StandardMaterial,
25433        ) -> i32;
25434        pub fn whiteout_m3_M3StandardMaterial_set_additionalFlags(
25435            self_: *mut whiteout_M3StandardMaterial,
25436            value: i32,
25437        );
25438        pub fn whiteout_m3_M3StandardMaterial_get_flags(
25439            self_: *mut whiteout_M3StandardMaterial,
25440        ) -> i32;
25441        pub fn whiteout_m3_M3StandardMaterial_set_flags(
25442            self_: *mut whiteout_M3StandardMaterial,
25443            value: i32,
25444        );
25445        pub fn whiteout_m3_M3StandardMaterial_get_blendMode(
25446            self_: *mut whiteout_M3StandardMaterial,
25447        ) -> i32;
25448        pub fn whiteout_m3_M3StandardMaterial_set_blendMode(
25449            self_: *mut whiteout_M3StandardMaterial,
25450            value: i32,
25451        );
25452        pub fn whiteout_m3_M3StandardMaterial_get_priority(
25453            self_: *mut whiteout_M3StandardMaterial,
25454        ) -> i32;
25455        pub fn whiteout_m3_M3StandardMaterial_set_priority(
25456            self_: *mut whiteout_M3StandardMaterial,
25457            value: i32,
25458        );
25459        pub fn whiteout_m3_M3StandardMaterial_get_rttChannels(
25460            self_: *mut whiteout_M3StandardMaterial,
25461        ) -> u32;
25462        pub fn whiteout_m3_M3StandardMaterial_set_rttChannels(
25463            self_: *mut whiteout_M3StandardMaterial,
25464            value: u32,
25465        );
25466        pub fn whiteout_m3_M3StandardMaterial_get_specularExponent(
25467            self_: *mut whiteout_M3StandardMaterial,
25468        ) -> f32;
25469        pub fn whiteout_m3_M3StandardMaterial_set_specularExponent(
25470            self_: *mut whiteout_M3StandardMaterial,
25471            value: f32,
25472        );
25473        pub fn whiteout_m3_M3StandardMaterial_get_depthBlendFalloff(
25474            self_: *mut whiteout_M3StandardMaterial,
25475        ) -> f32;
25476        pub fn whiteout_m3_M3StandardMaterial_set_depthBlendFalloff(
25477            self_: *mut whiteout_M3StandardMaterial,
25478            value: f32,
25479        );
25480        pub fn whiteout_m3_M3StandardMaterial_get_alphaTestThreshold(
25481            self_: *mut whiteout_M3StandardMaterial,
25482        ) -> u32;
25483        pub fn whiteout_m3_M3StandardMaterial_set_alphaTestThreshold(
25484            self_: *mut whiteout_M3StandardMaterial,
25485            value: u32,
25486        );
25487        pub fn whiteout_m3_M3StandardMaterial_get_hdrSpecularMultiplier(
25488            self_: *mut whiteout_M3StandardMaterial,
25489        ) -> f32;
25490        pub fn whiteout_m3_M3StandardMaterial_set_hdrSpecularMultiplier(
25491            self_: *mut whiteout_M3StandardMaterial,
25492            value: f32,
25493        );
25494        pub fn whiteout_m3_M3StandardMaterial_get_hdrEmissiveMultiplier(
25495            self_: *mut whiteout_M3StandardMaterial,
25496        ) -> f32;
25497        pub fn whiteout_m3_M3StandardMaterial_set_hdrEmissiveMultiplier(
25498            self_: *mut whiteout_M3StandardMaterial,
25499            value: f32,
25500        );
25501        pub fn whiteout_m3_M3StandardMaterial_get_hdrEnvironmentConstant(
25502            self_: *mut whiteout_M3StandardMaterial,
25503        ) -> f32;
25504        pub fn whiteout_m3_M3StandardMaterial_set_hdrEnvironmentConstant(
25505            self_: *mut whiteout_M3StandardMaterial,
25506            value: f32,
25507        );
25508        pub fn whiteout_m3_M3StandardMaterial_get_hdrEnvironmentDiffuse(
25509            self_: *mut whiteout_M3StandardMaterial,
25510        ) -> f32;
25511        pub fn whiteout_m3_M3StandardMaterial_set_hdrEnvironmentDiffuse(
25512            self_: *mut whiteout_M3StandardMaterial,
25513            value: f32,
25514        );
25515        pub fn whiteout_m3_M3StandardMaterial_get_hdrEnvironmentSpecular(
25516            self_: *mut whiteout_M3StandardMaterial,
25517        ) -> f32;
25518        pub fn whiteout_m3_M3StandardMaterial_set_hdrEnvironmentSpecular(
25519            self_: *mut whiteout_M3StandardMaterial,
25520            value: f32,
25521        );
25522        pub fn whiteout_m3_M3StandardMaterial_get_materialClass(
25523            self_: *mut whiteout_M3StandardMaterial,
25524        ) -> i32;
25525        pub fn whiteout_m3_M3StandardMaterial_set_materialClass(
25526            self_: *mut whiteout_M3StandardMaterial,
25527            value: i32,
25528        );
25529        pub fn whiteout_m3_M3StandardMaterial_get_layerBlendMode(
25530            self_: *mut whiteout_M3StandardMaterial,
25531        ) -> i32;
25532        pub fn whiteout_m3_M3StandardMaterial_set_layerBlendMode(
25533            self_: *mut whiteout_M3StandardMaterial,
25534            value: i32,
25535        );
25536        pub fn whiteout_m3_M3StandardMaterial_get_emissiveBlendMode1(
25537            self_: *mut whiteout_M3StandardMaterial,
25538        ) -> i32;
25539        pub fn whiteout_m3_M3StandardMaterial_set_emissiveBlendMode1(
25540            self_: *mut whiteout_M3StandardMaterial,
25541            value: i32,
25542        );
25543        pub fn whiteout_m3_M3StandardMaterial_get_emissiveBlendMode2(
25544            self_: *mut whiteout_M3StandardMaterial,
25545        ) -> i32;
25546        pub fn whiteout_m3_M3StandardMaterial_set_emissiveBlendMode2(
25547            self_: *mut whiteout_M3StandardMaterial,
25548            value: i32,
25549        );
25550        pub fn whiteout_m3_M3StandardMaterial_get_specularMode(
25551            self_: *mut whiteout_M3StandardMaterial,
25552        ) -> i32;
25553        pub fn whiteout_m3_M3StandardMaterial_set_specularMode(
25554            self_: *mut whiteout_M3StandardMaterial,
25555            value: i32,
25556        );
25557        pub fn whiteout_m3_M3StandardMaterial_get_parallaxHeight(
25558            self_: *mut whiteout_M3StandardMaterial,
25559        ) -> *mut whiteout_M3AnimRefF32;
25560        pub fn whiteout_m3_M3StandardMaterial_set_parallaxHeight(
25561            self_: *mut whiteout_M3StandardMaterial,
25562            value: *const whiteout_M3AnimRefF32,
25563        );
25564        pub fn whiteout_m3_M3StandardMaterial_get_motionBlurAmount(
25565            self_: *mut whiteout_M3StandardMaterial,
25566        ) -> *mut whiteout_M3AnimRefF32;
25567        pub fn whiteout_m3_M3StandardMaterial_set_motionBlurAmount(
25568            self_: *mut whiteout_M3StandardMaterial,
25569            value: *const whiteout_M3AnimRefF32,
25570        );
25571        pub fn whiteout_m3_M3StandardMaterial_get_normalBlendFactors_count(
25572            self_: *mut whiteout_M3StandardMaterial,
25573        ) -> usize;
25574        pub fn whiteout_m3_M3StandardMaterial_resize_normalBlendFactors(
25575            self_: *mut whiteout_M3StandardMaterial,
25576            count: usize,
25577        );
25578        pub fn whiteout_m3_M3StandardMaterial_get_normalBlendFactors_at(
25579            self_: *mut whiteout_M3StandardMaterial,
25580            index: usize,
25581        ) -> *mut whiteout_M3AnimRefF32;
25582        // DisplacementMaterial
25583        pub fn whiteout_m3_M3DisplacementMaterial_new() -> *mut whiteout_M3DisplacementMaterial;
25584        pub fn whiteout_m3_M3DisplacementMaterial_delete(
25585            self_: *mut whiteout_M3DisplacementMaterial,
25586        );
25587        pub fn whiteout_m3_M3DisplacementMaterial_get_name(
25588            self_: *mut whiteout_M3DisplacementMaterial,
25589        ) -> RawCString;
25590        pub fn whiteout_m3_M3DisplacementMaterial_set_name(
25591            self_: *mut whiteout_M3DisplacementMaterial,
25592            value: *const core::ffi::c_char,
25593        );
25594        pub fn whiteout_m3_M3DisplacementMaterial_get_unknown(
25595            self_: *mut whiteout_M3DisplacementMaterial,
25596        ) -> u32;
25597        pub fn whiteout_m3_M3DisplacementMaterial_set_unknown(
25598            self_: *mut whiteout_M3DisplacementMaterial,
25599            value: u32,
25600        );
25601        pub fn whiteout_m3_M3DisplacementMaterial_get_strength(
25602            self_: *mut whiteout_M3DisplacementMaterial,
25603        ) -> *mut whiteout_M3AnimRefF32;
25604        pub fn whiteout_m3_M3DisplacementMaterial_set_strength(
25605            self_: *mut whiteout_M3DisplacementMaterial,
25606            value: *const whiteout_M3AnimRefF32,
25607        );
25608        pub fn whiteout_m3_M3DisplacementMaterial_get_priority(
25609            self_: *mut whiteout_M3DisplacementMaterial,
25610        ) -> u32;
25611        pub fn whiteout_m3_M3DisplacementMaterial_set_priority(
25612            self_: *mut whiteout_M3DisplacementMaterial,
25613            value: u32,
25614        );
25615        // CompositeSection
25616        pub fn whiteout_m3_M3CompositeSection_new() -> *mut whiteout_M3CompositeSection;
25617        pub fn whiteout_m3_M3CompositeSection_delete(self_: *mut whiteout_M3CompositeSection);
25618        pub fn whiteout_m3_M3CompositeSection_get_materialIndex(
25619            self_: *mut whiteout_M3CompositeSection,
25620        ) -> u32;
25621        pub fn whiteout_m3_M3CompositeSection_set_materialIndex(
25622            self_: *mut whiteout_M3CompositeSection,
25623            value: u32,
25624        );
25625        pub fn whiteout_m3_M3CompositeSection_get_mapMultiplier(
25626            self_: *mut whiteout_M3CompositeSection,
25627        ) -> *mut whiteout_M3AnimRefF32;
25628        pub fn whiteout_m3_M3CompositeSection_set_mapMultiplier(
25629            self_: *mut whiteout_M3CompositeSection,
25630            value: *const whiteout_M3AnimRefF32,
25631        );
25632        // CompositeMaterial
25633        pub fn whiteout_m3_M3CompositeMaterial_new() -> *mut whiteout_M3CompositeMaterial;
25634        pub fn whiteout_m3_M3CompositeMaterial_delete(self_: *mut whiteout_M3CompositeMaterial);
25635        pub fn whiteout_m3_M3CompositeMaterial_get_name(
25636            self_: *mut whiteout_M3CompositeMaterial,
25637        ) -> RawCString;
25638        pub fn whiteout_m3_M3CompositeMaterial_set_name(
25639            self_: *mut whiteout_M3CompositeMaterial,
25640            value: *const core::ffi::c_char,
25641        );
25642        pub fn whiteout_m3_M3CompositeMaterial_get_priority(
25643            self_: *mut whiteout_M3CompositeMaterial,
25644        ) -> u32;
25645        pub fn whiteout_m3_M3CompositeMaterial_set_priority(
25646            self_: *mut whiteout_M3CompositeMaterial,
25647            value: u32,
25648        );
25649        pub fn whiteout_m3_M3CompositeMaterial_get_sections_count(
25650            self_: *mut whiteout_M3CompositeMaterial,
25651        ) -> usize;
25652        pub fn whiteout_m3_M3CompositeMaterial_resize_sections(
25653            self_: *mut whiteout_M3CompositeMaterial,
25654            count: usize,
25655        );
25656        pub fn whiteout_m3_M3CompositeMaterial_get_sections_at(
25657            self_: *mut whiteout_M3CompositeMaterial,
25658            index: usize,
25659        ) -> *mut whiteout_M3CompositeSection;
25660        // TerrainMaterial
25661        pub fn whiteout_m3_M3TerrainMaterial_new() -> *mut whiteout_M3TerrainMaterial;
25662        pub fn whiteout_m3_M3TerrainMaterial_delete(self_: *mut whiteout_M3TerrainMaterial);
25663        pub fn whiteout_m3_M3TerrainMaterial_get_name(
25664            self_: *mut whiteout_M3TerrainMaterial,
25665        ) -> RawCString;
25666        pub fn whiteout_m3_M3TerrainMaterial_set_name(
25667            self_: *mut whiteout_M3TerrainMaterial,
25668            value: *const core::ffi::c_char,
25669        );
25670        pub fn whiteout_m3_M3TerrainMaterial_get_unknown(
25671            self_: *mut whiteout_M3TerrainMaterial,
25672        ) -> u32;
25673        pub fn whiteout_m3_M3TerrainMaterial_set_unknown(
25674            self_: *mut whiteout_M3TerrainMaterial,
25675            value: u32,
25676        );
25677        // VolumeMaterial
25678        pub fn whiteout_m3_M3VolumeMaterial_new() -> *mut whiteout_M3VolumeMaterial;
25679        pub fn whiteout_m3_M3VolumeMaterial_delete(self_: *mut whiteout_M3VolumeMaterial);
25680        pub fn whiteout_m3_M3VolumeMaterial_get_name(
25681            self_: *mut whiteout_M3VolumeMaterial,
25682        ) -> RawCString;
25683        pub fn whiteout_m3_M3VolumeMaterial_set_name(
25684            self_: *mut whiteout_M3VolumeMaterial,
25685            value: *const core::ffi::c_char,
25686        );
25687        pub fn whiteout_m3_M3VolumeMaterial_get_blendMode(
25688            self_: *mut whiteout_M3VolumeMaterial,
25689        ) -> u32;
25690        pub fn whiteout_m3_M3VolumeMaterial_set_blendMode(
25691            self_: *mut whiteout_M3VolumeMaterial,
25692            value: u32,
25693        );
25694        pub fn whiteout_m3_M3VolumeMaterial_get_falloffType(
25695            self_: *mut whiteout_M3VolumeMaterial,
25696        ) -> i32;
25697        pub fn whiteout_m3_M3VolumeMaterial_set_falloffType(
25698            self_: *mut whiteout_M3VolumeMaterial,
25699            value: i32,
25700        );
25701        pub fn whiteout_m3_M3VolumeMaterial_get_density(
25702            self_: *mut whiteout_M3VolumeMaterial,
25703        ) -> *mut whiteout_M3AnimRefF32;
25704        pub fn whiteout_m3_M3VolumeMaterial_set_density(
25705            self_: *mut whiteout_M3VolumeMaterial,
25706            value: *const whiteout_M3AnimRefF32,
25707        );
25708        pub fn whiteout_m3_M3VolumeMaterial_get_alphaThreshold(
25709            self_: *mut whiteout_M3VolumeMaterial,
25710        ) -> u32;
25711        pub fn whiteout_m3_M3VolumeMaterial_set_alphaThreshold(
25712            self_: *mut whiteout_M3VolumeMaterial,
25713            value: u32,
25714        );
25715        // HairMaterial
25716        pub fn whiteout_m3_M3HairMaterial_new() -> *mut whiteout_M3HairMaterial;
25717        pub fn whiteout_m3_M3HairMaterial_delete(self_: *mut whiteout_M3HairMaterial);
25718        pub fn whiteout_m3_M3HairMaterial_get_name(
25719            self_: *mut whiteout_M3HairMaterial,
25720        ) -> RawCString;
25721        pub fn whiteout_m3_M3HairMaterial_set_name(
25722            self_: *mut whiteout_M3HairMaterial,
25723            value: *const core::ffi::c_char,
25724        );
25725        pub fn whiteout_m3_M3HairMaterial_get_shiftPrimary(
25726            self_: *mut whiteout_M3HairMaterial,
25727        ) -> f32;
25728        pub fn whiteout_m3_M3HairMaterial_set_shiftPrimary(
25729            self_: *mut whiteout_M3HairMaterial,
25730            value: f32,
25731        );
25732        pub fn whiteout_m3_M3HairMaterial_get_shiftSecondary(
25733            self_: *mut whiteout_M3HairMaterial,
25734        ) -> f32;
25735        pub fn whiteout_m3_M3HairMaterial_set_shiftSecondary(
25736            self_: *mut whiteout_M3HairMaterial,
25737            value: f32,
25738        );
25739        pub fn whiteout_m3_M3HairMaterial_get_colorDiffuse(
25740            self_: *mut whiteout_M3HairMaterial,
25741        ) -> *mut whiteout_M3AnimRefM3ColorBGRA;
25742        pub fn whiteout_m3_M3HairMaterial_set_colorDiffuse(
25743            self_: *mut whiteout_M3HairMaterial,
25744            value: *const whiteout_M3AnimRefM3ColorBGRA,
25745        );
25746        pub fn whiteout_m3_M3HairMaterial_get_colorSpec(
25747            self_: *mut whiteout_M3HairMaterial,
25748        ) -> *mut whiteout_M3AnimRefM3ColorBGRA;
25749        pub fn whiteout_m3_M3HairMaterial_set_colorSpec(
25750            self_: *mut whiteout_M3HairMaterial,
25751            value: *const whiteout_M3AnimRefM3ColorBGRA,
25752        );
25753        pub fn whiteout_m3_M3HairMaterial_get_specExponent0(
25754            self_: *mut whiteout_M3HairMaterial,
25755        ) -> f32;
25756        pub fn whiteout_m3_M3HairMaterial_set_specExponent0(
25757            self_: *mut whiteout_M3HairMaterial,
25758            value: f32,
25759        );
25760        pub fn whiteout_m3_M3HairMaterial_get_specExponent1(
25761            self_: *mut whiteout_M3HairMaterial,
25762        ) -> f32;
25763        pub fn whiteout_m3_M3HairMaterial_set_specExponent1(
25764            self_: *mut whiteout_M3HairMaterial,
25765            value: f32,
25766        );
25767        // VolumeNoiseMaterial
25768        pub fn whiteout_m3_M3VolumeNoiseMaterial_new() -> *mut whiteout_M3VolumeNoiseMaterial;
25769        pub fn whiteout_m3_M3VolumeNoiseMaterial_delete(self_: *mut whiteout_M3VolumeNoiseMaterial);
25770        pub fn whiteout_m3_M3VolumeNoiseMaterial_get_name(
25771            self_: *mut whiteout_M3VolumeNoiseMaterial,
25772        ) -> RawCString;
25773        pub fn whiteout_m3_M3VolumeNoiseMaterial_set_name(
25774            self_: *mut whiteout_M3VolumeNoiseMaterial,
25775            value: *const core::ffi::c_char,
25776        );
25777        pub fn whiteout_m3_M3VolumeNoiseMaterial_get_falloffType(
25778            self_: *mut whiteout_M3VolumeNoiseMaterial,
25779        ) -> i32;
25780        pub fn whiteout_m3_M3VolumeNoiseMaterial_set_falloffType(
25781            self_: *mut whiteout_M3VolumeNoiseMaterial,
25782            value: i32,
25783        );
25784        pub fn whiteout_m3_M3VolumeNoiseMaterial_get_drawTransparency(
25785            self_: *mut whiteout_M3VolumeNoiseMaterial,
25786        ) -> i32;
25787        pub fn whiteout_m3_M3VolumeNoiseMaterial_set_drawTransparency(
25788            self_: *mut whiteout_M3VolumeNoiseMaterial,
25789            value: i32,
25790        );
25791        pub fn whiteout_m3_M3VolumeNoiseMaterial_get_density(
25792            self_: *mut whiteout_M3VolumeNoiseMaterial,
25793        ) -> *mut whiteout_M3AnimRefF32;
25794        pub fn whiteout_m3_M3VolumeNoiseMaterial_set_density(
25795            self_: *mut whiteout_M3VolumeNoiseMaterial,
25796            value: *const whiteout_M3AnimRefF32,
25797        );
25798        pub fn whiteout_m3_M3VolumeNoiseMaterial_get_nearPlane(
25799            self_: *mut whiteout_M3VolumeNoiseMaterial,
25800        ) -> *mut whiteout_M3AnimRefF32;
25801        pub fn whiteout_m3_M3VolumeNoiseMaterial_set_nearPlane(
25802            self_: *mut whiteout_M3VolumeNoiseMaterial,
25803            value: *const whiteout_M3AnimRefF32,
25804        );
25805        pub fn whiteout_m3_M3VolumeNoiseMaterial_get_falloff(
25806            self_: *mut whiteout_M3VolumeNoiseMaterial,
25807        ) -> *mut whiteout_M3AnimRefF32;
25808        pub fn whiteout_m3_M3VolumeNoiseMaterial_set_falloff(
25809            self_: *mut whiteout_M3VolumeNoiseMaterial,
25810            value: *const whiteout_M3AnimRefF32,
25811        );
25812        pub fn whiteout_m3_M3VolumeNoiseMaterial_get_scrollRate(
25813            self_: *mut whiteout_M3VolumeNoiseMaterial,
25814        ) -> *mut whiteout_M3AnimRefVector3f;
25815        pub fn whiteout_m3_M3VolumeNoiseMaterial_set_scrollRate(
25816            self_: *mut whiteout_M3VolumeNoiseMaterial,
25817            value: *const whiteout_M3AnimRefVector3f,
25818        );
25819        pub fn whiteout_m3_M3VolumeNoiseMaterial_get_position(
25820            self_: *mut whiteout_M3VolumeNoiseMaterial,
25821        ) -> *mut whiteout_M3AnimRefVector3f;
25822        pub fn whiteout_m3_M3VolumeNoiseMaterial_set_position(
25823            self_: *mut whiteout_M3VolumeNoiseMaterial,
25824            value: *const whiteout_M3AnimRefVector3f,
25825        );
25826        pub fn whiteout_m3_M3VolumeNoiseMaterial_get_scale(
25827            self_: *mut whiteout_M3VolumeNoiseMaterial,
25828        ) -> *mut whiteout_M3AnimRefVector3f;
25829        pub fn whiteout_m3_M3VolumeNoiseMaterial_set_scale(
25830            self_: *mut whiteout_M3VolumeNoiseMaterial,
25831            value: *const whiteout_M3AnimRefVector3f,
25832        );
25833        pub fn whiteout_m3_M3VolumeNoiseMaterial_get_rotation(
25834            self_: *mut whiteout_M3VolumeNoiseMaterial,
25835        ) -> *mut whiteout_M3AnimRefVector3f;
25836        pub fn whiteout_m3_M3VolumeNoiseMaterial_set_rotation(
25837            self_: *mut whiteout_M3VolumeNoiseMaterial,
25838            value: *const whiteout_M3AnimRefVector3f,
25839        );
25840        pub fn whiteout_m3_M3VolumeNoiseMaterial_get_alphaThreshold(
25841            self_: *mut whiteout_M3VolumeNoiseMaterial,
25842        ) -> u32;
25843        pub fn whiteout_m3_M3VolumeNoiseMaterial_set_alphaThreshold(
25844            self_: *mut whiteout_M3VolumeNoiseMaterial,
25845            value: u32,
25846        );
25847        pub fn whiteout_m3_M3VolumeNoiseMaterial_get_flags(
25848            self_: *mut whiteout_M3VolumeNoiseMaterial,
25849        ) -> i32;
25850        pub fn whiteout_m3_M3VolumeNoiseMaterial_set_flags(
25851            self_: *mut whiteout_M3VolumeNoiseMaterial,
25852            value: i32,
25853        );
25854        // CreepMaterial
25855        pub fn whiteout_m3_M3CreepMaterial_new() -> *mut whiteout_M3CreepMaterial;
25856        pub fn whiteout_m3_M3CreepMaterial_delete(self_: *mut whiteout_M3CreepMaterial);
25857        pub fn whiteout_m3_M3CreepMaterial_get_name(
25858            self_: *mut whiteout_M3CreepMaterial,
25859        ) -> RawCString;
25860        pub fn whiteout_m3_M3CreepMaterial_set_name(
25861            self_: *mut whiteout_M3CreepMaterial,
25862            value: *const core::ffi::c_char,
25863        );
25864        pub fn whiteout_m3_M3CreepMaterial_get_creepLow(
25865            self_: *mut whiteout_M3CreepMaterial,
25866        ) -> u32;
25867        pub fn whiteout_m3_M3CreepMaterial_set_creepLow(
25868            self_: *mut whiteout_M3CreepMaterial,
25869            value: u32,
25870        );
25871        // STBMaterial
25872        pub fn whiteout_m3_M3STBMaterial_new() -> *mut whiteout_M3STBMaterial;
25873        pub fn whiteout_m3_M3STBMaterial_delete(self_: *mut whiteout_M3STBMaterial);
25874        pub fn whiteout_m3_M3STBMaterial_get_name(self_: *mut whiteout_M3STBMaterial)
25875            -> RawCString;
25876        pub fn whiteout_m3_M3STBMaterial_set_name(
25877            self_: *mut whiteout_M3STBMaterial,
25878            value: *const core::ffi::c_char,
25879        );
25880        // ReflectionMaterial
25881        pub fn whiteout_m3_M3ReflectionMaterial_new() -> *mut whiteout_M3ReflectionMaterial;
25882        pub fn whiteout_m3_M3ReflectionMaterial_delete(self_: *mut whiteout_M3ReflectionMaterial);
25883        pub fn whiteout_m3_M3ReflectionMaterial_get_name(
25884            self_: *mut whiteout_M3ReflectionMaterial,
25885        ) -> RawCString;
25886        pub fn whiteout_m3_M3ReflectionMaterial_set_name(
25887            self_: *mut whiteout_M3ReflectionMaterial,
25888            value: *const core::ffi::c_char,
25889        );
25890        pub fn whiteout_m3_M3ReflectionMaterial_get_unknown(
25891            self_: *mut whiteout_M3ReflectionMaterial,
25892        ) -> u32;
25893        pub fn whiteout_m3_M3ReflectionMaterial_set_unknown(
25894            self_: *mut whiteout_M3ReflectionMaterial,
25895            value: u32,
25896        );
25897        pub fn whiteout_m3_M3ReflectionMaterial_get_reflectionStrength(
25898            self_: *mut whiteout_M3ReflectionMaterial,
25899        ) -> *mut whiteout_M3AnimRefF32;
25900        pub fn whiteout_m3_M3ReflectionMaterial_set_reflectionStrength(
25901            self_: *mut whiteout_M3ReflectionMaterial,
25902            value: *const whiteout_M3AnimRefF32,
25903        );
25904        pub fn whiteout_m3_M3ReflectionMaterial_get_displacementStrength(
25905            self_: *mut whiteout_M3ReflectionMaterial,
25906        ) -> *mut whiteout_M3AnimRefF32;
25907        pub fn whiteout_m3_M3ReflectionMaterial_set_displacementStrength(
25908            self_: *mut whiteout_M3ReflectionMaterial,
25909            value: *const whiteout_M3AnimRefF32,
25910        );
25911        pub fn whiteout_m3_M3ReflectionMaterial_get_reflectionOffset(
25912            self_: *mut whiteout_M3ReflectionMaterial,
25913        ) -> *mut whiteout_M3AnimRefF32;
25914        pub fn whiteout_m3_M3ReflectionMaterial_set_reflectionOffset(
25915            self_: *mut whiteout_M3ReflectionMaterial,
25916            value: *const whiteout_M3AnimRefF32,
25917        );
25918        pub fn whiteout_m3_M3ReflectionMaterial_get_blurAngle(
25919            self_: *mut whiteout_M3ReflectionMaterial,
25920        ) -> *mut whiteout_M3AnimRefF32;
25921        pub fn whiteout_m3_M3ReflectionMaterial_set_blurAngle(
25922            self_: *mut whiteout_M3ReflectionMaterial,
25923            value: *const whiteout_M3AnimRefF32,
25924        );
25925        pub fn whiteout_m3_M3ReflectionMaterial_get_blurDistanceMax(
25926            self_: *mut whiteout_M3ReflectionMaterial,
25927        ) -> *mut whiteout_M3AnimRefF32;
25928        pub fn whiteout_m3_M3ReflectionMaterial_set_blurDistanceMax(
25929            self_: *mut whiteout_M3ReflectionMaterial,
25930            value: *const whiteout_M3AnimRefF32,
25931        );
25932        pub fn whiteout_m3_M3ReflectionMaterial_get_flags(
25933            self_: *mut whiteout_M3ReflectionMaterial,
25934        ) -> i32;
25935        pub fn whiteout_m3_M3ReflectionMaterial_set_flags(
25936            self_: *mut whiteout_M3ReflectionMaterial,
25937            value: i32,
25938        );
25939        pub fn whiteout_m3_M3ReflectionMaterial_get_unknown2(
25940            self_: *mut whiteout_M3ReflectionMaterial,
25941        ) -> u32;
25942        pub fn whiteout_m3_M3ReflectionMaterial_set_unknown2(
25943            self_: *mut whiteout_M3ReflectionMaterial,
25944            value: u32,
25945        );
25946        // SubFlare
25947        pub fn whiteout_m3_M3SubFlare_new() -> *mut whiteout_M3SubFlare;
25948        pub fn whiteout_m3_M3SubFlare_delete(self_: *mut whiteout_M3SubFlare);
25949        pub fn whiteout_m3_M3SubFlare_get_index(self_: *mut whiteout_M3SubFlare) -> u32;
25950        pub fn whiteout_m3_M3SubFlare_set_index(self_: *mut whiteout_M3SubFlare, value: u32);
25951        pub fn whiteout_m3_M3SubFlare_get_position(self_: *mut whiteout_M3SubFlare) -> f32;
25952        pub fn whiteout_m3_M3SubFlare_set_position(self_: *mut whiteout_M3SubFlare, value: f32);
25953        pub fn whiteout_m3_M3SubFlare_get_sizeXY(
25954            self_: *mut whiteout_M3SubFlare,
25955        ) -> *mut core::ffi::c_void;
25956        pub fn whiteout_m3_M3SubFlare_set_sizeXY(
25957            self_: *mut whiteout_M3SubFlare,
25958            value: *const core::ffi::c_void,
25959        );
25960        pub fn whiteout_m3_M3SubFlare_get_scaleXY(
25961            self_: *mut whiteout_M3SubFlare,
25962        ) -> *mut core::ffi::c_void;
25963        pub fn whiteout_m3_M3SubFlare_set_scaleXY(
25964            self_: *mut whiteout_M3SubFlare,
25965            value: *const core::ffi::c_void,
25966        );
25967        pub fn whiteout_m3_M3SubFlare_get_fadeIn(
25968            self_: *mut whiteout_M3SubFlare,
25969        ) -> *mut core::ffi::c_void;
25970        pub fn whiteout_m3_M3SubFlare_set_fadeIn(
25971            self_: *mut whiteout_M3SubFlare,
25972            value: *const core::ffi::c_void,
25973        );
25974        pub fn whiteout_m3_M3SubFlare_get_fadeOut(
25975            self_: *mut whiteout_M3SubFlare,
25976        ) -> *mut core::ffi::c_void;
25977        pub fn whiteout_m3_M3SubFlare_set_fadeOut(
25978            self_: *mut whiteout_M3SubFlare,
25979            value: *const core::ffi::c_void,
25980        );
25981        pub fn whiteout_m3_M3SubFlare_get_colorAlpha(
25982            self_: *mut whiteout_M3SubFlare,
25983        ) -> *mut whiteout_M3ColorBGRA;
25984        pub fn whiteout_m3_M3SubFlare_set_colorAlpha(
25985            self_: *mut whiteout_M3SubFlare,
25986            value: *const whiteout_M3ColorBGRA,
25987        );
25988        pub fn whiteout_m3_M3SubFlare_get_faceCenter(self_: *mut whiteout_M3SubFlare) -> u32;
25989        pub fn whiteout_m3_M3SubFlare_set_faceCenter(self_: *mut whiteout_M3SubFlare, value: u32);
25990        pub fn whiteout_m3_M3SubFlare_get_offset(
25991            self_: *mut whiteout_M3SubFlare,
25992        ) -> *mut core::ffi::c_void;
25993        pub fn whiteout_m3_M3SubFlare_set_offset(
25994            self_: *mut whiteout_M3SubFlare,
25995            value: *const core::ffi::c_void,
25996        );
25997        // LensFlare
25998        pub fn whiteout_m3_M3LensFlare_new() -> *mut whiteout_M3LensFlare;
25999        pub fn whiteout_m3_M3LensFlare_delete(self_: *mut whiteout_M3LensFlare);
26000        pub fn whiteout_m3_M3LensFlare_get_name(self_: *mut whiteout_M3LensFlare) -> RawCString;
26001        pub fn whiteout_m3_M3LensFlare_set_name(
26002            self_: *mut whiteout_M3LensFlare,
26003            value: *const core::ffi::c_char,
26004        );
26005        pub fn whiteout_m3_M3LensFlare_get_subFlares_count(
26006            self_: *mut whiteout_M3LensFlare,
26007        ) -> usize;
26008        pub fn whiteout_m3_M3LensFlare_resize_subFlares(
26009            self_: *mut whiteout_M3LensFlare,
26010            count: usize,
26011        );
26012        pub fn whiteout_m3_M3LensFlare_get_subFlares_at(
26013            self_: *mut whiteout_M3LensFlare,
26014            index: usize,
26015        ) -> *mut whiteout_M3SubFlare;
26016        pub fn whiteout_m3_M3LensFlare_get_columns(self_: *mut whiteout_M3LensFlare) -> u32;
26017        pub fn whiteout_m3_M3LensFlare_set_columns(self_: *mut whiteout_M3LensFlare, value: u32);
26018        pub fn whiteout_m3_M3LensFlare_get_rows(self_: *mut whiteout_M3LensFlare) -> u32;
26019        pub fn whiteout_m3_M3LensFlare_set_rows(self_: *mut whiteout_M3LensFlare, value: u32);
26020        pub fn whiteout_m3_M3LensFlare_get_distanceFade(self_: *mut whiteout_M3LensFlare) -> f32;
26021        pub fn whiteout_m3_M3LensFlare_set_distanceFade(
26022            self_: *mut whiteout_M3LensFlare,
26023            value: f32,
26024        );
26025        pub fn whiteout_m3_M3LensFlare_get_libName(self_: *mut whiteout_M3LensFlare) -> RawCString;
26026        pub fn whiteout_m3_M3LensFlare_set_libName(
26027            self_: *mut whiteout_M3LensFlare,
26028            value: *const core::ffi::c_char,
26029        );
26030        pub fn whiteout_m3_M3LensFlare_get_intensity(
26031            self_: *mut whiteout_M3LensFlare,
26032        ) -> *mut whiteout_M3AnimRefF32;
26033        pub fn whiteout_m3_M3LensFlare_set_intensity(
26034            self_: *mut whiteout_M3LensFlare,
26035            value: *const whiteout_M3AnimRefF32,
26036        );
26037        pub fn whiteout_m3_M3LensFlare_get_color(
26038            self_: *mut whiteout_M3LensFlare,
26039        ) -> *mut whiteout_M3AnimRefM3ColorBGRA;
26040        pub fn whiteout_m3_M3LensFlare_set_color(
26041            self_: *mut whiteout_M3LensFlare,
26042            value: *const whiteout_M3AnimRefM3ColorBGRA,
26043        );
26044        pub fn whiteout_m3_M3LensFlare_get_hdr(
26045            self_: *mut whiteout_M3LensFlare,
26046        ) -> *mut whiteout_M3AnimRefF32;
26047        pub fn whiteout_m3_M3LensFlare_set_hdr(
26048            self_: *mut whiteout_M3LensFlare,
26049            value: *const whiteout_M3AnimRefF32,
26050        );
26051        pub fn whiteout_m3_M3LensFlare_get_size(
26052            self_: *mut whiteout_M3LensFlare,
26053        ) -> *mut whiteout_M3AnimRefF32;
26054        pub fn whiteout_m3_M3LensFlare_set_size(
26055            self_: *mut whiteout_M3LensFlare,
26056            value: *const whiteout_M3AnimRefF32,
26057        );
26058        // MaterialAddData
26059        pub fn whiteout_m3_M3MaterialAddData_new() -> *mut whiteout_M3MaterialAddData;
26060        pub fn whiteout_m3_M3MaterialAddData_delete(self_: *mut whiteout_M3MaterialAddData);
26061        pub fn whiteout_m3_M3MaterialAddData_get_keyName(
26062            self_: *mut whiteout_M3MaterialAddData,
26063        ) -> RawCString;
26064        pub fn whiteout_m3_M3MaterialAddData_set_keyName(
26065            self_: *mut whiteout_M3MaterialAddData,
26066            value: *const core::ffi::c_char,
26067        );
26068        pub fn whiteout_m3_M3MaterialAddData_get_keyHash_count(
26069            self_: *mut whiteout_M3MaterialAddData,
26070        ) -> usize;
26071        pub fn whiteout_m3_M3MaterialAddData_resize_keyHash(
26072            self_: *mut whiteout_M3MaterialAddData,
26073            count: usize,
26074        );
26075        pub fn whiteout_m3_M3MaterialAddData_get_keyHash_data(
26076            self_: *mut whiteout_M3MaterialAddData,
26077        ) -> *const u32;
26078        pub fn whiteout_m3_M3MaterialAddData_assign_keyHash(
26079            self_: *mut whiteout_M3MaterialAddData,
26080            data: *const u32,
26081            count: usize,
26082        );
26083        pub fn whiteout_m3_M3MaterialAddData_get_extraHash_count(
26084            self_: *mut whiteout_M3MaterialAddData,
26085        ) -> usize;
26086        pub fn whiteout_m3_M3MaterialAddData_resize_extraHash(
26087            self_: *mut whiteout_M3MaterialAddData,
26088            count: usize,
26089        );
26090        pub fn whiteout_m3_M3MaterialAddData_get_extraHash_data(
26091            self_: *mut whiteout_M3MaterialAddData,
26092        ) -> *const u32;
26093        pub fn whiteout_m3_M3MaterialAddData_assign_extraHash(
26094            self_: *mut whiteout_M3MaterialAddData,
26095            data: *const u32,
26096            count: usize,
26097        );
26098        pub fn whiteout_m3_M3MaterialAddData_get_valuePath(
26099            self_: *mut whiteout_M3MaterialAddData,
26100        ) -> RawCString;
26101        pub fn whiteout_m3_M3MaterialAddData_set_valuePath(
26102            self_: *mut whiteout_M3MaterialAddData,
26103            value: *const core::ffi::c_char,
26104        );
26105        pub fn whiteout_m3_M3MaterialAddData_get_frequency(
26106            self_: *mut whiteout_M3MaterialAddData,
26107        ) -> f32;
26108        pub fn whiteout_m3_M3MaterialAddData_set_frequency(
26109            self_: *mut whiteout_M3MaterialAddData,
26110            value: f32,
26111        );
26112        pub fn whiteout_m3_M3MaterialAddData_get_intensity(
26113            self_: *mut whiteout_M3MaterialAddData,
26114        ) -> f32;
26115        pub fn whiteout_m3_M3MaterialAddData_set_intensity(
26116            self_: *mut whiteout_M3MaterialAddData,
26117            value: f32,
26118        );
26119        pub fn whiteout_m3_M3MaterialAddData_get_holdTime(
26120            self_: *mut whiteout_M3MaterialAddData,
26121        ) -> f32;
26122        pub fn whiteout_m3_M3MaterialAddData_set_holdTime(
26123            self_: *mut whiteout_M3MaterialAddData,
26124            value: f32,
26125        );
26126        pub fn whiteout_m3_M3MaterialAddData_get_randomHash(
26127            self_: *mut whiteout_M3MaterialAddData,
26128        ) -> u32;
26129        pub fn whiteout_m3_M3MaterialAddData_set_randomHash(
26130            self_: *mut whiteout_M3MaterialAddData,
26131            value: u32,
26132        );
26133        pub fn whiteout_m3_M3MaterialAddData_get_animationType(
26134            self_: *mut whiteout_M3MaterialAddData,
26135        ) -> u32;
26136        pub fn whiteout_m3_M3MaterialAddData_set_animationType(
26137            self_: *mut whiteout_M3MaterialAddData,
26138            value: u32,
26139        );
26140        pub fn whiteout_m3_M3MaterialAddData_get_padding0(
26141            self_: *mut whiteout_M3MaterialAddData,
26142        ) -> u32;
26143        pub fn whiteout_m3_M3MaterialAddData_set_padding0(
26144            self_: *mut whiteout_M3MaterialAddData,
26145            value: u32,
26146        );
26147        pub fn whiteout_m3_M3MaterialAddData_get_loopCount(
26148            self_: *mut whiteout_M3MaterialAddData,
26149        ) -> i32;
26150        pub fn whiteout_m3_M3MaterialAddData_set_loopCount(
26151            self_: *mut whiteout_M3MaterialAddData,
26152            value: i32,
26153        );
26154        pub fn whiteout_m3_M3MaterialAddData_get_flags(
26155            self_: *mut whiteout_M3MaterialAddData,
26156        ) -> u32;
26157        pub fn whiteout_m3_M3MaterialAddData_set_flags(
26158            self_: *mut whiteout_M3MaterialAddData,
26159            value: u32,
26160        );
26161        pub fn whiteout_m3_M3MaterialAddData_get_subType(
26162            self_: *mut whiteout_M3MaterialAddData,
26163        ) -> u32;
26164        pub fn whiteout_m3_M3MaterialAddData_set_subType(
26165            self_: *mut whiteout_M3MaterialAddData,
26166            value: u32,
26167        );
26168        pub fn whiteout_m3_M3MaterialAddData_get_configA(
26169            self_: *mut whiteout_M3MaterialAddData,
26170        ) -> u32;
26171        pub fn whiteout_m3_M3MaterialAddData_set_configA(
26172            self_: *mut whiteout_M3MaterialAddData,
26173            value: u32,
26174        );
26175        pub fn whiteout_m3_M3MaterialAddData_get_configB(
26176            self_: *mut whiteout_M3MaterialAddData,
26177        ) -> u32;
26178        pub fn whiteout_m3_M3MaterialAddData_set_configB(
26179            self_: *mut whiteout_M3MaterialAddData,
26180            value: u32,
26181        );
26182        pub fn whiteout_m3_M3MaterialAddData_get_extraId0(
26183            self_: *mut whiteout_M3MaterialAddData,
26184        ) -> u32;
26185        pub fn whiteout_m3_M3MaterialAddData_set_extraId0(
26186            self_: *mut whiteout_M3MaterialAddData,
26187            value: u32,
26188        );
26189        pub fn whiteout_m3_M3MaterialAddData_get_extraId1(
26190            self_: *mut whiteout_M3MaterialAddData,
26191        ) -> u32;
26192        pub fn whiteout_m3_M3MaterialAddData_set_extraId1(
26193            self_: *mut whiteout_M3MaterialAddData,
26194            value: u32,
26195        );
26196        // Bone
26197        pub fn whiteout_m3_M3Bone_new() -> *mut whiteout_M3Bone;
26198        pub fn whiteout_m3_M3Bone_delete(self_: *mut whiteout_M3Bone);
26199        pub fn whiteout_m3_M3Bone_get_unknown(self_: *mut whiteout_M3Bone) -> u32;
26200        pub fn whiteout_m3_M3Bone_set_unknown(self_: *mut whiteout_M3Bone, value: u32);
26201        pub fn whiteout_m3_M3Bone_get_name(self_: *mut whiteout_M3Bone) -> RawCString;
26202        pub fn whiteout_m3_M3Bone_set_name(
26203            self_: *mut whiteout_M3Bone,
26204            value: *const core::ffi::c_char,
26205        );
26206        pub fn whiteout_m3_M3Bone_get_flags(self_: *mut whiteout_M3Bone) -> i32;
26207        pub fn whiteout_m3_M3Bone_set_flags(self_: *mut whiteout_M3Bone, value: i32);
26208        pub fn whiteout_m3_M3Bone_get_parentIndex(self_: *mut whiteout_M3Bone) -> u16;
26209        pub fn whiteout_m3_M3Bone_set_parentIndex(self_: *mut whiteout_M3Bone, value: u16);
26210        pub fn whiteout_m3_M3Bone_get_padding(self_: *mut whiteout_M3Bone) -> u16;
26211        pub fn whiteout_m3_M3Bone_set_padding(self_: *mut whiteout_M3Bone, value: u16);
26212        pub fn whiteout_m3_M3Bone_get_position(
26213            self_: *mut whiteout_M3Bone,
26214        ) -> *mut whiteout_M3AnimRefVector3f;
26215        pub fn whiteout_m3_M3Bone_set_position(
26216            self_: *mut whiteout_M3Bone,
26217            value: *const whiteout_M3AnimRefVector3f,
26218        );
26219        pub fn whiteout_m3_M3Bone_get_rotation(
26220            self_: *mut whiteout_M3Bone,
26221        ) -> *mut whiteout_M3AnimRefQuaternion;
26222        pub fn whiteout_m3_M3Bone_set_rotation(
26223            self_: *mut whiteout_M3Bone,
26224            value: *const whiteout_M3AnimRefQuaternion,
26225        );
26226        pub fn whiteout_m3_M3Bone_get_scale(
26227            self_: *mut whiteout_M3Bone,
26228        ) -> *mut whiteout_M3AnimRefVector3f;
26229        pub fn whiteout_m3_M3Bone_set_scale(
26230            self_: *mut whiteout_M3Bone,
26231            value: *const whiteout_M3AnimRefVector3f,
26232        );
26233        pub fn whiteout_m3_M3Bone_get_visibility(
26234            self_: *mut whiteout_M3Bone,
26235        ) -> *mut whiteout_M3AnimRefU32;
26236        pub fn whiteout_m3_M3Bone_set_visibility(
26237            self_: *mut whiteout_M3Bone,
26238            value: *const whiteout_M3AnimRefU32,
26239        );
26240        // Region
26241        pub fn whiteout_m3_M3Region_new() -> *mut whiteout_M3Region;
26242        pub fn whiteout_m3_M3Region_delete(self_: *mut whiteout_M3Region);
26243        pub fn whiteout_m3_M3Region_get_index(self_: *mut whiteout_M3Region) -> u32;
26244        pub fn whiteout_m3_M3Region_set_index(self_: *mut whiteout_M3Region, value: u32);
26245        pub fn whiteout_m3_M3Region_get_unknown(self_: *mut whiteout_M3Region) -> u32;
26246        pub fn whiteout_m3_M3Region_set_unknown(self_: *mut whiteout_M3Region, value: u32);
26247        pub fn whiteout_m3_M3Region_get_firstVertex(self_: *mut whiteout_M3Region) -> u32;
26248        pub fn whiteout_m3_M3Region_set_firstVertex(self_: *mut whiteout_M3Region, value: u32);
26249        pub fn whiteout_m3_M3Region_get_vertexCount(self_: *mut whiteout_M3Region) -> u32;
26250        pub fn whiteout_m3_M3Region_set_vertexCount(self_: *mut whiteout_M3Region, value: u32);
26251        pub fn whiteout_m3_M3Region_get_firstIndex(self_: *mut whiteout_M3Region) -> u32;
26252        pub fn whiteout_m3_M3Region_set_firstIndex(self_: *mut whiteout_M3Region, value: u32);
26253        pub fn whiteout_m3_M3Region_get_indexCount(self_: *mut whiteout_M3Region) -> u32;
26254        pub fn whiteout_m3_M3Region_set_indexCount(self_: *mut whiteout_M3Region, value: u32);
26255        pub fn whiteout_m3_M3Region_get_unknown2(self_: *mut whiteout_M3Region) -> u16;
26256        pub fn whiteout_m3_M3Region_set_unknown2(self_: *mut whiteout_M3Region, value: u16);
26257        pub fn whiteout_m3_M3Region_get_firstBoneLookup(self_: *mut whiteout_M3Region) -> u16;
26258        pub fn whiteout_m3_M3Region_set_firstBoneLookup(self_: *mut whiteout_M3Region, value: u16);
26259        pub fn whiteout_m3_M3Region_get_boneLookupCount(self_: *mut whiteout_M3Region) -> u16;
26260        pub fn whiteout_m3_M3Region_set_boneLookupCount(self_: *mut whiteout_M3Region, value: u16);
26261        pub fn whiteout_m3_M3Region_get_padding(self_: *mut whiteout_M3Region) -> u16;
26262        pub fn whiteout_m3_M3Region_set_padding(self_: *mut whiteout_M3Region, value: u16);
26263        pub fn whiteout_m3_M3Region_get_boneWeightPairs(self_: *mut whiteout_M3Region) -> u8;
26264        pub fn whiteout_m3_M3Region_set_boneWeightPairs(self_: *mut whiteout_M3Region, value: u8);
26265        pub fn whiteout_m3_M3Region_get_boneIndexPairs(self_: *mut whiteout_M3Region) -> u8;
26266        pub fn whiteout_m3_M3Region_set_boneIndexPairs(self_: *mut whiteout_M3Region, value: u8);
26267        pub fn whiteout_m3_M3Region_get_rootBone(self_: *mut whiteout_M3Region) -> u16;
26268        pub fn whiteout_m3_M3Region_set_rootBone(self_: *mut whiteout_M3Region, value: u16);
26269        pub fn whiteout_m3_M3Region_get_flags(self_: *mut whiteout_M3Region) -> i32;
26270        pub fn whiteout_m3_M3Region_set_flags(self_: *mut whiteout_M3Region, value: i32);
26271        pub fn whiteout_m3_M3Region_get_uvScale(self_: *mut whiteout_M3Region) -> f32;
26272        pub fn whiteout_m3_M3Region_set_uvScale(self_: *mut whiteout_M3Region, value: f32);
26273        pub fn whiteout_m3_M3Region_get_uvOffset(self_: *mut whiteout_M3Region) -> f32;
26274        pub fn whiteout_m3_M3Region_set_uvOffset(self_: *mut whiteout_M3Region, value: f32);
26275        // Batch
26276        pub fn whiteout_m3_M3Batch_new() -> *mut whiteout_M3Batch;
26277        pub fn whiteout_m3_M3Batch_delete(self_: *mut whiteout_M3Batch);
26278        pub fn whiteout_m3_M3Batch_get_unknown(self_: *mut whiteout_M3Batch) -> u32;
26279        pub fn whiteout_m3_M3Batch_set_unknown(self_: *mut whiteout_M3Batch, value: u32);
26280        pub fn whiteout_m3_M3Batch_get_regionIndex(self_: *mut whiteout_M3Batch) -> u16;
26281        pub fn whiteout_m3_M3Batch_set_regionIndex(self_: *mut whiteout_M3Batch, value: u16);
26282        pub fn whiteout_m3_M3Batch_get_unknown2(self_: *mut whiteout_M3Batch) -> u32;
26283        pub fn whiteout_m3_M3Batch_set_unknown2(self_: *mut whiteout_M3Batch, value: u32);
26284        pub fn whiteout_m3_M3Batch_get_materialIndex(self_: *mut whiteout_M3Batch) -> u16;
26285        pub fn whiteout_m3_M3Batch_set_materialIndex(self_: *mut whiteout_M3Batch, value: u16);
26286        pub fn whiteout_m3_M3Batch_get_boneCount(self_: *mut whiteout_M3Batch) -> u16;
26287        pub fn whiteout_m3_M3Batch_set_boneCount(self_: *mut whiteout_M3Batch, value: u16);
26288        // MeshSection
26289        pub fn whiteout_m3_M3MeshSection_new() -> *mut whiteout_M3MeshSection;
26290        pub fn whiteout_m3_M3MeshSection_delete(self_: *mut whiteout_M3MeshSection);
26291        pub fn whiteout_m3_M3MeshSection_get_nodeIndex(self_: *mut whiteout_M3MeshSection) -> u32;
26292        pub fn whiteout_m3_M3MeshSection_set_nodeIndex(
26293            self_: *mut whiteout_M3MeshSection,
26294            value: u32,
26295        );
26296        pub fn whiteout_m3_M3MeshSection_get_bounds(
26297            self_: *mut whiteout_M3MeshSection,
26298        ) -> *mut whiteout_M3AnimRefM3Extent;
26299        pub fn whiteout_m3_M3MeshSection_set_bounds(
26300            self_: *mut whiteout_M3MeshSection,
26301            value: *const whiteout_M3AnimRefM3Extent,
26302        );
26303        // MeshDivision
26304        pub fn whiteout_m3_M3MeshDivision_new() -> *mut whiteout_M3MeshDivision;
26305        pub fn whiteout_m3_M3MeshDivision_delete(self_: *mut whiteout_M3MeshDivision);
26306        pub fn whiteout_m3_M3MeshDivision_get_faces_count(
26307            self_: *mut whiteout_M3MeshDivision,
26308        ) -> usize;
26309        pub fn whiteout_m3_M3MeshDivision_resize_faces(
26310            self_: *mut whiteout_M3MeshDivision,
26311            count: usize,
26312        );
26313        pub fn whiteout_m3_M3MeshDivision_get_faces_data(
26314            self_: *mut whiteout_M3MeshDivision,
26315        ) -> *const u16;
26316        pub fn whiteout_m3_M3MeshDivision_assign_faces(
26317            self_: *mut whiteout_M3MeshDivision,
26318            data: *const u16,
26319            count: usize,
26320        );
26321        pub fn whiteout_m3_M3MeshDivision_get_regions_count(
26322            self_: *mut whiteout_M3MeshDivision,
26323        ) -> usize;
26324        pub fn whiteout_m3_M3MeshDivision_resize_regions(
26325            self_: *mut whiteout_M3MeshDivision,
26326            count: usize,
26327        );
26328        pub fn whiteout_m3_M3MeshDivision_get_regions_at(
26329            self_: *mut whiteout_M3MeshDivision,
26330            index: usize,
26331        ) -> *mut whiteout_M3Region;
26332        pub fn whiteout_m3_M3MeshDivision_get_batches_count(
26333            self_: *mut whiteout_M3MeshDivision,
26334        ) -> usize;
26335        pub fn whiteout_m3_M3MeshDivision_resize_batches(
26336            self_: *mut whiteout_M3MeshDivision,
26337            count: usize,
26338        );
26339        pub fn whiteout_m3_M3MeshDivision_get_batches_at(
26340            self_: *mut whiteout_M3MeshDivision,
26341            index: usize,
26342        ) -> *mut whiteout_M3Batch;
26343        pub fn whiteout_m3_M3MeshDivision_get_msec_count(
26344            self_: *mut whiteout_M3MeshDivision,
26345        ) -> usize;
26346        pub fn whiteout_m3_M3MeshDivision_resize_msec(
26347            self_: *mut whiteout_M3MeshDivision,
26348            count: usize,
26349        );
26350        pub fn whiteout_m3_M3MeshDivision_get_msec_at(
26351            self_: *mut whiteout_M3MeshDivision,
26352            index: usize,
26353        ) -> *mut whiteout_M3MeshSection;
26354        pub fn whiteout_m3_M3MeshDivision_get_instances(self_: *mut whiteout_M3MeshDivision)
26355            -> u32;
26356        pub fn whiteout_m3_M3MeshDivision_set_instances(
26357            self_: *mut whiteout_M3MeshDivision,
26358            value: u32,
26359        );
26360        // InitialReference
26361        pub fn whiteout_m3_M3InitialReference_new() -> *mut whiteout_M3InitialReference;
26362        pub fn whiteout_m3_M3InitialReference_delete(self_: *mut whiteout_M3InitialReference);
26363        // AttachmentPoint
26364        pub fn whiteout_m3_M3AttachmentPoint_new() -> *mut whiteout_M3AttachmentPoint;
26365        pub fn whiteout_m3_M3AttachmentPoint_delete(self_: *mut whiteout_M3AttachmentPoint);
26366        pub fn whiteout_m3_M3AttachmentPoint_get_unknown(
26367            self_: *mut whiteout_M3AttachmentPoint,
26368        ) -> u32;
26369        pub fn whiteout_m3_M3AttachmentPoint_set_unknown(
26370            self_: *mut whiteout_M3AttachmentPoint,
26371            value: u32,
26372        );
26373        pub fn whiteout_m3_M3AttachmentPoint_get_name(
26374            self_: *mut whiteout_M3AttachmentPoint,
26375        ) -> RawCString;
26376        pub fn whiteout_m3_M3AttachmentPoint_set_name(
26377            self_: *mut whiteout_M3AttachmentPoint,
26378            value: *const core::ffi::c_char,
26379        );
26380        pub fn whiteout_m3_M3AttachmentPoint_get_boneIndex(
26381            self_: *mut whiteout_M3AttachmentPoint,
26382        ) -> u32;
26383        pub fn whiteout_m3_M3AttachmentPoint_set_boneIndex(
26384            self_: *mut whiteout_M3AttachmentPoint,
26385            value: u32,
26386        );
26387        // HitTestShape
26388        pub fn whiteout_m3_M3HitTestShape_new() -> *mut whiteout_M3HitTestShape;
26389        pub fn whiteout_m3_M3HitTestShape_delete(self_: *mut whiteout_M3HitTestShape);
26390        pub fn whiteout_m3_M3HitTestShape_get_shapeType(self_: *mut whiteout_M3HitTestShape)
26391            -> i32;
26392        pub fn whiteout_m3_M3HitTestShape_set_shapeType(
26393            self_: *mut whiteout_M3HitTestShape,
26394            value: i32,
26395        );
26396        pub fn whiteout_m3_M3HitTestShape_get_boneIndex(self_: *mut whiteout_M3HitTestShape)
26397            -> u16;
26398        pub fn whiteout_m3_M3HitTestShape_set_boneIndex(
26399            self_: *mut whiteout_M3HitTestShape,
26400            value: u16,
26401        );
26402        pub fn whiteout_m3_M3HitTestShape_get_padding(self_: *mut whiteout_M3HitTestShape) -> u16;
26403        pub fn whiteout_m3_M3HitTestShape_set_padding(
26404            self_: *mut whiteout_M3HitTestShape,
26405            value: u16,
26406        );
26407        pub fn whiteout_m3_M3HitTestShape_get_vertexPositions_count(
26408            self_: *mut whiteout_M3HitTestShape,
26409        ) -> usize;
26410        pub fn whiteout_m3_M3HitTestShape_resize_vertexPositions(
26411            self_: *mut whiteout_M3HitTestShape,
26412            count: usize,
26413        );
26414        pub fn whiteout_m3_M3HitTestShape_get_vertexPositions_data(
26415            self_: *mut whiteout_M3HitTestShape,
26416        ) -> *const f32;
26417        pub fn whiteout_m3_M3HitTestShape_assign_vertexPositions(
26418            self_: *mut whiteout_M3HitTestShape,
26419            data: *const f32,
26420            count: usize,
26421        );
26422        pub fn whiteout_m3_M3HitTestShape_get_faceIndices_count(
26423            self_: *mut whiteout_M3HitTestShape,
26424        ) -> usize;
26425        pub fn whiteout_m3_M3HitTestShape_resize_faceIndices(
26426            self_: *mut whiteout_M3HitTestShape,
26427            count: usize,
26428        );
26429        pub fn whiteout_m3_M3HitTestShape_get_faceIndices_data(
26430            self_: *mut whiteout_M3HitTestShape,
26431        ) -> *const u16;
26432        pub fn whiteout_m3_M3HitTestShape_assign_faceIndices(
26433            self_: *mut whiteout_M3HitTestShape,
26434            data: *const u16,
26435            count: usize,
26436        );
26437        pub fn whiteout_m3_M3HitTestShape_get_sizeX(self_: *mut whiteout_M3HitTestShape) -> f32;
26438        pub fn whiteout_m3_M3HitTestShape_set_sizeX(
26439            self_: *mut whiteout_M3HitTestShape,
26440            value: f32,
26441        );
26442        pub fn whiteout_m3_M3HitTestShape_get_sizeY(self_: *mut whiteout_M3HitTestShape) -> f32;
26443        pub fn whiteout_m3_M3HitTestShape_set_sizeY(
26444            self_: *mut whiteout_M3HitTestShape,
26445            value: f32,
26446        );
26447        pub fn whiteout_m3_M3HitTestShape_get_sizeZ(self_: *mut whiteout_M3HitTestShape) -> f32;
26448        pub fn whiteout_m3_M3HitTestShape_set_sizeZ(
26449            self_: *mut whiteout_M3HitTestShape,
26450            value: f32,
26451        );
26452        // AttachmentVolume
26453        pub fn whiteout_m3_M3AttachmentVolume_new() -> *mut whiteout_M3AttachmentVolume;
26454        pub fn whiteout_m3_M3AttachmentVolume_delete(self_: *mut whiteout_M3AttachmentVolume);
26455        pub fn whiteout_m3_M3AttachmentVolume_get_bone1(
26456            self_: *mut whiteout_M3AttachmentVolume,
26457        ) -> u32;
26458        pub fn whiteout_m3_M3AttachmentVolume_set_bone1(
26459            self_: *mut whiteout_M3AttachmentVolume,
26460            value: u32,
26461        );
26462        pub fn whiteout_m3_M3AttachmentVolume_get_bone2(
26463            self_: *mut whiteout_M3AttachmentVolume,
26464        ) -> u32;
26465        pub fn whiteout_m3_M3AttachmentVolume_set_bone2(
26466            self_: *mut whiteout_M3AttachmentVolume,
26467            value: u32,
26468        );
26469        pub fn whiteout_m3_M3AttachmentVolume_get_shapeType(
26470            self_: *mut whiteout_M3AttachmentVolume,
26471        ) -> i32;
26472        pub fn whiteout_m3_M3AttachmentVolume_set_shapeType(
26473            self_: *mut whiteout_M3AttachmentVolume,
26474            value: i32,
26475        );
26476        pub fn whiteout_m3_M3AttachmentVolume_get_boneIndex(
26477            self_: *mut whiteout_M3AttachmentVolume,
26478        ) -> u16;
26479        pub fn whiteout_m3_M3AttachmentVolume_set_boneIndex(
26480            self_: *mut whiteout_M3AttachmentVolume,
26481            value: u16,
26482        );
26483        pub fn whiteout_m3_M3AttachmentVolume_get_padding(
26484            self_: *mut whiteout_M3AttachmentVolume,
26485        ) -> u16;
26486        pub fn whiteout_m3_M3AttachmentVolume_set_padding(
26487            self_: *mut whiteout_M3AttachmentVolume,
26488            value: u16,
26489        );
26490        pub fn whiteout_m3_M3AttachmentVolume_get_vertexPositions_count(
26491            self_: *mut whiteout_M3AttachmentVolume,
26492        ) -> usize;
26493        pub fn whiteout_m3_M3AttachmentVolume_resize_vertexPositions(
26494            self_: *mut whiteout_M3AttachmentVolume,
26495            count: usize,
26496        );
26497        pub fn whiteout_m3_M3AttachmentVolume_get_vertexPositions_data(
26498            self_: *mut whiteout_M3AttachmentVolume,
26499        ) -> *const f32;
26500        pub fn whiteout_m3_M3AttachmentVolume_assign_vertexPositions(
26501            self_: *mut whiteout_M3AttachmentVolume,
26502            data: *const f32,
26503            count: usize,
26504        );
26505        pub fn whiteout_m3_M3AttachmentVolume_get_faceIndices_count(
26506            self_: *mut whiteout_M3AttachmentVolume,
26507        ) -> usize;
26508        pub fn whiteout_m3_M3AttachmentVolume_resize_faceIndices(
26509            self_: *mut whiteout_M3AttachmentVolume,
26510            count: usize,
26511        );
26512        pub fn whiteout_m3_M3AttachmentVolume_get_faceIndices_data(
26513            self_: *mut whiteout_M3AttachmentVolume,
26514        ) -> *const u16;
26515        pub fn whiteout_m3_M3AttachmentVolume_assign_faceIndices(
26516            self_: *mut whiteout_M3AttachmentVolume,
26517            data: *const u16,
26518            count: usize,
26519        );
26520        pub fn whiteout_m3_M3AttachmentVolume_get_sizeX(
26521            self_: *mut whiteout_M3AttachmentVolume,
26522        ) -> f32;
26523        pub fn whiteout_m3_M3AttachmentVolume_set_sizeX(
26524            self_: *mut whiteout_M3AttachmentVolume,
26525            value: f32,
26526        );
26527        pub fn whiteout_m3_M3AttachmentVolume_get_sizeY(
26528            self_: *mut whiteout_M3AttachmentVolume,
26529        ) -> f32;
26530        pub fn whiteout_m3_M3AttachmentVolume_set_sizeY(
26531            self_: *mut whiteout_M3AttachmentVolume,
26532            value: f32,
26533        );
26534        pub fn whiteout_m3_M3AttachmentVolume_get_sizeZ(
26535            self_: *mut whiteout_M3AttachmentVolume,
26536        ) -> f32;
26537        pub fn whiteout_m3_M3AttachmentVolume_set_sizeZ(
26538            self_: *mut whiteout_M3AttachmentVolume,
26539            value: f32,
26540        );
26541        // TriggerData
26542        pub fn whiteout_m3_M3TriggerData_new() -> *mut whiteout_M3TriggerData;
26543        pub fn whiteout_m3_M3TriggerData_delete(self_: *mut whiteout_M3TriggerData);
26544        pub fn whiteout_m3_M3TriggerData_get_dataIndices_count(
26545            self_: *mut whiteout_M3TriggerData,
26546        ) -> usize;
26547        pub fn whiteout_m3_M3TriggerData_resize_dataIndices(
26548            self_: *mut whiteout_M3TriggerData,
26549            count: usize,
26550        );
26551        pub fn whiteout_m3_M3TriggerData_get_dataIndices_data(
26552            self_: *mut whiteout_M3TriggerData,
26553        ) -> *const u32;
26554        pub fn whiteout_m3_M3TriggerData_assign_dataIndices(
26555            self_: *mut whiteout_M3TriggerData,
26556            data: *const u32,
26557            count: usize,
26558        );
26559        pub fn whiteout_m3_M3TriggerData_get_name(self_: *mut whiteout_M3TriggerData)
26560            -> RawCString;
26561        pub fn whiteout_m3_M3TriggerData_set_name(
26562            self_: *mut whiteout_M3TriggerData,
26563            value: *const core::ffi::c_char,
26564        );
26565        // TurretBehavior
26566        pub fn whiteout_m3_M3TurretBehavior_new() -> *mut whiteout_M3TurretBehavior;
26567        pub fn whiteout_m3_M3TurretBehavior_delete(self_: *mut whiteout_M3TurretBehavior);
26568        pub fn whiteout_m3_M3TurretBehavior_get_unknown1(
26569            self_: *mut whiteout_M3TurretBehavior,
26570        ) -> *mut core::ffi::c_void;
26571        pub fn whiteout_m3_M3TurretBehavior_set_unknown1(
26572            self_: *mut whiteout_M3TurretBehavior,
26573            value: *const core::ffi::c_void,
26574        );
26575        pub fn whiteout_m3_M3TurretBehavior_get_unknown2(
26576            self_: *mut whiteout_M3TurretBehavior,
26577        ) -> *mut core::ffi::c_void;
26578        pub fn whiteout_m3_M3TurretBehavior_set_unknown2(
26579            self_: *mut whiteout_M3TurretBehavior,
26580            value: *const core::ffi::c_void,
26581        );
26582        pub fn whiteout_m3_M3TurretBehavior_get_boneIndex(
26583            self_: *mut whiteout_M3TurretBehavior,
26584        ) -> u16;
26585        pub fn whiteout_m3_M3TurretBehavior_set_boneIndex(
26586            self_: *mut whiteout_M3TurretBehavior,
26587            value: u16,
26588        );
26589        pub fn whiteout_m3_M3TurretBehavior_get_useAsMainTurret(
26590            self_: *mut whiteout_M3TurretBehavior,
26591        ) -> u8;
26592        pub fn whiteout_m3_M3TurretBehavior_set_useAsMainTurret(
26593            self_: *mut whiteout_M3TurretBehavior,
26594            value: u8,
26595        );
26596        pub fn whiteout_m3_M3TurretBehavior_get_turretGroupId(
26597            self_: *mut whiteout_M3TurretBehavior,
26598        ) -> u8;
26599        pub fn whiteout_m3_M3TurretBehavior_set_turretGroupId(
26600            self_: *mut whiteout_M3TurretBehavior,
26601            value: u8,
26602        );
26603        pub fn whiteout_m3_M3TurretBehavior_get_yawLimited(
26604            self_: *mut whiteout_M3TurretBehavior,
26605        ) -> u32;
26606        pub fn whiteout_m3_M3TurretBehavior_set_yawLimited(
26607            self_: *mut whiteout_M3TurretBehavior,
26608            value: u32,
26609        );
26610        pub fn whiteout_m3_M3TurretBehavior_get_yawMin(
26611            self_: *mut whiteout_M3TurretBehavior,
26612        ) -> f32;
26613        pub fn whiteout_m3_M3TurretBehavior_set_yawMin(
26614            self_: *mut whiteout_M3TurretBehavior,
26615            value: f32,
26616        );
26617        pub fn whiteout_m3_M3TurretBehavior_get_yawMax(
26618            self_: *mut whiteout_M3TurretBehavior,
26619        ) -> f32;
26620        pub fn whiteout_m3_M3TurretBehavior_set_yawMax(
26621            self_: *mut whiteout_M3TurretBehavior,
26622            value: f32,
26623        );
26624        pub fn whiteout_m3_M3TurretBehavior_get_yawWeight(
26625            self_: *mut whiteout_M3TurretBehavior,
26626        ) -> f32;
26627        pub fn whiteout_m3_M3TurretBehavior_set_yawWeight(
26628            self_: *mut whiteout_M3TurretBehavior,
26629            value: f32,
26630        );
26631        pub fn whiteout_m3_M3TurretBehavior_get_pitchLimited(
26632            self_: *mut whiteout_M3TurretBehavior,
26633        ) -> u32;
26634        pub fn whiteout_m3_M3TurretBehavior_set_pitchLimited(
26635            self_: *mut whiteout_M3TurretBehavior,
26636            value: u32,
26637        );
26638        pub fn whiteout_m3_M3TurretBehavior_get_pitchMin(
26639            self_: *mut whiteout_M3TurretBehavior,
26640        ) -> f32;
26641        pub fn whiteout_m3_M3TurretBehavior_set_pitchMin(
26642            self_: *mut whiteout_M3TurretBehavior,
26643            value: f32,
26644        );
26645        pub fn whiteout_m3_M3TurretBehavior_get_pitchMax(
26646            self_: *mut whiteout_M3TurretBehavior,
26647        ) -> f32;
26648        pub fn whiteout_m3_M3TurretBehavior_set_pitchMax(
26649            self_: *mut whiteout_M3TurretBehavior,
26650            value: f32,
26651        );
26652        pub fn whiteout_m3_M3TurretBehavior_get_pitchWeight(
26653            self_: *mut whiteout_M3TurretBehavior,
26654        ) -> f32;
26655        pub fn whiteout_m3_M3TurretBehavior_set_pitchWeight(
26656            self_: *mut whiteout_M3TurretBehavior,
26657            value: f32,
26658        );
26659        pub fn whiteout_m3_M3TurretBehavior_get_unknown3(
26660            self_: *mut whiteout_M3TurretBehavior,
26661        ) -> f32;
26662        pub fn whiteout_m3_M3TurretBehavior_set_unknown3(
26663            self_: *mut whiteout_M3TurretBehavior,
26664            value: f32,
26665        );
26666        pub fn whiteout_m3_M3TurretBehavior_get_unknown4(
26667            self_: *mut whiteout_M3TurretBehavior,
26668        ) -> f32;
26669        pub fn whiteout_m3_M3TurretBehavior_set_unknown4(
26670            self_: *mut whiteout_M3TurretBehavior,
26671            value: f32,
26672        );
26673        pub fn whiteout_m3_M3TurretBehavior_get_mainBoneOffset(
26674            self_: *mut whiteout_M3TurretBehavior,
26675        ) -> *mut core::ffi::c_void;
26676        pub fn whiteout_m3_M3TurretBehavior_set_mainBoneOffset(
26677            self_: *mut whiteout_M3TurretBehavior,
26678            value: *const core::ffi::c_void,
26679        );
26680        // BillboardBehavior
26681        pub fn whiteout_m3_M3BillboardBehavior_new() -> *mut whiteout_M3BillboardBehavior;
26682        pub fn whiteout_m3_M3BillboardBehavior_delete(self_: *mut whiteout_M3BillboardBehavior);
26683        pub fn whiteout_m3_M3BillboardBehavior_get_dependents_count(
26684            self_: *mut whiteout_M3BillboardBehavior,
26685        ) -> usize;
26686        pub fn whiteout_m3_M3BillboardBehavior_resize_dependents(
26687            self_: *mut whiteout_M3BillboardBehavior,
26688            count: usize,
26689        );
26690        pub fn whiteout_m3_M3BillboardBehavior_get_dependents_data(
26691            self_: *mut whiteout_M3BillboardBehavior,
26692        ) -> *const u16;
26693        pub fn whiteout_m3_M3BillboardBehavior_assign_dependents(
26694            self_: *mut whiteout_M3BillboardBehavior,
26695            data: *const u16,
26696            count: usize,
26697        );
26698        pub fn whiteout_m3_M3BillboardBehavior_get_boneIndex(
26699            self_: *mut whiteout_M3BillboardBehavior,
26700        ) -> u16;
26701        pub fn whiteout_m3_M3BillboardBehavior_set_boneIndex(
26702            self_: *mut whiteout_M3BillboardBehavior,
26703            value: u16,
26704        );
26705        pub fn whiteout_m3_M3BillboardBehavior_get_billboardType(
26706            self_: *mut whiteout_M3BillboardBehavior,
26707        ) -> u8;
26708        pub fn whiteout_m3_M3BillboardBehavior_set_billboardType(
26709            self_: *mut whiteout_M3BillboardBehavior,
26710            value: u8,
26711        );
26712        pub fn whiteout_m3_M3BillboardBehavior_get_cameraLookAt(
26713            self_: *mut whiteout_M3BillboardBehavior,
26714        ) -> u8;
26715        pub fn whiteout_m3_M3BillboardBehavior_set_cameraLookAt(
26716            self_: *mut whiteout_M3BillboardBehavior,
26717            value: u8,
26718        );
26719        pub fn whiteout_m3_M3BillboardBehavior_get_up(
26720            self_: *mut whiteout_M3BillboardBehavior,
26721        ) -> *mut core::ffi::c_void;
26722        pub fn whiteout_m3_M3BillboardBehavior_set_up(
26723            self_: *mut whiteout_M3BillboardBehavior,
26724            value: *const core::ffi::c_void,
26725        );
26726        pub fn whiteout_m3_M3BillboardBehavior_get_forward(
26727            self_: *mut whiteout_M3BillboardBehavior,
26728        ) -> *mut core::ffi::c_void;
26729        pub fn whiteout_m3_M3BillboardBehavior_set_forward(
26730            self_: *mut whiteout_M3BillboardBehavior,
26731            value: *const core::ffi::c_void,
26732        );
26733        // IKJoint
26734        pub fn whiteout_m3_M3IKJoint_new() -> *mut whiteout_M3IKJoint;
26735        pub fn whiteout_m3_M3IKJoint_delete(self_: *mut whiteout_M3IKJoint);
26736        pub fn whiteout_m3_M3IKJoint_get_dependents_count(self_: *mut whiteout_M3IKJoint) -> usize;
26737        pub fn whiteout_m3_M3IKJoint_resize_dependents(
26738            self_: *mut whiteout_M3IKJoint,
26739            count: usize,
26740        );
26741        pub fn whiteout_m3_M3IKJoint_get_dependents_data(
26742            self_: *mut whiteout_M3IKJoint,
26743        ) -> *const u16;
26744        pub fn whiteout_m3_M3IKJoint_assign_dependents(
26745            self_: *mut whiteout_M3IKJoint,
26746            data: *const u16,
26747            count: usize,
26748        );
26749        pub fn whiteout_m3_M3IKJoint_get_boneIndex1(self_: *mut whiteout_M3IKJoint) -> u16;
26750        pub fn whiteout_m3_M3IKJoint_set_boneIndex1(self_: *mut whiteout_M3IKJoint, value: u16);
26751        pub fn whiteout_m3_M3IKJoint_get_boneIndex2(self_: *mut whiteout_M3IKJoint) -> u16;
26752        pub fn whiteout_m3_M3IKJoint_set_boneIndex2(self_: *mut whiteout_M3IKJoint, value: u16);
26753        pub fn whiteout_m3_M3IKJoint_get_raycastUp(self_: *mut whiteout_M3IKJoint) -> f32;
26754        pub fn whiteout_m3_M3IKJoint_set_raycastUp(self_: *mut whiteout_M3IKJoint, value: f32);
26755        pub fn whiteout_m3_M3IKJoint_get_raycastDown(self_: *mut whiteout_M3IKJoint) -> f32;
26756        pub fn whiteout_m3_M3IKJoint_set_raycastDown(self_: *mut whiteout_M3IKJoint, value: f32);
26757        pub fn whiteout_m3_M3IKJoint_get_maxSpeed(self_: *mut whiteout_M3IKJoint) -> f32;
26758        pub fn whiteout_m3_M3IKJoint_set_maxSpeed(self_: *mut whiteout_M3IKJoint, value: f32);
26759        pub fn whiteout_m3_M3IKJoint_get_goalThreshold(self_: *mut whiteout_M3IKJoint) -> f32;
26760        pub fn whiteout_m3_M3IKJoint_set_goalThreshold(self_: *mut whiteout_M3IKJoint, value: f32);
26761        // IKTwoJoint
26762        pub fn whiteout_m3_M3IKTwoJoint_new() -> *mut whiteout_M3IKTwoJoint;
26763        pub fn whiteout_m3_M3IKTwoJoint_delete(self_: *mut whiteout_M3IKTwoJoint);
26764        pub fn whiteout_m3_M3IKTwoJoint_get_dependents_count(
26765            self_: *mut whiteout_M3IKTwoJoint,
26766        ) -> usize;
26767        pub fn whiteout_m3_M3IKTwoJoint_resize_dependents(
26768            self_: *mut whiteout_M3IKTwoJoint,
26769            count: usize,
26770        );
26771        pub fn whiteout_m3_M3IKTwoJoint_get_dependents_data(
26772            self_: *mut whiteout_M3IKTwoJoint,
26773        ) -> *const u16;
26774        pub fn whiteout_m3_M3IKTwoJoint_assign_dependents(
26775            self_: *mut whiteout_M3IKTwoJoint,
26776            data: *const u16,
26777            count: usize,
26778        );
26779        pub fn whiteout_m3_M3IKTwoJoint_get_boneBase(self_: *mut whiteout_M3IKTwoJoint) -> u16;
26780        pub fn whiteout_m3_M3IKTwoJoint_set_boneBase(self_: *mut whiteout_M3IKTwoJoint, value: u16);
26781        pub fn whiteout_m3_M3IKTwoJoint_get_boneTarget(self_: *mut whiteout_M3IKTwoJoint) -> u16;
26782        pub fn whiteout_m3_M3IKTwoJoint_set_boneTarget(
26783            self_: *mut whiteout_M3IKTwoJoint,
26784            value: u16,
26785        );
26786        pub fn whiteout_m3_M3IKTwoJoint_get_boneEnd(self_: *mut whiteout_M3IKTwoJoint) -> u16;
26787        pub fn whiteout_m3_M3IKTwoJoint_set_boneEnd(self_: *mut whiteout_M3IKTwoJoint, value: u16);
26788        pub fn whiteout_m3_M3IKTwoJoint_get_padding(self_: *mut whiteout_M3IKTwoJoint) -> u16;
26789        pub fn whiteout_m3_M3IKTwoJoint_set_padding(self_: *mut whiteout_M3IKTwoJoint, value: u16);
26790        pub fn whiteout_m3_M3IKTwoJoint_get_hingeAxis(
26791            self_: *mut whiteout_M3IKTwoJoint,
26792        ) -> *mut core::ffi::c_void;
26793        pub fn whiteout_m3_M3IKTwoJoint_set_hingeAxis(
26794            self_: *mut whiteout_M3IKTwoJoint,
26795            value: *const core::ffi::c_void,
26796        );
26797        pub fn whiteout_m3_M3IKTwoJoint_get_maxAngleInner(self_: *mut whiteout_M3IKTwoJoint)
26798            -> f32;
26799        pub fn whiteout_m3_M3IKTwoJoint_set_maxAngleInner(
26800            self_: *mut whiteout_M3IKTwoJoint,
26801            value: f32,
26802        );
26803        pub fn whiteout_m3_M3IKTwoJoint_get_maxAngleOuter(self_: *mut whiteout_M3IKTwoJoint)
26804            -> f32;
26805        pub fn whiteout_m3_M3IKTwoJoint_set_maxAngleOuter(
26806            self_: *mut whiteout_M3IKTwoJoint,
26807            value: f32,
26808        );
26809        pub fn whiteout_m3_M3IKTwoJoint_get_searchUp(self_: *mut whiteout_M3IKTwoJoint) -> f32;
26810        pub fn whiteout_m3_M3IKTwoJoint_set_searchUp(self_: *mut whiteout_M3IKTwoJoint, value: f32);
26811        pub fn whiteout_m3_M3IKTwoJoint_get_searchDown(self_: *mut whiteout_M3IKTwoJoint) -> f32;
26812        pub fn whiteout_m3_M3IKTwoJoint_set_searchDown(
26813            self_: *mut whiteout_M3IKTwoJoint,
26814            value: f32,
26815        );
26816        // IKCCD
26817        pub fn whiteout_m3_M3IKCCD_new() -> *mut whiteout_M3IKCCD;
26818        pub fn whiteout_m3_M3IKCCD_delete(self_: *mut whiteout_M3IKCCD);
26819        pub fn whiteout_m3_M3IKCCD_get_dependents_count(self_: *mut whiteout_M3IKCCD) -> usize;
26820        pub fn whiteout_m3_M3IKCCD_resize_dependents(self_: *mut whiteout_M3IKCCD, count: usize);
26821        pub fn whiteout_m3_M3IKCCD_get_dependents_data(self_: *mut whiteout_M3IKCCD) -> *const u16;
26822        pub fn whiteout_m3_M3IKCCD_assign_dependents(
26823            self_: *mut whiteout_M3IKCCD,
26824            data: *const u16,
26825            count: usize,
26826        );
26827        pub fn whiteout_m3_M3IKCCD_get_boneBase(self_: *mut whiteout_M3IKCCD) -> u16;
26828        pub fn whiteout_m3_M3IKCCD_set_boneBase(self_: *mut whiteout_M3IKCCD, value: u16);
26829        pub fn whiteout_m3_M3IKCCD_get_boneTarget(self_: *mut whiteout_M3IKCCD) -> u16;
26830        pub fn whiteout_m3_M3IKCCD_set_boneTarget(self_: *mut whiteout_M3IKCCD, value: u16);
26831        pub fn whiteout_m3_M3IKCCD_get_searchUp(self_: *mut whiteout_M3IKCCD) -> f32;
26832        pub fn whiteout_m3_M3IKCCD_set_searchUp(self_: *mut whiteout_M3IKCCD, value: f32);
26833        pub fn whiteout_m3_M3IKCCD_get_searchDown(self_: *mut whiteout_M3IKCCD) -> f32;
26834        pub fn whiteout_m3_M3IKCCD_set_searchDown(self_: *mut whiteout_M3IKCCD, value: f32);
26835        // OneBoneSolver
26836        pub fn whiteout_m3_M3OneBoneSolver_new() -> *mut whiteout_M3OneBoneSolver;
26837        pub fn whiteout_m3_M3OneBoneSolver_delete(self_: *mut whiteout_M3OneBoneSolver);
26838        pub fn whiteout_m3_M3OneBoneSolver_get_dependents_count(
26839            self_: *mut whiteout_M3OneBoneSolver,
26840        ) -> usize;
26841        pub fn whiteout_m3_M3OneBoneSolver_resize_dependents(
26842            self_: *mut whiteout_M3OneBoneSolver,
26843            count: usize,
26844        );
26845        pub fn whiteout_m3_M3OneBoneSolver_get_dependents_data(
26846            self_: *mut whiteout_M3OneBoneSolver,
26847        ) -> *const u16;
26848        pub fn whiteout_m3_M3OneBoneSolver_assign_dependents(
26849            self_: *mut whiteout_M3OneBoneSolver,
26850            data: *const u16,
26851            count: usize,
26852        );
26853        pub fn whiteout_m3_M3OneBoneSolver_get_bone(self_: *mut whiteout_M3OneBoneSolver) -> u16;
26854        pub fn whiteout_m3_M3OneBoneSolver_set_bone(
26855            self_: *mut whiteout_M3OneBoneSolver,
26856            value: u16,
26857        );
26858        pub fn whiteout_m3_M3OneBoneSolver_get_boneFallback(
26859            self_: *mut whiteout_M3OneBoneSolver,
26860        ) -> u16;
26861        pub fn whiteout_m3_M3OneBoneSolver_set_boneFallback(
26862            self_: *mut whiteout_M3OneBoneSolver,
26863            value: u16,
26864        );
26865        pub fn whiteout_m3_M3OneBoneSolver_get_maxAngle(
26866            self_: *mut whiteout_M3OneBoneSolver,
26867        ) -> f32;
26868        pub fn whiteout_m3_M3OneBoneSolver_set_maxAngle(
26869            self_: *mut whiteout_M3OneBoneSolver,
26870            value: f32,
26871        );
26872        // ShadowBox
26873        pub fn whiteout_m3_M3ShadowBox_new() -> *mut whiteout_M3ShadowBox;
26874        pub fn whiteout_m3_M3ShadowBox_delete(self_: *mut whiteout_M3ShadowBox);
26875        // ViewVolume
26876        pub fn whiteout_m3_M3ViewVolume_new() -> *mut whiteout_M3ViewVolume;
26877        pub fn whiteout_m3_M3ViewVolume_delete(self_: *mut whiteout_M3ViewVolume);
26878        pub fn whiteout_m3_M3ViewVolume_get_nodeIndex(self_: *mut whiteout_M3ViewVolume) -> u32;
26879        pub fn whiteout_m3_M3ViewVolume_set_nodeIndex(
26880            self_: *mut whiteout_M3ViewVolume,
26881            value: u32,
26882        );
26883        pub fn whiteout_m3_M3ViewVolume_get_size(
26884            self_: *mut whiteout_M3ViewVolume,
26885        ) -> *mut whiteout_M3AnimRefVector3f;
26886        pub fn whiteout_m3_M3ViewVolume_set_size(
26887            self_: *mut whiteout_M3ViewVolume,
26888            value: *const whiteout_M3AnimRefVector3f,
26889        );
26890        // TrailingModel
26891        pub fn whiteout_m3_M3TrailingModel_new() -> *mut whiteout_M3TrailingModel;
26892        pub fn whiteout_m3_M3TrailingModel_delete(self_: *mut whiteout_M3TrailingModel);
26893        pub fn whiteout_m3_M3TrailingModel_get_vectors_count(
26894            self_: *mut whiteout_M3TrailingModel,
26895        ) -> usize;
26896        pub fn whiteout_m3_M3TrailingModel_resize_vectors(
26897            self_: *mut whiteout_M3TrailingModel,
26898            count: usize,
26899        );
26900        pub fn whiteout_m3_M3TrailingModel_get_vectors_data(
26901            self_: *mut whiteout_M3TrailingModel,
26902        ) -> *const f32;
26903        pub fn whiteout_m3_M3TrailingModel_assign_vectors(
26904            self_: *mut whiteout_M3TrailingModel,
26905            data: *const f32,
26906            count: usize,
26907        );
26908        pub fn whiteout_m3_M3TrailingModel_get_param0(self_: *mut whiteout_M3TrailingModel) -> f32;
26909        pub fn whiteout_m3_M3TrailingModel_set_param0(
26910            self_: *mut whiteout_M3TrailingModel,
26911            value: f32,
26912        );
26913        pub fn whiteout_m3_M3TrailingModel_get_param1(self_: *mut whiteout_M3TrailingModel) -> f32;
26914        pub fn whiteout_m3_M3TrailingModel_set_param1(
26915            self_: *mut whiteout_M3TrailingModel,
26916            value: f32,
26917        );
26918        pub fn whiteout_m3_M3TrailingModel_get_animFloat0(
26919            self_: *mut whiteout_M3TrailingModel,
26920        ) -> *mut whiteout_M3AnimRefF32;
26921        pub fn whiteout_m3_M3TrailingModel_set_animFloat0(
26922            self_: *mut whiteout_M3TrailingModel,
26923            value: *const whiteout_M3AnimRefF32,
26924        );
26925        pub fn whiteout_m3_M3TrailingModel_get_animFloat1(
26926            self_: *mut whiteout_M3TrailingModel,
26927        ) -> *mut whiteout_M3AnimRefF32;
26928        pub fn whiteout_m3_M3TrailingModel_set_animFloat1(
26929            self_: *mut whiteout_M3TrailingModel,
26930            value: *const whiteout_M3AnimRefF32,
26931        );
26932        pub fn whiteout_m3_M3TrailingModel_get_flag(self_: *mut whiteout_M3TrailingModel) -> u32;
26933        pub fn whiteout_m3_M3TrailingModel_set_flag(
26934            self_: *mut whiteout_M3TrailingModel,
26935            value: u32,
26936        );
26937        pub fn whiteout_m3_M3TrailingModel_get_reserved0(
26938            self_: *mut whiteout_M3TrailingModel,
26939        ) -> u32;
26940        pub fn whiteout_m3_M3TrailingModel_set_reserved0(
26941            self_: *mut whiteout_M3TrailingModel,
26942            value: u32,
26943        );
26944        pub fn whiteout_m3_M3TrailingModel_get_reserved1(
26945            self_: *mut whiteout_M3TrailingModel,
26946        ) -> u32;
26947        pub fn whiteout_m3_M3TrailingModel_set_reserved1(
26948            self_: *mut whiteout_M3TrailingModel,
26949            value: u32,
26950        );
26951        // Force
26952        pub fn whiteout_m3_M3Force_new() -> *mut whiteout_M3Force;
26953        pub fn whiteout_m3_M3Force_delete(self_: *mut whiteout_M3Force);
26954        pub fn whiteout_m3_M3Force_get_forceType(self_: *mut whiteout_M3Force) -> i32;
26955        pub fn whiteout_m3_M3Force_set_forceType(self_: *mut whiteout_M3Force, value: i32);
26956        pub fn whiteout_m3_M3Force_get_forceShape(self_: *mut whiteout_M3Force) -> i32;
26957        pub fn whiteout_m3_M3Force_set_forceShape(self_: *mut whiteout_M3Force, value: i32);
26958        pub fn whiteout_m3_M3Force_get_unknown(self_: *mut whiteout_M3Force) -> u32;
26959        pub fn whiteout_m3_M3Force_set_unknown(self_: *mut whiteout_M3Force, value: u32);
26960        pub fn whiteout_m3_M3Force_get_boneIndex(self_: *mut whiteout_M3Force) -> u32;
26961        pub fn whiteout_m3_M3Force_set_boneIndex(self_: *mut whiteout_M3Force, value: u32);
26962        pub fn whiteout_m3_M3Force_get_flags(self_: *mut whiteout_M3Force) -> i32;
26963        pub fn whiteout_m3_M3Force_set_flags(self_: *mut whiteout_M3Force, value: i32);
26964        pub fn whiteout_m3_M3Force_get_localChannels(self_: *mut whiteout_M3Force) -> u32;
26965        pub fn whiteout_m3_M3Force_set_localChannels(self_: *mut whiteout_M3Force, value: u32);
26966        pub fn whiteout_m3_M3Force_get_strength(
26967            self_: *mut whiteout_M3Force,
26968        ) -> *mut whiteout_M3AnimRefF32;
26969        pub fn whiteout_m3_M3Force_set_strength(
26970            self_: *mut whiteout_M3Force,
26971            value: *const whiteout_M3AnimRefF32,
26972        );
26973        pub fn whiteout_m3_M3Force_get_width(
26974            self_: *mut whiteout_M3Force,
26975        ) -> *mut whiteout_M3AnimRefF32;
26976        pub fn whiteout_m3_M3Force_set_width(
26977            self_: *mut whiteout_M3Force,
26978            value: *const whiteout_M3AnimRefF32,
26979        );
26980        pub fn whiteout_m3_M3Force_get_height(
26981            self_: *mut whiteout_M3Force,
26982        ) -> *mut whiteout_M3AnimRefF32;
26983        pub fn whiteout_m3_M3Force_set_height(
26984            self_: *mut whiteout_M3Force,
26985            value: *const whiteout_M3AnimRefF32,
26986        );
26987        pub fn whiteout_m3_M3Force_get_length(
26988            self_: *mut whiteout_M3Force,
26989        ) -> *mut whiteout_M3AnimRefF32;
26990        pub fn whiteout_m3_M3Force_set_length(
26991            self_: *mut whiteout_M3Force,
26992            value: *const whiteout_M3AnimRefF32,
26993        );
26994        // Warp
26995        pub fn whiteout_m3_M3Warp_new() -> *mut whiteout_M3Warp;
26996        pub fn whiteout_m3_M3Warp_delete(self_: *mut whiteout_M3Warp);
26997        pub fn whiteout_m3_M3Warp_get_warpType(self_: *mut whiteout_M3Warp) -> u32;
26998        pub fn whiteout_m3_M3Warp_set_warpType(self_: *mut whiteout_M3Warp, value: u32);
26999        pub fn whiteout_m3_M3Warp_get_boneIndex(self_: *mut whiteout_M3Warp) -> u32;
27000        pub fn whiteout_m3_M3Warp_set_boneIndex(self_: *mut whiteout_M3Warp, value: u32);
27001        pub fn whiteout_m3_M3Warp_get_unknown(self_: *mut whiteout_M3Warp) -> u32;
27002        pub fn whiteout_m3_M3Warp_set_unknown(self_: *mut whiteout_M3Warp, value: u32);
27003        pub fn whiteout_m3_M3Warp_get_radius(
27004            self_: *mut whiteout_M3Warp,
27005        ) -> *mut whiteout_M3AnimRefF32;
27006        pub fn whiteout_m3_M3Warp_set_radius(
27007            self_: *mut whiteout_M3Warp,
27008            value: *const whiteout_M3AnimRefF32,
27009        );
27010        pub fn whiteout_m3_M3Warp_get_height(
27011            self_: *mut whiteout_M3Warp,
27012        ) -> *mut whiteout_M3AnimRefF32;
27013        pub fn whiteout_m3_M3Warp_set_height(
27014            self_: *mut whiteout_M3Warp,
27015            value: *const whiteout_M3AnimRefF32,
27016        );
27017        pub fn whiteout_m3_M3Warp_get_strength(
27018            self_: *mut whiteout_M3Warp,
27019        ) -> *mut whiteout_M3AnimRefF32;
27020        pub fn whiteout_m3_M3Warp_set_strength(
27021            self_: *mut whiteout_M3Warp,
27022            value: *const whiteout_M3AnimRefF32,
27023        );
27024        pub fn whiteout_m3_M3Warp_get_angular(
27025            self_: *mut whiteout_M3Warp,
27026        ) -> *mut whiteout_M3AnimRefF32;
27027        pub fn whiteout_m3_M3Warp_set_angular(
27028            self_: *mut whiteout_M3Warp,
27029            value: *const whiteout_M3AnimRefF32,
27030        );
27031        pub fn whiteout_m3_M3Warp_get_axial(
27032            self_: *mut whiteout_M3Warp,
27033        ) -> *mut whiteout_M3AnimRefF32;
27034        pub fn whiteout_m3_M3Warp_set_axial(
27035            self_: *mut whiteout_M3Warp,
27036            value: *const whiteout_M3AnimRefF32,
27037        );
27038        pub fn whiteout_m3_M3Warp_get_radial(
27039            self_: *mut whiteout_M3Warp,
27040        ) -> *mut whiteout_M3AnimRefF32;
27041        pub fn whiteout_m3_M3Warp_set_radial(
27042            self_: *mut whiteout_M3Warp,
27043            value: *const whiteout_M3AnimRefF32,
27044        );
27045        // ConvexHullHalfEdge
27046        pub fn whiteout_m3_M3ConvexHullHalfEdge_new() -> *mut whiteout_M3ConvexHullHalfEdge;
27047        pub fn whiteout_m3_M3ConvexHullHalfEdge_delete(self_: *mut whiteout_M3ConvexHullHalfEdge);
27048        pub fn whiteout_m3_M3ConvexHullHalfEdge_get_type(
27049            self_: *mut whiteout_M3ConvexHullHalfEdge,
27050        ) -> u8;
27051        pub fn whiteout_m3_M3ConvexHullHalfEdge_set_type(
27052            self_: *mut whiteout_M3ConvexHullHalfEdge,
27053            value: u8,
27054        );
27055        pub fn whiteout_m3_M3ConvexHullHalfEdge_get_faceIndex(
27056            self_: *mut whiteout_M3ConvexHullHalfEdge,
27057        ) -> u8;
27058        pub fn whiteout_m3_M3ConvexHullHalfEdge_set_faceIndex(
27059            self_: *mut whiteout_M3ConvexHullHalfEdge,
27060            value: u8,
27061        );
27062        pub fn whiteout_m3_M3ConvexHullHalfEdge_get_vertexIndex(
27063            self_: *mut whiteout_M3ConvexHullHalfEdge,
27064        ) -> u8;
27065        pub fn whiteout_m3_M3ConvexHullHalfEdge_set_vertexIndex(
27066            self_: *mut whiteout_M3ConvexHullHalfEdge,
27067            value: u8,
27068        );
27069        pub fn whiteout_m3_M3ConvexHullHalfEdge_get_nextAroundVertex(
27070            self_: *mut whiteout_M3ConvexHullHalfEdge,
27071        ) -> u8;
27072        pub fn whiteout_m3_M3ConvexHullHalfEdge_set_nextAroundVertex(
27073            self_: *mut whiteout_M3ConvexHullHalfEdge,
27074            value: u8,
27075        );
27076        // PhysicsMeshBvhNode
27077        pub fn whiteout_m3_M3PhysicsMeshBvhNode_new() -> *mut whiteout_M3PhysicsMeshBvhNode;
27078        pub fn whiteout_m3_M3PhysicsMeshBvhNode_delete(self_: *mut whiteout_M3PhysicsMeshBvhNode);
27079        // PhysicsMeshTriangle
27080        pub fn whiteout_m3_M3PhysicsMeshTriangle_new() -> *mut whiteout_M3PhysicsMeshTriangle;
27081        pub fn whiteout_m3_M3PhysicsMeshTriangle_delete(self_: *mut whiteout_M3PhysicsMeshTriangle);
27082        pub fn whiteout_m3_M3PhysicsMeshTriangle_get_vertexIndex0(
27083            self_: *mut whiteout_M3PhysicsMeshTriangle,
27084        ) -> u32;
27085        pub fn whiteout_m3_M3PhysicsMeshTriangle_set_vertexIndex0(
27086            self_: *mut whiteout_M3PhysicsMeshTriangle,
27087            value: u32,
27088        );
27089        pub fn whiteout_m3_M3PhysicsMeshTriangle_get_vertexIndex1(
27090            self_: *mut whiteout_M3PhysicsMeshTriangle,
27091        ) -> u32;
27092        pub fn whiteout_m3_M3PhysicsMeshTriangle_set_vertexIndex1(
27093            self_: *mut whiteout_M3PhysicsMeshTriangle,
27094            value: u32,
27095        );
27096        pub fn whiteout_m3_M3PhysicsMeshTriangle_get_vertexIndex2(
27097            self_: *mut whiteout_M3PhysicsMeshTriangle,
27098        ) -> u32;
27099        pub fn whiteout_m3_M3PhysicsMeshTriangle_set_vertexIndex2(
27100            self_: *mut whiteout_M3PhysicsMeshTriangle,
27101            value: u32,
27102        );
27103        pub fn whiteout_m3_M3PhysicsMeshTriangle_get_edgeIndex0(
27104            self_: *mut whiteout_M3PhysicsMeshTriangle,
27105        ) -> u32;
27106        pub fn whiteout_m3_M3PhysicsMeshTriangle_set_edgeIndex0(
27107            self_: *mut whiteout_M3PhysicsMeshTriangle,
27108            value: u32,
27109        );
27110        pub fn whiteout_m3_M3PhysicsMeshTriangle_get_edgeIndex1(
27111            self_: *mut whiteout_M3PhysicsMeshTriangle,
27112        ) -> u32;
27113        pub fn whiteout_m3_M3PhysicsMeshTriangle_set_edgeIndex1(
27114            self_: *mut whiteout_M3PhysicsMeshTriangle,
27115            value: u32,
27116        );
27117        pub fn whiteout_m3_M3PhysicsMeshTriangle_get_edgeIndex2(
27118            self_: *mut whiteout_M3PhysicsMeshTriangle,
27119        ) -> u32;
27120        pub fn whiteout_m3_M3PhysicsMeshTriangle_set_edgeIndex2(
27121            self_: *mut whiteout_M3PhysicsMeshTriangle,
27122            value: u32,
27123        );
27124        pub fn whiteout_m3_M3PhysicsMeshTriangle_get_reserved(
27125            self_: *mut whiteout_M3PhysicsMeshTriangle,
27126        ) -> u16;
27127        pub fn whiteout_m3_M3PhysicsMeshTriangle_set_reserved(
27128            self_: *mut whiteout_M3PhysicsMeshTriangle,
27129            value: u16,
27130        );
27131        pub fn whiteout_m3_M3PhysicsMeshTriangle_get_flags(
27132            self_: *mut whiteout_M3PhysicsMeshTriangle,
27133        ) -> u16;
27134        pub fn whiteout_m3_M3PhysicsMeshTriangle_set_flags(
27135            self_: *mut whiteout_M3PhysicsMeshTriangle,
27136            value: u16,
27137        );
27138        // PhysicsMeshEdge
27139        pub fn whiteout_m3_M3PhysicsMeshEdge_new() -> *mut whiteout_M3PhysicsMeshEdge;
27140        pub fn whiteout_m3_M3PhysicsMeshEdge_delete(self_: *mut whiteout_M3PhysicsMeshEdge);
27141        pub fn whiteout_m3_M3PhysicsMeshEdge_get_edgeType(
27142            self_: *mut whiteout_M3PhysicsMeshEdge,
27143        ) -> u32;
27144        pub fn whiteout_m3_M3PhysicsMeshEdge_set_edgeType(
27145            self_: *mut whiteout_M3PhysicsMeshEdge,
27146            value: u32,
27147        );
27148        pub fn whiteout_m3_M3PhysicsMeshEdge_get_vertexA(
27149            self_: *mut whiteout_M3PhysicsMeshEdge,
27150        ) -> u32;
27151        pub fn whiteout_m3_M3PhysicsMeshEdge_set_vertexA(
27152            self_: *mut whiteout_M3PhysicsMeshEdge,
27153            value: u32,
27154        );
27155        pub fn whiteout_m3_M3PhysicsMeshEdge_get_vertexB(
27156            self_: *mut whiteout_M3PhysicsMeshEdge,
27157        ) -> u32;
27158        pub fn whiteout_m3_M3PhysicsMeshEdge_set_vertexB(
27159            self_: *mut whiteout_M3PhysicsMeshEdge,
27160            value: u32,
27161        );
27162        pub fn whiteout_m3_M3PhysicsMeshEdge_get_faceA(
27163            self_: *mut whiteout_M3PhysicsMeshEdge,
27164        ) -> u32;
27165        pub fn whiteout_m3_M3PhysicsMeshEdge_set_faceA(
27166            self_: *mut whiteout_M3PhysicsMeshEdge,
27167            value: u32,
27168        );
27169        pub fn whiteout_m3_M3PhysicsMeshEdge_get_faceB(
27170            self_: *mut whiteout_M3PhysicsMeshEdge,
27171        ) -> u32;
27172        pub fn whiteout_m3_M3PhysicsMeshEdge_set_faceB(
27173            self_: *mut whiteout_M3PhysicsMeshEdge,
27174            value: u32,
27175        );
27176        // PhysicsShape
27177        pub fn whiteout_m3_M3PhysicsShape_new() -> *mut whiteout_M3PhysicsShape;
27178        pub fn whiteout_m3_M3PhysicsShape_delete(self_: *mut whiteout_M3PhysicsShape);
27179        pub fn whiteout_m3_M3PhysicsShape_get_collisionMargin(
27180            self_: *mut whiteout_M3PhysicsShape,
27181        ) -> f32;
27182        pub fn whiteout_m3_M3PhysicsShape_set_collisionMargin(
27183            self_: *mut whiteout_M3PhysicsShape,
27184            value: f32,
27185        );
27186        pub fn whiteout_m3_M3PhysicsShape_get_shapeType(self_: *mut whiteout_M3PhysicsShape)
27187            -> i32;
27188        pub fn whiteout_m3_M3PhysicsShape_set_shapeType(
27189            self_: *mut whiteout_M3PhysicsShape,
27190            value: i32,
27191        );
27192        pub fn whiteout_m3_M3PhysicsShape_get_oldSizes(
27193            self_: *mut whiteout_M3PhysicsShape,
27194        ) -> *mut core::ffi::c_void;
27195        pub fn whiteout_m3_M3PhysicsShape_set_oldSizes(
27196            self_: *mut whiteout_M3PhysicsShape,
27197            value: *const core::ffi::c_void,
27198        );
27199        pub fn whiteout_m3_M3PhysicsShape_get_shapeDimensions(
27200            self_: *mut whiteout_M3PhysicsShape,
27201        ) -> *mut core::ffi::c_void;
27202        pub fn whiteout_m3_M3PhysicsShape_set_shapeDimensions(
27203            self_: *mut whiteout_M3PhysicsShape,
27204            value: *const core::ffi::c_void,
27205        );
27206        pub fn whiteout_m3_M3PhysicsShape_get_hullFaceNormals_count(
27207            self_: *mut whiteout_M3PhysicsShape,
27208        ) -> usize;
27209        pub fn whiteout_m3_M3PhysicsShape_resize_hullFaceNormals(
27210            self_: *mut whiteout_M3PhysicsShape,
27211            count: usize,
27212        );
27213        pub fn whiteout_m3_M3PhysicsShape_get_hullFaceNormals_data(
27214            self_: *mut whiteout_M3PhysicsShape,
27215        ) -> *const f32;
27216        pub fn whiteout_m3_M3PhysicsShape_assign_hullFaceNormals(
27217            self_: *mut whiteout_M3PhysicsShape,
27218            data: *const f32,
27219            count: usize,
27220        );
27221        pub fn whiteout_m3_M3PhysicsShape_get_hullVertexPositions_count(
27222            self_: *mut whiteout_M3PhysicsShape,
27223        ) -> usize;
27224        pub fn whiteout_m3_M3PhysicsShape_resize_hullVertexPositions(
27225            self_: *mut whiteout_M3PhysicsShape,
27226            count: usize,
27227        );
27228        pub fn whiteout_m3_M3PhysicsShape_get_hullVertexPositions_data(
27229            self_: *mut whiteout_M3PhysicsShape,
27230        ) -> *const f32;
27231        pub fn whiteout_m3_M3PhysicsShape_assign_hullVertexPositions(
27232            self_: *mut whiteout_M3PhysicsShape,
27233            data: *const f32,
27234            count: usize,
27235        );
27236        pub fn whiteout_m3_M3PhysicsShape_get_hullHalfEdges_count(
27237            self_: *mut whiteout_M3PhysicsShape,
27238        ) -> usize;
27239        pub fn whiteout_m3_M3PhysicsShape_resize_hullHalfEdges(
27240            self_: *mut whiteout_M3PhysicsShape,
27241            count: usize,
27242        );
27243        pub fn whiteout_m3_M3PhysicsShape_get_hullHalfEdges_at(
27244            self_: *mut whiteout_M3PhysicsShape,
27245            index: usize,
27246        ) -> *mut whiteout_M3ConvexHullHalfEdge;
27247        pub fn whiteout_m3_M3PhysicsShape_get_hullVertexFaceIndices_count(
27248            self_: *mut whiteout_M3PhysicsShape,
27249        ) -> usize;
27250        pub fn whiteout_m3_M3PhysicsShape_resize_hullVertexFaceIndices(
27251            self_: *mut whiteout_M3PhysicsShape,
27252            count: usize,
27253        );
27254        pub fn whiteout_m3_M3PhysicsShape_get_hullVertexFaceIndices_data(
27255            self_: *mut whiteout_M3PhysicsShape,
27256        ) -> *const u8;
27257        pub fn whiteout_m3_M3PhysicsShape_assign_hullVertexFaceIndices(
27258            self_: *mut whiteout_M3PhysicsShape,
27259            data: *const u8,
27260            count: usize,
27261        );
27262        pub fn whiteout_m3_M3PhysicsShape_get_hullCenter(
27263            self_: *mut whiteout_M3PhysicsShape,
27264        ) -> *mut core::ffi::c_void;
27265        pub fn whiteout_m3_M3PhysicsShape_set_hullCenter(
27266            self_: *mut whiteout_M3PhysicsShape,
27267            value: *const core::ffi::c_void,
27268        );
27269        pub fn whiteout_m3_M3PhysicsShape_get_hullFaceNormalCount(
27270            self_: *mut whiteout_M3PhysicsShape,
27271        ) -> u32;
27272        pub fn whiteout_m3_M3PhysicsShape_set_hullFaceNormalCount(
27273            self_: *mut whiteout_M3PhysicsShape,
27274            value: u32,
27275        );
27276        pub fn whiteout_m3_M3PhysicsShape_get_hullVertexCount(
27277            self_: *mut whiteout_M3PhysicsShape,
27278        ) -> u32;
27279        pub fn whiteout_m3_M3PhysicsShape_set_hullVertexCount(
27280            self_: *mut whiteout_M3PhysicsShape,
27281            value: u32,
27282        );
27283        pub fn whiteout_m3_M3PhysicsShape_get_hullHalfEdgeCount(
27284            self_: *mut whiteout_M3PhysicsShape,
27285        ) -> u32;
27286        pub fn whiteout_m3_M3PhysicsShape_set_hullHalfEdgeCount(
27287            self_: *mut whiteout_M3PhysicsShape,
27288            value: u32,
27289        );
27290        pub fn whiteout_m3_M3PhysicsShape_get_hullUnknown0(
27291            self_: *mut whiteout_M3PhysicsShape,
27292        ) -> f32;
27293        pub fn whiteout_m3_M3PhysicsShape_set_hullUnknown0(
27294            self_: *mut whiteout_M3PhysicsShape,
27295            value: f32,
27296        );
27297        pub fn whiteout_m3_M3PhysicsShape_get_hullUnknown1(
27298            self_: *mut whiteout_M3PhysicsShape,
27299        ) -> f32;
27300        pub fn whiteout_m3_M3PhysicsShape_set_hullUnknown1(
27301            self_: *mut whiteout_M3PhysicsShape,
27302            value: f32,
27303        );
27304        pub fn whiteout_m3_M3PhysicsShape_get_meshBvhNodes_count(
27305            self_: *mut whiteout_M3PhysicsShape,
27306        ) -> usize;
27307        pub fn whiteout_m3_M3PhysicsShape_resize_meshBvhNodes(
27308            self_: *mut whiteout_M3PhysicsShape,
27309            count: usize,
27310        );
27311        pub fn whiteout_m3_M3PhysicsShape_get_meshBvhNodes_at(
27312            self_: *mut whiteout_M3PhysicsShape,
27313            index: usize,
27314        ) -> *mut whiteout_M3PhysicsMeshBvhNode;
27315        pub fn whiteout_m3_M3PhysicsShape_get_meshVertexPositions_count(
27316            self_: *mut whiteout_M3PhysicsShape,
27317        ) -> usize;
27318        pub fn whiteout_m3_M3PhysicsShape_resize_meshVertexPositions(
27319            self_: *mut whiteout_M3PhysicsShape,
27320            count: usize,
27321        );
27322        pub fn whiteout_m3_M3PhysicsShape_get_meshVertexPositions_data(
27323            self_: *mut whiteout_M3PhysicsShape,
27324        ) -> *const f32;
27325        pub fn whiteout_m3_M3PhysicsShape_assign_meshVertexPositions(
27326            self_: *mut whiteout_M3PhysicsShape,
27327            data: *const f32,
27328            count: usize,
27329        );
27330        pub fn whiteout_m3_M3PhysicsShape_get_meshBoundsCenter(
27331            self_: *mut whiteout_M3PhysicsShape,
27332        ) -> *mut core::ffi::c_void;
27333        pub fn whiteout_m3_M3PhysicsShape_set_meshBoundsCenter(
27334            self_: *mut whiteout_M3PhysicsShape,
27335            value: *const core::ffi::c_void,
27336        );
27337        pub fn whiteout_m3_M3PhysicsShape_get_meshBoundsExtent(
27338            self_: *mut whiteout_M3PhysicsShape,
27339        ) -> *mut core::ffi::c_void;
27340        pub fn whiteout_m3_M3PhysicsShape_set_meshBoundsExtent(
27341            self_: *mut whiteout_M3PhysicsShape,
27342            value: *const core::ffi::c_void,
27343        );
27344        pub fn whiteout_m3_M3PhysicsShape_get_meshTolerance(
27345            self_: *mut whiteout_M3PhysicsShape,
27346        ) -> *mut core::ffi::c_void;
27347        pub fn whiteout_m3_M3PhysicsShape_set_meshTolerance(
27348            self_: *mut whiteout_M3PhysicsShape,
27349            value: *const core::ffi::c_void,
27350        );
27351        pub fn whiteout_m3_M3PhysicsShape_get_meshNormalCount(
27352            self_: *mut whiteout_M3PhysicsShape,
27353        ) -> u32;
27354        pub fn whiteout_m3_M3PhysicsShape_set_meshNormalCount(
27355            self_: *mut whiteout_M3PhysicsShape,
27356            value: u32,
27357        );
27358        pub fn whiteout_m3_M3PhysicsShape_get_meshVertexCount(
27359            self_: *mut whiteout_M3PhysicsShape,
27360        ) -> u32;
27361        pub fn whiteout_m3_M3PhysicsShape_set_meshVertexCount(
27362            self_: *mut whiteout_M3PhysicsShape,
27363            value: u32,
27364        );
27365        pub fn whiteout_m3_M3PhysicsShape_get_meshFaceIndex16Count(
27366            self_: *mut whiteout_M3PhysicsShape,
27367        ) -> u32;
27368        pub fn whiteout_m3_M3PhysicsShape_set_meshFaceIndex16Count(
27369            self_: *mut whiteout_M3PhysicsShape,
27370            value: u32,
27371        );
27372        pub fn whiteout_m3_M3PhysicsShape_get_meshFaceIndex32Count(
27373            self_: *mut whiteout_M3PhysicsShape,
27374        ) -> u32;
27375        pub fn whiteout_m3_M3PhysicsShape_set_meshFaceIndex32Count(
27376            self_: *mut whiteout_M3PhysicsShape,
27377            value: u32,
27378        );
27379        pub fn whiteout_m3_M3PhysicsShape_get_meshUnknown1(
27380            self_: *mut whiteout_M3PhysicsShape,
27381        ) -> u32;
27382        pub fn whiteout_m3_M3PhysicsShape_set_meshUnknown1(
27383            self_: *mut whiteout_M3PhysicsShape,
27384            value: u32,
27385        );
27386        pub fn whiteout_m3_M3PhysicsShape_get_meshReserved(
27387            self_: *mut whiteout_M3PhysicsShape,
27388        ) -> u32;
27389        pub fn whiteout_m3_M3PhysicsShape_set_meshReserved(
27390            self_: *mut whiteout_M3PhysicsShape,
27391            value: u32,
27392        );
27393        pub fn whiteout_m3_M3PhysicsShape_get_meshTreeDepth(
27394            self_: *mut whiteout_M3PhysicsShape,
27395        ) -> u32;
27396        pub fn whiteout_m3_M3PhysicsShape_set_meshTreeDepth(
27397            self_: *mut whiteout_M3PhysicsShape,
27398            value: u32,
27399        );
27400        pub fn whiteout_m3_M3PhysicsShape_get_meshCollisionMargin(
27401            self_: *mut whiteout_M3PhysicsShape,
27402        ) -> f32;
27403        pub fn whiteout_m3_M3PhysicsShape_set_meshCollisionMargin(
27404            self_: *mut whiteout_M3PhysicsShape,
27405            value: f32,
27406        );
27407        // RigidBody
27408        pub fn whiteout_m3_M3RigidBody_new() -> *mut whiteout_M3RigidBody;
27409        pub fn whiteout_m3_M3RigidBody_delete(self_: *mut whiteout_M3RigidBody);
27410        pub fn whiteout_m3_M3RigidBody_get_simulationType(self_: *mut whiteout_M3RigidBody) -> u16;
27411        pub fn whiteout_m3_M3RigidBody_set_simulationType(
27412            self_: *mut whiteout_M3RigidBody,
27413            value: u16,
27414        );
27415        pub fn whiteout_m3_M3RigidBody_get_parentBoneIndex(self_: *mut whiteout_M3RigidBody)
27416            -> u16;
27417        pub fn whiteout_m3_M3RigidBody_set_parentBoneIndex(
27418            self_: *mut whiteout_M3RigidBody,
27419            value: u16,
27420        );
27421        pub fn whiteout_m3_M3RigidBody_get_physicsType(self_: *mut whiteout_M3RigidBody) -> u32;
27422        pub fn whiteout_m3_M3RigidBody_set_physicsType(
27423            self_: *mut whiteout_M3RigidBody,
27424            value: u32,
27425        );
27426        pub fn whiteout_m3_M3RigidBody_get_density(self_: *mut whiteout_M3RigidBody) -> f32;
27427        pub fn whiteout_m3_M3RigidBody_set_density(self_: *mut whiteout_M3RigidBody, value: f32);
27428        pub fn whiteout_m3_M3RigidBody_get_friction(self_: *mut whiteout_M3RigidBody) -> f32;
27429        pub fn whiteout_m3_M3RigidBody_set_friction(self_: *mut whiteout_M3RigidBody, value: f32);
27430        pub fn whiteout_m3_M3RigidBody_get_restitution(self_: *mut whiteout_M3RigidBody) -> f32;
27431        pub fn whiteout_m3_M3RigidBody_set_restitution(
27432            self_: *mut whiteout_M3RigidBody,
27433            value: f32,
27434        );
27435        pub fn whiteout_m3_M3RigidBody_get_linearDamping(self_: *mut whiteout_M3RigidBody) -> f32;
27436        pub fn whiteout_m3_M3RigidBody_set_linearDamping(
27437            self_: *mut whiteout_M3RigidBody,
27438            value: f32,
27439        );
27440        pub fn whiteout_m3_M3RigidBody_get_angularDamping(self_: *mut whiteout_M3RigidBody) -> f32;
27441        pub fn whiteout_m3_M3RigidBody_set_angularDamping(
27442            self_: *mut whiteout_M3RigidBody,
27443            value: f32,
27444        );
27445        pub fn whiteout_m3_M3RigidBody_get_gravityScale(self_: *mut whiteout_M3RigidBody) -> f32;
27446        pub fn whiteout_m3_M3RigidBody_set_gravityScale(
27447            self_: *mut whiteout_M3RigidBody,
27448            value: f32,
27449        );
27450        pub fn whiteout_m3_M3RigidBody_get_dynamicState(
27451            self_: *mut whiteout_M3RigidBody,
27452        ) -> *mut whiteout_M3AnimRefU32;
27453        pub fn whiteout_m3_M3RigidBody_set_dynamicState(
27454            self_: *mut whiteout_M3RigidBody,
27455            value: *const whiteout_M3AnimRefU32,
27456        );
27457        pub fn whiteout_m3_M3RigidBody_get_dynamicBlendOut(self_: *mut whiteout_M3RigidBody)
27458            -> f32;
27459        pub fn whiteout_m3_M3RigidBody_set_dynamicBlendOut(
27460            self_: *mut whiteout_M3RigidBody,
27461            value: f32,
27462        );
27463        pub fn whiteout_m3_M3RigidBody_get_rigidBodyShape_count(
27464            self_: *mut whiteout_M3RigidBody,
27465        ) -> usize;
27466        pub fn whiteout_m3_M3RigidBody_resize_rigidBodyShape(
27467            self_: *mut whiteout_M3RigidBody,
27468            count: usize,
27469        );
27470        pub fn whiteout_m3_M3RigidBody_get_rigidBodyShape_at(
27471            self_: *mut whiteout_M3RigidBody,
27472            index: usize,
27473        ) -> *mut whiteout_M3PhysicsShape;
27474        pub fn whiteout_m3_M3RigidBody_get_flags(self_: *mut whiteout_M3RigidBody) -> i32;
27475        pub fn whiteout_m3_M3RigidBody_set_flags(self_: *mut whiteout_M3RigidBody, value: i32);
27476        pub fn whiteout_m3_M3RigidBody_get_localForces(self_: *mut whiteout_M3RigidBody) -> u16;
27477        pub fn whiteout_m3_M3RigidBody_set_localForces(
27478            self_: *mut whiteout_M3RigidBody,
27479            value: u16,
27480        );
27481        pub fn whiteout_m3_M3RigidBody_get_worldForces(self_: *mut whiteout_M3RigidBody) -> u16;
27482        pub fn whiteout_m3_M3RigidBody_set_worldForces(
27483            self_: *mut whiteout_M3RigidBody,
27484            value: u16,
27485        );
27486        pub fn whiteout_m3_M3RigidBody_get_priority(self_: *mut whiteout_M3RigidBody) -> u32;
27487        pub fn whiteout_m3_M3RigidBody_set_priority(self_: *mut whiteout_M3RigidBody, value: u32);
27488        // PhysicsJoint
27489        pub fn whiteout_m3_M3PhysicsJoint_new() -> *mut whiteout_M3PhysicsJoint;
27490        pub fn whiteout_m3_M3PhysicsJoint_delete(self_: *mut whiteout_M3PhysicsJoint);
27491        pub fn whiteout_m3_M3PhysicsJoint_get_jointType(self_: *mut whiteout_M3PhysicsJoint)
27492            -> u32;
27493        pub fn whiteout_m3_M3PhysicsJoint_set_jointType(
27494            self_: *mut whiteout_M3PhysicsJoint,
27495            value: u32,
27496        );
27497        pub fn whiteout_m3_M3PhysicsJoint_get_boneIndex1(
27498            self_: *mut whiteout_M3PhysicsJoint,
27499        ) -> u32;
27500        pub fn whiteout_m3_M3PhysicsJoint_set_boneIndex1(
27501            self_: *mut whiteout_M3PhysicsJoint,
27502            value: u32,
27503        );
27504        pub fn whiteout_m3_M3PhysicsJoint_get_boneIndex2(
27505            self_: *mut whiteout_M3PhysicsJoint,
27506        ) -> u32;
27507        pub fn whiteout_m3_M3PhysicsJoint_set_boneIndex2(
27508            self_: *mut whiteout_M3PhysicsJoint,
27509            value: u32,
27510        );
27511        pub fn whiteout_m3_M3PhysicsJoint_get_enableLimits(
27512            self_: *mut whiteout_M3PhysicsJoint,
27513        ) -> u32;
27514        pub fn whiteout_m3_M3PhysicsJoint_set_enableLimits(
27515            self_: *mut whiteout_M3PhysicsJoint,
27516            value: u32,
27517        );
27518        pub fn whiteout_m3_M3PhysicsJoint_get_limitMin(self_: *mut whiteout_M3PhysicsJoint) -> f32;
27519        pub fn whiteout_m3_M3PhysicsJoint_set_limitMin(
27520            self_: *mut whiteout_M3PhysicsJoint,
27521            value: f32,
27522        );
27523        pub fn whiteout_m3_M3PhysicsJoint_get_limitMax(self_: *mut whiteout_M3PhysicsJoint) -> f32;
27524        pub fn whiteout_m3_M3PhysicsJoint_set_limitMax(
27525            self_: *mut whiteout_M3PhysicsJoint,
27526            value: f32,
27527        );
27528        pub fn whiteout_m3_M3PhysicsJoint_get_coneAngle(self_: *mut whiteout_M3PhysicsJoint)
27529            -> f32;
27530        pub fn whiteout_m3_M3PhysicsJoint_set_coneAngle(
27531            self_: *mut whiteout_M3PhysicsJoint,
27532            value: f32,
27533        );
27534        pub fn whiteout_m3_M3PhysicsJoint_get_enableFriction(
27535            self_: *mut whiteout_M3PhysicsJoint,
27536        ) -> u32;
27537        pub fn whiteout_m3_M3PhysicsJoint_set_enableFriction(
27538            self_: *mut whiteout_M3PhysicsJoint,
27539            value: u32,
27540        );
27541        pub fn whiteout_m3_M3PhysicsJoint_get_friction(self_: *mut whiteout_M3PhysicsJoint) -> f32;
27542        pub fn whiteout_m3_M3PhysicsJoint_set_friction(
27543            self_: *mut whiteout_M3PhysicsJoint,
27544            value: f32,
27545        );
27546        pub fn whiteout_m3_M3PhysicsJoint_get_dampingRatio(
27547            self_: *mut whiteout_M3PhysicsJoint,
27548        ) -> f32;
27549        pub fn whiteout_m3_M3PhysicsJoint_set_dampingRatio(
27550            self_: *mut whiteout_M3PhysicsJoint,
27551            value: f32,
27552        );
27553        pub fn whiteout_m3_M3PhysicsJoint_get_angularFrequency(
27554            self_: *mut whiteout_M3PhysicsJoint,
27555        ) -> f32;
27556        pub fn whiteout_m3_M3PhysicsJoint_set_angularFrequency(
27557            self_: *mut whiteout_M3PhysicsJoint,
27558            value: f32,
27559        );
27560        pub fn whiteout_m3_M3PhysicsJoint_get_breakThreshold(
27561            self_: *mut whiteout_M3PhysicsJoint,
27562        ) -> f32;
27563        pub fn whiteout_m3_M3PhysicsJoint_set_breakThreshold(
27564            self_: *mut whiteout_M3PhysicsJoint,
27565            value: f32,
27566        );
27567        pub fn whiteout_m3_M3PhysicsJoint_get_enableShape(
27568            self_: *mut whiteout_M3PhysicsJoint,
27569        ) -> u8;
27570        pub fn whiteout_m3_M3PhysicsJoint_set_enableShape(
27571            self_: *mut whiteout_M3PhysicsJoint,
27572            value: u8,
27573        );
27574        // PhysicsConstraint
27575        pub fn whiteout_m3_M3PhysicsConstraint_new() -> *mut whiteout_M3PhysicsConstraint;
27576        pub fn whiteout_m3_M3PhysicsConstraint_delete(self_: *mut whiteout_M3PhysicsConstraint);
27577        pub fn whiteout_m3_M3PhysicsConstraint_get_dependents_count(
27578            self_: *mut whiteout_M3PhysicsConstraint,
27579        ) -> usize;
27580        pub fn whiteout_m3_M3PhysicsConstraint_resize_dependents(
27581            self_: *mut whiteout_M3PhysicsConstraint,
27582            count: usize,
27583        );
27584        pub fn whiteout_m3_M3PhysicsConstraint_get_dependents_data(
27585            self_: *mut whiteout_M3PhysicsConstraint,
27586        ) -> *const u16;
27587        pub fn whiteout_m3_M3PhysicsConstraint_assign_dependents(
27588            self_: *mut whiteout_M3PhysicsConstraint,
27589            data: *const u16,
27590            count: usize,
27591        );
27592        pub fn whiteout_m3_M3PhysicsConstraint_get_rigidBody1(
27593            self_: *mut whiteout_M3PhysicsConstraint,
27594        ) -> u16;
27595        pub fn whiteout_m3_M3PhysicsConstraint_set_rigidBody1(
27596            self_: *mut whiteout_M3PhysicsConstraint,
27597            value: u16,
27598        );
27599        pub fn whiteout_m3_M3PhysicsConstraint_get_rigidBody2(
27600            self_: *mut whiteout_M3PhysicsConstraint,
27601        ) -> u16;
27602        pub fn whiteout_m3_M3PhysicsConstraint_set_rigidBody2(
27603            self_: *mut whiteout_M3PhysicsConstraint,
27604            value: u16,
27605        );
27606        pub fn whiteout_m3_M3PhysicsConstraint_get_breakForce(
27607            self_: *mut whiteout_M3PhysicsConstraint,
27608        ) -> f32;
27609        pub fn whiteout_m3_M3PhysicsConstraint_set_breakForce(
27610            self_: *mut whiteout_M3PhysicsConstraint,
27611            value: f32,
27612        );
27613        // ClothCollider
27614        pub fn whiteout_m3_M3ClothCollider_new() -> *mut whiteout_M3ClothCollider;
27615        pub fn whiteout_m3_M3ClothCollider_delete(self_: *mut whiteout_M3ClothCollider);
27616        pub fn whiteout_m3_M3ClothCollider_get_radius(self_: *mut whiteout_M3ClothCollider) -> f32;
27617        pub fn whiteout_m3_M3ClothCollider_set_radius(
27618            self_: *mut whiteout_M3ClothCollider,
27619            value: f32,
27620        );
27621        pub fn whiteout_m3_M3ClothCollider_get_height(self_: *mut whiteout_M3ClothCollider) -> f32;
27622        pub fn whiteout_m3_M3ClothCollider_set_height(
27623            self_: *mut whiteout_M3ClothCollider,
27624            value: f32,
27625        );
27626        pub fn whiteout_m3_M3ClothCollider_get_padding(self_: *mut whiteout_M3ClothCollider)
27627            -> u32;
27628        pub fn whiteout_m3_M3ClothCollider_set_padding(
27629            self_: *mut whiteout_M3ClothCollider,
27630            value: u32,
27631        );
27632        // ClothProxy
27633        pub fn whiteout_m3_M3ClothProxy_new() -> *mut whiteout_M3ClothProxy;
27634        pub fn whiteout_m3_M3ClothProxy_delete(self_: *mut whiteout_M3ClothProxy);
27635        pub fn whiteout_m3_M3ClothProxy_get_proxyIndex(self_: *mut whiteout_M3ClothProxy) -> u32;
27636        pub fn whiteout_m3_M3ClothProxy_set_proxyIndex(
27637            self_: *mut whiteout_M3ClothProxy,
27638            value: u32,
27639        );
27640        pub fn whiteout_m3_M3ClothProxy_get_clothIndex(self_: *mut whiteout_M3ClothProxy) -> u32;
27641        pub fn whiteout_m3_M3ClothProxy_set_clothIndex(
27642            self_: *mut whiteout_M3ClothProxy,
27643            value: u32,
27644        );
27645        pub fn whiteout_m3_M3ClothProxy_get_proxyVertices_count(
27646            self_: *mut whiteout_M3ClothProxy,
27647        ) -> usize;
27648        pub fn whiteout_m3_M3ClothProxy_resize_proxyVertices(
27649            self_: *mut whiteout_M3ClothProxy,
27650            count: usize,
27651        );
27652        pub fn whiteout_m3_M3ClothProxy_get_proxyVertices_data(
27653            self_: *mut whiteout_M3ClothProxy,
27654        ) -> *const u64;
27655        pub fn whiteout_m3_M3ClothProxy_assign_proxyVertices(
27656            self_: *mut whiteout_M3ClothProxy,
27657            data: *const u64,
27658            count: usize,
27659        );
27660        pub fn whiteout_m3_M3ClothProxy_get_proxyWeights_count(
27661            self_: *mut whiteout_M3ClothProxy,
27662        ) -> usize;
27663        pub fn whiteout_m3_M3ClothProxy_resize_proxyWeights(
27664            self_: *mut whiteout_M3ClothProxy,
27665            count: usize,
27666        );
27667        pub fn whiteout_m3_M3ClothProxy_get_proxyWeights_data(
27668            self_: *mut whiteout_M3ClothProxy,
27669        ) -> *const u32;
27670        pub fn whiteout_m3_M3ClothProxy_assign_proxyWeights(
27671            self_: *mut whiteout_M3ClothProxy,
27672            data: *const u32,
27673            count: usize,
27674        );
27675        // ClothPhysics
27676        pub fn whiteout_m3_M3ClothPhysics_new() -> *mut whiteout_M3ClothPhysics;
27677        pub fn whiteout_m3_M3ClothPhysics_delete(self_: *mut whiteout_M3ClothPhysics);
27678        pub fn whiteout_m3_M3ClothPhysics_get_clothMeshCount(
27679            self_: *mut whiteout_M3ClothPhysics,
27680        ) -> u32;
27681        pub fn whiteout_m3_M3ClothPhysics_set_clothMeshCount(
27682            self_: *mut whiteout_M3ClothPhysics,
27683            value: u32,
27684        );
27685        pub fn whiteout_m3_M3ClothPhysics_get_skinBoneCount(
27686            self_: *mut whiteout_M3ClothPhysics,
27687        ) -> u32;
27688        pub fn whiteout_m3_M3ClothPhysics_set_skinBoneCount(
27689            self_: *mut whiteout_M3ClothPhysics,
27690            value: u32,
27691        );
27692        pub fn whiteout_m3_M3ClothPhysics_get_skinBones_count(
27693            self_: *mut whiteout_M3ClothPhysics,
27694        ) -> usize;
27695        pub fn whiteout_m3_M3ClothPhysics_resize_skinBones(
27696            self_: *mut whiteout_M3ClothPhysics,
27697            count: usize,
27698        );
27699        pub fn whiteout_m3_M3ClothPhysics_get_skinBones_data(
27700            self_: *mut whiteout_M3ClothPhysics,
27701        ) -> *const u16;
27702        pub fn whiteout_m3_M3ClothPhysics_assign_skinBones(
27703            self_: *mut whiteout_M3ClothPhysics,
27704            data: *const u16,
27705            count: usize,
27706        );
27707        pub fn whiteout_m3_M3ClothPhysics_get_simEnabled_count(
27708            self_: *mut whiteout_M3ClothPhysics,
27709        ) -> usize;
27710        pub fn whiteout_m3_M3ClothPhysics_resize_simEnabled(
27711            self_: *mut whiteout_M3ClothPhysics,
27712            count: usize,
27713        );
27714        pub fn whiteout_m3_M3ClothPhysics_get_simEnabled_data(
27715            self_: *mut whiteout_M3ClothPhysics,
27716        ) -> *const u8;
27717        pub fn whiteout_m3_M3ClothPhysics_assign_simEnabled(
27718            self_: *mut whiteout_M3ClothPhysics,
27719            data: *const u8,
27720            count: usize,
27721        );
27722        pub fn whiteout_m3_M3ClothPhysics_get_vertexBones_count(
27723            self_: *mut whiteout_M3ClothPhysics,
27724        ) -> usize;
27725        pub fn whiteout_m3_M3ClothPhysics_resize_vertexBones(
27726            self_: *mut whiteout_M3ClothPhysics,
27727            count: usize,
27728        );
27729        pub fn whiteout_m3_M3ClothPhysics_get_vertexBones_data(
27730            self_: *mut whiteout_M3ClothPhysics,
27731        ) -> *const u32;
27732        pub fn whiteout_m3_M3ClothPhysics_assign_vertexBones(
27733            self_: *mut whiteout_M3ClothPhysics,
27734            data: *const u32,
27735            count: usize,
27736        );
27737        pub fn whiteout_m3_M3ClothPhysics_get_vertexWeights_count(
27738            self_: *mut whiteout_M3ClothPhysics,
27739        ) -> usize;
27740        pub fn whiteout_m3_M3ClothPhysics_resize_vertexWeights(
27741            self_: *mut whiteout_M3ClothPhysics,
27742            count: usize,
27743        );
27744        pub fn whiteout_m3_M3ClothPhysics_get_vertexWeights_data(
27745            self_: *mut whiteout_M3ClothPhysics,
27746        ) -> *const u32;
27747        pub fn whiteout_m3_M3ClothPhysics_assign_vertexWeights(
27748            self_: *mut whiteout_M3ClothPhysics,
27749            data: *const u32,
27750            count: usize,
27751        );
27752        pub fn whiteout_m3_M3ClothPhysics_get_colliders_count(
27753            self_: *mut whiteout_M3ClothPhysics,
27754        ) -> usize;
27755        pub fn whiteout_m3_M3ClothPhysics_resize_colliders(
27756            self_: *mut whiteout_M3ClothPhysics,
27757            count: usize,
27758        );
27759        pub fn whiteout_m3_M3ClothPhysics_get_colliders_at(
27760            self_: *mut whiteout_M3ClothPhysics,
27761            index: usize,
27762        ) -> *mut whiteout_M3ClothCollider;
27763        pub fn whiteout_m3_M3ClothPhysics_get_proxies_count(
27764            self_: *mut whiteout_M3ClothPhysics,
27765        ) -> usize;
27766        pub fn whiteout_m3_M3ClothPhysics_resize_proxies(
27767            self_: *mut whiteout_M3ClothPhysics,
27768            count: usize,
27769        );
27770        pub fn whiteout_m3_M3ClothPhysics_get_proxies_at(
27771            self_: *mut whiteout_M3ClothPhysics,
27772            index: usize,
27773        ) -> *mut whiteout_M3ClothProxy;
27774        pub fn whiteout_m3_M3ClothPhysics_get_density(self_: *mut whiteout_M3ClothPhysics) -> f32;
27775        pub fn whiteout_m3_M3ClothPhysics_set_density(
27776            self_: *mut whiteout_M3ClothPhysics,
27777            value: f32,
27778        );
27779        pub fn whiteout_m3_M3ClothPhysics_get_tracking(self_: *mut whiteout_M3ClothPhysics) -> f32;
27780        pub fn whiteout_m3_M3ClothPhysics_set_tracking(
27781            self_: *mut whiteout_M3ClothPhysics,
27782            value: f32,
27783        );
27784        pub fn whiteout_m3_M3ClothPhysics_get_stretchStiffness(
27785            self_: *mut whiteout_M3ClothPhysics,
27786        ) -> f32;
27787        pub fn whiteout_m3_M3ClothPhysics_set_stretchStiffness(
27788            self_: *mut whiteout_M3ClothPhysics,
27789            value: f32,
27790        );
27791        pub fn whiteout_m3_M3ClothPhysics_get_horizontalStiffness(
27792            self_: *mut whiteout_M3ClothPhysics,
27793        ) -> f32;
27794        pub fn whiteout_m3_M3ClothPhysics_set_horizontalStiffness(
27795            self_: *mut whiteout_M3ClothPhysics,
27796            value: f32,
27797        );
27798        pub fn whiteout_m3_M3ClothPhysics_get_bendingStiffness(
27799            self_: *mut whiteout_M3ClothPhysics,
27800        ) -> f32;
27801        pub fn whiteout_m3_M3ClothPhysics_set_bendingStiffness(
27802            self_: *mut whiteout_M3ClothPhysics,
27803            value: f32,
27804        );
27805        pub fn whiteout_m3_M3ClothPhysics_get_damping(self_: *mut whiteout_M3ClothPhysics) -> f32;
27806        pub fn whiteout_m3_M3ClothPhysics_set_damping(
27807            self_: *mut whiteout_M3ClothPhysics,
27808            value: f32,
27809        );
27810        pub fn whiteout_m3_M3ClothPhysics_get_friction(self_: *mut whiteout_M3ClothPhysics) -> f32;
27811        pub fn whiteout_m3_M3ClothPhysics_set_friction(
27812            self_: *mut whiteout_M3ClothPhysics,
27813            value: f32,
27814        );
27815        pub fn whiteout_m3_M3ClothPhysics_get_gravity(self_: *mut whiteout_M3ClothPhysics) -> f32;
27816        pub fn whiteout_m3_M3ClothPhysics_set_gravity(
27817            self_: *mut whiteout_M3ClothPhysics,
27818            value: f32,
27819        );
27820        pub fn whiteout_m3_M3ClothPhysics_get_explosionScale(
27821            self_: *mut whiteout_M3ClothPhysics,
27822        ) -> f32;
27823        pub fn whiteout_m3_M3ClothPhysics_set_explosionScale(
27824            self_: *mut whiteout_M3ClothPhysics,
27825            value: f32,
27826        );
27827        pub fn whiteout_m3_M3ClothPhysics_get_windScale(self_: *mut whiteout_M3ClothPhysics)
27828            -> f32;
27829        pub fn whiteout_m3_M3ClothPhysics_set_windScale(
27830            self_: *mut whiteout_M3ClothPhysics,
27831            value: f32,
27832        );
27833        pub fn whiteout_m3_M3ClothPhysics_get_shearStiffness(
27834            self_: *mut whiteout_M3ClothPhysics,
27835        ) -> f32;
27836        pub fn whiteout_m3_M3ClothPhysics_set_shearStiffness(
27837            self_: *mut whiteout_M3ClothPhysics,
27838            value: f32,
27839        );
27840        pub fn whiteout_m3_M3ClothPhysics_get_dragFactor(
27841            self_: *mut whiteout_M3ClothPhysics,
27842        ) -> f32;
27843        pub fn whiteout_m3_M3ClothPhysics_set_dragFactor(
27844            self_: *mut whiteout_M3ClothPhysics,
27845            value: f32,
27846        );
27847        pub fn whiteout_m3_M3ClothPhysics_get_liftFactor(
27848            self_: *mut whiteout_M3ClothPhysics,
27849        ) -> f32;
27850        pub fn whiteout_m3_M3ClothPhysics_set_liftFactor(
27851            self_: *mut whiteout_M3ClothPhysics,
27852            value: f32,
27853        );
27854        pub fn whiteout_m3_M3ClothPhysics_get_sphereStiffness(
27855            self_: *mut whiteout_M3ClothPhysics,
27856        ) -> f32;
27857        pub fn whiteout_m3_M3ClothPhysics_set_sphereStiffness(
27858            self_: *mut whiteout_M3ClothPhysics,
27859            value: f32,
27860        );
27861        pub fn whiteout_m3_M3ClothPhysics_get_flatten(self_: *mut whiteout_M3ClothPhysics) -> u32;
27862        pub fn whiteout_m3_M3ClothPhysics_set_flatten(
27863            self_: *mut whiteout_M3ClothPhysics,
27864            value: u32,
27865        );
27866        pub fn whiteout_m3_M3ClothPhysics_get_active(
27867            self_: *mut whiteout_M3ClothPhysics,
27868        ) -> *mut whiteout_M3AnimRefU32;
27869        pub fn whiteout_m3_M3ClothPhysics_set_active(
27870            self_: *mut whiteout_M3ClothPhysics,
27871            value: *const whiteout_M3AnimRefU32,
27872        );
27873        pub fn whiteout_m3_M3ClothPhysics_get_useSkinCollision(
27874            self_: *mut whiteout_M3ClothPhysics,
27875        ) -> u32;
27876        pub fn whiteout_m3_M3ClothPhysics_set_useSkinCollision(
27877            self_: *mut whiteout_M3ClothPhysics,
27878            value: u32,
27879        );
27880        pub fn whiteout_m3_M3ClothPhysics_get_skinOffset(
27881            self_: *mut whiteout_M3ClothPhysics,
27882        ) -> f32;
27883        pub fn whiteout_m3_M3ClothPhysics_set_skinOffset(
27884            self_: *mut whiteout_M3ClothPhysics,
27885            value: f32,
27886        );
27887        pub fn whiteout_m3_M3ClothPhysics_get_skinExponent(
27888            self_: *mut whiteout_M3ClothPhysics,
27889        ) -> f32;
27890        pub fn whiteout_m3_M3ClothPhysics_set_skinExponent(
27891            self_: *mut whiteout_M3ClothPhysics,
27892            value: f32,
27893        );
27894        pub fn whiteout_m3_M3ClothPhysics_get_skinStiffness(
27895            self_: *mut whiteout_M3ClothPhysics,
27896        ) -> f32;
27897        pub fn whiteout_m3_M3ClothPhysics_set_skinStiffness(
27898            self_: *mut whiteout_M3ClothPhysics,
27899            value: f32,
27900        );
27901        pub fn whiteout_m3_M3ClothPhysics_get_localChannels(
27902            self_: *mut whiteout_M3ClothPhysics,
27903        ) -> u32;
27904        pub fn whiteout_m3_M3ClothPhysics_set_localChannels(
27905            self_: *mut whiteout_M3ClothPhysics,
27906            value: u32,
27907        );
27908        pub fn whiteout_m3_M3ClothPhysics_get_localWind(
27909            self_: *mut whiteout_M3ClothPhysics,
27910        ) -> *mut core::ffi::c_void;
27911        pub fn whiteout_m3_M3ClothPhysics_set_localWind(
27912            self_: *mut whiteout_M3ClothPhysics,
27913            value: *const core::ffi::c_void,
27914        );
27915        // Light
27916        pub fn whiteout_m3_M3Light_new() -> *mut whiteout_M3Light;
27917        pub fn whiteout_m3_M3Light_delete(self_: *mut whiteout_M3Light);
27918        pub fn whiteout_m3_M3Light_get_lightType(self_: *mut whiteout_M3Light) -> i32;
27919        pub fn whiteout_m3_M3Light_set_lightType(self_: *mut whiteout_M3Light, value: i32);
27920        pub fn whiteout_m3_M3Light_get_boneIndex(self_: *mut whiteout_M3Light) -> u16;
27921        pub fn whiteout_m3_M3Light_set_boneIndex(self_: *mut whiteout_M3Light, value: u16);
27922        pub fn whiteout_m3_M3Light_get_flags(self_: *mut whiteout_M3Light) -> i32;
27923        pub fn whiteout_m3_M3Light_set_flags(self_: *mut whiteout_M3Light, value: i32);
27924        pub fn whiteout_m3_M3Light_get_lodCut(self_: *mut whiteout_M3Light) -> u32;
27925        pub fn whiteout_m3_M3Light_set_lodCut(self_: *mut whiteout_M3Light, value: u32);
27926        pub fn whiteout_m3_M3Light_get_shadowLodCut(self_: *mut whiteout_M3Light) -> u32;
27927        pub fn whiteout_m3_M3Light_set_shadowLodCut(self_: *mut whiteout_M3Light, value: u32);
27928        pub fn whiteout_m3_M3Light_get_diffuseColor(
27929            self_: *mut whiteout_M3Light,
27930        ) -> *mut whiteout_M3AnimRefVector3f;
27931        pub fn whiteout_m3_M3Light_set_diffuseColor(
27932            self_: *mut whiteout_M3Light,
27933            value: *const whiteout_M3AnimRefVector3f,
27934        );
27935        pub fn whiteout_m3_M3Light_get_intensityMultiplier(
27936            self_: *mut whiteout_M3Light,
27937        ) -> *mut whiteout_M3AnimRefF32;
27938        pub fn whiteout_m3_M3Light_set_intensityMultiplier(
27939            self_: *mut whiteout_M3Light,
27940            value: *const whiteout_M3AnimRefF32,
27941        );
27942        pub fn whiteout_m3_M3Light_get_specularColor(
27943            self_: *mut whiteout_M3Light,
27944        ) -> *mut whiteout_M3AnimRefVector3f;
27945        pub fn whiteout_m3_M3Light_set_specularColor(
27946            self_: *mut whiteout_M3Light,
27947            value: *const whiteout_M3AnimRefVector3f,
27948        );
27949        pub fn whiteout_m3_M3Light_get_specularMultiplier(
27950            self_: *mut whiteout_M3Light,
27951        ) -> *mut whiteout_M3AnimRefF32;
27952        pub fn whiteout_m3_M3Light_set_specularMultiplier(
27953            self_: *mut whiteout_M3Light,
27954            value: *const whiteout_M3AnimRefF32,
27955        );
27956        pub fn whiteout_m3_M3Light_get_decay(
27957            self_: *mut whiteout_M3Light,
27958        ) -> *mut whiteout_M3AnimRefF32;
27959        pub fn whiteout_m3_M3Light_set_decay(
27960            self_: *mut whiteout_M3Light,
27961            value: *const whiteout_M3AnimRefF32,
27962        );
27963        pub fn whiteout_m3_M3Light_get_attenuationEnd(self_: *mut whiteout_M3Light) -> f32;
27964        pub fn whiteout_m3_M3Light_set_attenuationEnd(self_: *mut whiteout_M3Light, value: f32);
27965        pub fn whiteout_m3_M3Light_get_attenuationStart(
27966            self_: *mut whiteout_M3Light,
27967        ) -> *mut whiteout_M3AnimRefF32;
27968        pub fn whiteout_m3_M3Light_set_attenuationStart(
27969            self_: *mut whiteout_M3Light,
27970            value: *const whiteout_M3AnimRefF32,
27971        );
27972        pub fn whiteout_m3_M3Light_get_hotSpot(
27973            self_: *mut whiteout_M3Light,
27974        ) -> *mut whiteout_M3AnimRefF32;
27975        pub fn whiteout_m3_M3Light_set_hotSpot(
27976            self_: *mut whiteout_M3Light,
27977            value: *const whiteout_M3AnimRefF32,
27978        );
27979        pub fn whiteout_m3_M3Light_get_falloff(
27980            self_: *mut whiteout_M3Light,
27981        ) -> *mut whiteout_M3AnimRefF32;
27982        pub fn whiteout_m3_M3Light_set_falloff(
27983            self_: *mut whiteout_M3Light,
27984            value: *const whiteout_M3AnimRefF32,
27985        );
27986        // Camera
27987        pub fn whiteout_m3_M3Camera_new() -> *mut whiteout_M3Camera;
27988        pub fn whiteout_m3_M3Camera_delete(self_: *mut whiteout_M3Camera);
27989        pub fn whiteout_m3_M3Camera_get_boneIndex(self_: *mut whiteout_M3Camera) -> u32;
27990        pub fn whiteout_m3_M3Camera_set_boneIndex(self_: *mut whiteout_M3Camera, value: u32);
27991        pub fn whiteout_m3_M3Camera_get_name(self_: *mut whiteout_M3Camera) -> RawCString;
27992        pub fn whiteout_m3_M3Camera_set_name(
27993            self_: *mut whiteout_M3Camera,
27994            value: *const core::ffi::c_char,
27995        );
27996        pub fn whiteout_m3_M3Camera_get_fieldOfView(
27997            self_: *mut whiteout_M3Camera,
27998        ) -> *mut whiteout_M3AnimRefF32;
27999        pub fn whiteout_m3_M3Camera_set_fieldOfView(
28000            self_: *mut whiteout_M3Camera,
28001            value: *const whiteout_M3AnimRefF32,
28002        );
28003        pub fn whiteout_m3_M3Camera_get_useVerticalFOV(self_: *mut whiteout_M3Camera) -> u32;
28004        pub fn whiteout_m3_M3Camera_set_useVerticalFOV(self_: *mut whiteout_M3Camera, value: u32);
28005        pub fn whiteout_m3_M3Camera_get_dofType(self_: *mut whiteout_M3Camera) -> u32;
28006        pub fn whiteout_m3_M3Camera_set_dofType(self_: *mut whiteout_M3Camera, value: u32);
28007        pub fn whiteout_m3_M3Camera_get_farClip(
28008            self_: *mut whiteout_M3Camera,
28009        ) -> *mut whiteout_M3AnimRefF32;
28010        pub fn whiteout_m3_M3Camera_set_farClip(
28011            self_: *mut whiteout_M3Camera,
28012            value: *const whiteout_M3AnimRefF32,
28013        );
28014        pub fn whiteout_m3_M3Camera_get_nearClip(
28015            self_: *mut whiteout_M3Camera,
28016        ) -> *mut whiteout_M3AnimRefF32;
28017        pub fn whiteout_m3_M3Camera_set_nearClip(
28018            self_: *mut whiteout_M3Camera,
28019            value: *const whiteout_M3AnimRefF32,
28020        );
28021        pub fn whiteout_m3_M3Camera_get_shadowClipDistance(
28022            self_: *mut whiteout_M3Camera,
28023        ) -> *mut whiteout_M3AnimRefF32;
28024        pub fn whiteout_m3_M3Camera_set_shadowClipDistance(
28025            self_: *mut whiteout_M3Camera,
28026            value: *const whiteout_M3AnimRefF32,
28027        );
28028        pub fn whiteout_m3_M3Camera_get_focusDistance(
28029            self_: *mut whiteout_M3Camera,
28030        ) -> *mut whiteout_M3AnimRefF32;
28031        pub fn whiteout_m3_M3Camera_set_focusDistance(
28032            self_: *mut whiteout_M3Camera,
28033            value: *const whiteout_M3AnimRefF32,
28034        );
28035        pub fn whiteout_m3_M3Camera_get_farFocusRange(
28036            self_: *mut whiteout_M3Camera,
28037        ) -> *mut whiteout_M3AnimRefF32;
28038        pub fn whiteout_m3_M3Camera_set_farFocusRange(
28039            self_: *mut whiteout_M3Camera,
28040            value: *const whiteout_M3AnimRefF32,
28041        );
28042        pub fn whiteout_m3_M3Camera_get_nearFocusRange(
28043            self_: *mut whiteout_M3Camera,
28044        ) -> *mut whiteout_M3AnimRefF32;
28045        pub fn whiteout_m3_M3Camera_set_nearFocusRange(
28046            self_: *mut whiteout_M3Camera,
28047            value: *const whiteout_M3AnimRefF32,
28048        );
28049        pub fn whiteout_m3_M3Camera_get_nearFalloffStart(
28050            self_: *mut whiteout_M3Camera,
28051        ) -> *mut whiteout_M3AnimRefF32;
28052        pub fn whiteout_m3_M3Camera_set_nearFalloffStart(
28053            self_: *mut whiteout_M3Camera,
28054            value: *const whiteout_M3AnimRefF32,
28055        );
28056        pub fn whiteout_m3_M3Camera_get_nearFalloffEnd(
28057            self_: *mut whiteout_M3Camera,
28058        ) -> *mut whiteout_M3AnimRefF32;
28059        pub fn whiteout_m3_M3Camera_set_nearFalloffEnd(
28060            self_: *mut whiteout_M3Camera,
28061            value: *const whiteout_M3AnimRefF32,
28062        );
28063        pub fn whiteout_m3_M3Camera_get_dofAmount(
28064            self_: *mut whiteout_M3Camera,
28065        ) -> *mut whiteout_M3AnimRefF32;
28066        pub fn whiteout_m3_M3Camera_set_dofAmount(
28067            self_: *mut whiteout_M3Camera,
28068            value: *const whiteout_M3AnimRefF32,
28069        );
28070        pub fn whiteout_m3_M3Camera_get_bokehFStop(
28071            self_: *mut whiteout_M3Camera,
28072        ) -> *mut whiteout_M3AnimRefF32;
28073        pub fn whiteout_m3_M3Camera_set_bokehFStop(
28074            self_: *mut whiteout_M3Camera,
28075            value: *const whiteout_M3AnimRefF32,
28076        );
28077        pub fn whiteout_m3_M3Camera_get_bokehMaxCoCDiameter(
28078            self_: *mut whiteout_M3Camera,
28079        ) -> *mut whiteout_M3AnimRefF32;
28080        pub fn whiteout_m3_M3Camera_set_bokehMaxCoCDiameter(
28081            self_: *mut whiteout_M3Camera,
28082            value: *const whiteout_M3AnimRefF32,
28083        );
28084        // Model
28085        pub fn whiteout_m3_M3Model_new() -> *mut whiteout_M3Model;
28086        pub fn whiteout_m3_M3Model_delete(self_: *mut whiteout_M3Model);
28087        pub fn whiteout_m3_M3Model_get_name(self_: *mut whiteout_M3Model) -> RawCString;
28088        pub fn whiteout_m3_M3Model_set_name(
28089            self_: *mut whiteout_M3Model,
28090            value: *const core::ffi::c_char,
28091        );
28092        pub fn whiteout_m3_M3Model_get_flags(self_: *mut whiteout_M3Model) -> i32;
28093        pub fn whiteout_m3_M3Model_set_flags(self_: *mut whiteout_M3Model, value: i32);
28094        pub fn whiteout_m3_M3Model_get_sequences_count(self_: *mut whiteout_M3Model) -> usize;
28095        pub fn whiteout_m3_M3Model_resize_sequences(self_: *mut whiteout_M3Model, count: usize);
28096        pub fn whiteout_m3_M3Model_get_sequences_at(
28097            self_: *mut whiteout_M3Model,
28098            index: usize,
28099        ) -> *mut whiteout_M3Sequence;
28100        pub fn whiteout_m3_M3Model_get_subTrackCollections_count(
28101            self_: *mut whiteout_M3Model,
28102        ) -> usize;
28103        pub fn whiteout_m3_M3Model_resize_subTrackCollections(
28104            self_: *mut whiteout_M3Model,
28105            count: usize,
28106        );
28107        pub fn whiteout_m3_M3Model_get_subTrackCollections_at(
28108            self_: *mut whiteout_M3Model,
28109            index: usize,
28110        ) -> *mut whiteout_M3SubTrackContainer;
28111        pub fn whiteout_m3_M3Model_get_animationGroups_count(self_: *mut whiteout_M3Model)
28112            -> usize;
28113        pub fn whiteout_m3_M3Model_resize_animationGroups(
28114            self_: *mut whiteout_M3Model,
28115            count: usize,
28116        );
28117        pub fn whiteout_m3_M3Model_get_animationGroups_at(
28118            self_: *mut whiteout_M3Model,
28119            index: usize,
28120        ) -> *mut whiteout_M3AnimationGroup;
28121        pub fn whiteout_m3_M3Model_get_boneAnimationSets_count(
28122            self_: *mut whiteout_M3Model,
28123        ) -> usize;
28124        pub fn whiteout_m3_M3Model_resize_boneAnimationSets(
28125            self_: *mut whiteout_M3Model,
28126            count: usize,
28127        );
28128        pub fn whiteout_m3_M3Model_get_boneAnimationSets_at(
28129            self_: *mut whiteout_M3Model,
28130            index: usize,
28131        ) -> *mut whiteout_M3BoneAnimationSet;
28132        pub fn whiteout_m3_M3Model_get_animationSplitCount(self_: *mut whiteout_M3Model) -> u32;
28133        pub fn whiteout_m3_M3Model_set_animationSplitCount(
28134            self_: *mut whiteout_M3Model,
28135            value: u32,
28136        );
28137        pub fn whiteout_m3_M3Model_get_animationStates_count(self_: *mut whiteout_M3Model)
28138            -> usize;
28139        pub fn whiteout_m3_M3Model_resize_animationStates(
28140            self_: *mut whiteout_M3Model,
28141            count: usize,
28142        );
28143        pub fn whiteout_m3_M3Model_get_animationStates_at(
28144            self_: *mut whiteout_M3Model,
28145            index: usize,
28146        ) -> *mut whiteout_M3AnimationState;
28147        pub fn whiteout_m3_M3Model_get_bones_count(self_: *mut whiteout_M3Model) -> usize;
28148        pub fn whiteout_m3_M3Model_resize_bones(self_: *mut whiteout_M3Model, count: usize);
28149        pub fn whiteout_m3_M3Model_get_bones_at(
28150            self_: *mut whiteout_M3Model,
28151            index: usize,
28152        ) -> *mut whiteout_M3Bone;
28153        pub fn whiteout_m3_M3Model_get_skinBoneCount(self_: *mut whiteout_M3Model) -> u32;
28154        pub fn whiteout_m3_M3Model_set_skinBoneCount(self_: *mut whiteout_M3Model, value: u32);
28155        pub fn whiteout_m3_M3Model_get_divisions_count(self_: *mut whiteout_M3Model) -> usize;
28156        pub fn whiteout_m3_M3Model_resize_divisions(self_: *mut whiteout_M3Model, count: usize);
28157        pub fn whiteout_m3_M3Model_get_divisions_at(
28158            self_: *mut whiteout_M3Model,
28159            index: usize,
28160        ) -> *mut whiteout_M3MeshDivision;
28161        pub fn whiteout_m3_M3Model_get_boneLookup_count(self_: *mut whiteout_M3Model) -> usize;
28162        pub fn whiteout_m3_M3Model_resize_boneLookup(self_: *mut whiteout_M3Model, count: usize);
28163        pub fn whiteout_m3_M3Model_get_boneLookup_data(self_: *mut whiteout_M3Model) -> *const u16;
28164        pub fn whiteout_m3_M3Model_assign_boneLookup(
28165            self_: *mut whiteout_M3Model,
28166            data: *const u16,
28167            count: usize,
28168        );
28169        pub fn whiteout_m3_M3Model_get_bounds(
28170            self_: *mut whiteout_M3Model,
28171        ) -> *mut whiteout_M3Extent;
28172        pub fn whiteout_m3_M3Model_set_bounds(
28173            self_: *mut whiteout_M3Model,
28174            value: *const whiteout_M3Extent,
28175        );
28176        pub fn whiteout_m3_M3Model_get_collisionBounds(
28177            self_: *mut whiteout_M3Model,
28178        ) -> *mut whiteout_M3Extent;
28179        pub fn whiteout_m3_M3Model_set_collisionBounds(
28180            self_: *mut whiteout_M3Model,
28181            value: *const whiteout_M3Extent,
28182        );
28183        pub fn whiteout_m3_M3Model_get_collisionFaces_count(self_: *mut whiteout_M3Model) -> usize;
28184        pub fn whiteout_m3_M3Model_resize_collisionFaces(
28185            self_: *mut whiteout_M3Model,
28186            count: usize,
28187        );
28188        pub fn whiteout_m3_M3Model_get_collisionFaces_data(
28189            self_: *mut whiteout_M3Model,
28190        ) -> *const u16;
28191        pub fn whiteout_m3_M3Model_assign_collisionFaces(
28192            self_: *mut whiteout_M3Model,
28193            data: *const u16,
28194            count: usize,
28195        );
28196        pub fn whiteout_m3_M3Model_get_collisionVerts_count(self_: *mut whiteout_M3Model) -> usize;
28197        pub fn whiteout_m3_M3Model_resize_collisionVerts(
28198            self_: *mut whiteout_M3Model,
28199            count: usize,
28200        );
28201        pub fn whiteout_m3_M3Model_get_collisionVerts_data(
28202            self_: *mut whiteout_M3Model,
28203        ) -> *const f32;
28204        pub fn whiteout_m3_M3Model_assign_collisionVerts(
28205            self_: *mut whiteout_M3Model,
28206            data: *const f32,
28207            count: usize,
28208        );
28209        pub fn whiteout_m3_M3Model_get_collisionNormals_count(
28210            self_: *mut whiteout_M3Model,
28211        ) -> usize;
28212        pub fn whiteout_m3_M3Model_resize_collisionNormals(
28213            self_: *mut whiteout_M3Model,
28214            count: usize,
28215        );
28216        pub fn whiteout_m3_M3Model_get_collisionNormals_data(
28217            self_: *mut whiteout_M3Model,
28218        ) -> *const f32;
28219        pub fn whiteout_m3_M3Model_assign_collisionNormals(
28220            self_: *mut whiteout_M3Model,
28221            data: *const f32,
28222            count: usize,
28223        );
28224        pub fn whiteout_m3_M3Model_get_attachmentPoints_count(
28225            self_: *mut whiteout_M3Model,
28226        ) -> usize;
28227        pub fn whiteout_m3_M3Model_resize_attachmentPoints(
28228            self_: *mut whiteout_M3Model,
28229            count: usize,
28230        );
28231        pub fn whiteout_m3_M3Model_get_attachmentPoints_at(
28232            self_: *mut whiteout_M3Model,
28233            index: usize,
28234        ) -> *mut whiteout_M3AttachmentPoint;
28235        pub fn whiteout_m3_M3Model_get_attachmentPointAddons_count(
28236            self_: *mut whiteout_M3Model,
28237        ) -> usize;
28238        pub fn whiteout_m3_M3Model_resize_attachmentPointAddons(
28239            self_: *mut whiteout_M3Model,
28240            count: usize,
28241        );
28242        pub fn whiteout_m3_M3Model_get_attachmentPointAddons_data(
28243            self_: *mut whiteout_M3Model,
28244        ) -> *const u16;
28245        pub fn whiteout_m3_M3Model_assign_attachmentPointAddons(
28246            self_: *mut whiteout_M3Model,
28247            data: *const u16,
28248            count: usize,
28249        );
28250        pub fn whiteout_m3_M3Model_get_lights_count(self_: *mut whiteout_M3Model) -> usize;
28251        pub fn whiteout_m3_M3Model_resize_lights(self_: *mut whiteout_M3Model, count: usize);
28252        pub fn whiteout_m3_M3Model_get_lights_at(
28253            self_: *mut whiteout_M3Model,
28254            index: usize,
28255        ) -> *mut whiteout_M3Light;
28256        pub fn whiteout_m3_M3Model_get_shadowBoxes_count(self_: *mut whiteout_M3Model) -> usize;
28257        pub fn whiteout_m3_M3Model_resize_shadowBoxes(self_: *mut whiteout_M3Model, count: usize);
28258        pub fn whiteout_m3_M3Model_get_shadowBoxes_at(
28259            self_: *mut whiteout_M3Model,
28260            index: usize,
28261        ) -> *mut whiteout_M3ShadowBox;
28262        pub fn whiteout_m3_M3Model_get_cameras_count(self_: *mut whiteout_M3Model) -> usize;
28263        pub fn whiteout_m3_M3Model_resize_cameras(self_: *mut whiteout_M3Model, count: usize);
28264        pub fn whiteout_m3_M3Model_get_cameras_at(
28265            self_: *mut whiteout_M3Model,
28266            index: usize,
28267        ) -> *mut whiteout_M3Camera;
28268        pub fn whiteout_m3_M3Model_get_camerasAddons_count(self_: *mut whiteout_M3Model) -> usize;
28269        pub fn whiteout_m3_M3Model_resize_camerasAddons(self_: *mut whiteout_M3Model, count: usize);
28270        pub fn whiteout_m3_M3Model_get_camerasAddons_data(
28271            self_: *mut whiteout_M3Model,
28272        ) -> *const u16;
28273        pub fn whiteout_m3_M3Model_assign_camerasAddons(
28274            self_: *mut whiteout_M3Model,
28275            data: *const u16,
28276            count: usize,
28277        );
28278        pub fn whiteout_m3_M3Model_get_materialMaps_count(self_: *mut whiteout_M3Model) -> usize;
28279        pub fn whiteout_m3_M3Model_resize_materialMaps(self_: *mut whiteout_M3Model, count: usize);
28280        pub fn whiteout_m3_M3Model_get_materialMaps_at(
28281            self_: *mut whiteout_M3Model,
28282            index: usize,
28283        ) -> *mut whiteout_M3MaterialMap;
28284        pub fn whiteout_m3_M3Model_get_standardMaterials_count(
28285            self_: *mut whiteout_M3Model,
28286        ) -> usize;
28287        pub fn whiteout_m3_M3Model_resize_standardMaterials(
28288            self_: *mut whiteout_M3Model,
28289            count: usize,
28290        );
28291        pub fn whiteout_m3_M3Model_get_standardMaterials_at(
28292            self_: *mut whiteout_M3Model,
28293            index: usize,
28294        ) -> *mut whiteout_M3StandardMaterial;
28295        pub fn whiteout_m3_M3Model_get_displacementMaterials_count(
28296            self_: *mut whiteout_M3Model,
28297        ) -> usize;
28298        pub fn whiteout_m3_M3Model_resize_displacementMaterials(
28299            self_: *mut whiteout_M3Model,
28300            count: usize,
28301        );
28302        pub fn whiteout_m3_M3Model_get_displacementMaterials_at(
28303            self_: *mut whiteout_M3Model,
28304            index: usize,
28305        ) -> *mut whiteout_M3DisplacementMaterial;
28306        pub fn whiteout_m3_M3Model_get_compositeMaterials_count(
28307            self_: *mut whiteout_M3Model,
28308        ) -> usize;
28309        pub fn whiteout_m3_M3Model_resize_compositeMaterials(
28310            self_: *mut whiteout_M3Model,
28311            count: usize,
28312        );
28313        pub fn whiteout_m3_M3Model_get_compositeMaterials_at(
28314            self_: *mut whiteout_M3Model,
28315            index: usize,
28316        ) -> *mut whiteout_M3CompositeMaterial;
28317        pub fn whiteout_m3_M3Model_get_terrainMaterials_count(
28318            self_: *mut whiteout_M3Model,
28319        ) -> usize;
28320        pub fn whiteout_m3_M3Model_resize_terrainMaterials(
28321            self_: *mut whiteout_M3Model,
28322            count: usize,
28323        );
28324        pub fn whiteout_m3_M3Model_get_terrainMaterials_at(
28325            self_: *mut whiteout_M3Model,
28326            index: usize,
28327        ) -> *mut whiteout_M3TerrainMaterial;
28328        pub fn whiteout_m3_M3Model_get_volumeMaterials_count(self_: *mut whiteout_M3Model)
28329            -> usize;
28330        pub fn whiteout_m3_M3Model_resize_volumeMaterials(
28331            self_: *mut whiteout_M3Model,
28332            count: usize,
28333        );
28334        pub fn whiteout_m3_M3Model_get_volumeMaterials_at(
28335            self_: *mut whiteout_M3Model,
28336            index: usize,
28337        ) -> *mut whiteout_M3VolumeMaterial;
28338        pub fn whiteout_m3_M3Model_get_hairMaterials_count(self_: *mut whiteout_M3Model) -> usize;
28339        pub fn whiteout_m3_M3Model_resize_hairMaterials(self_: *mut whiteout_M3Model, count: usize);
28340        pub fn whiteout_m3_M3Model_get_hairMaterials_at(
28341            self_: *mut whiteout_M3Model,
28342            index: usize,
28343        ) -> *mut whiteout_M3HairMaterial;
28344        pub fn whiteout_m3_M3Model_get_creepMaterials_count(self_: *mut whiteout_M3Model) -> usize;
28345        pub fn whiteout_m3_M3Model_resize_creepMaterials(
28346            self_: *mut whiteout_M3Model,
28347            count: usize,
28348        );
28349        pub fn whiteout_m3_M3Model_get_creepMaterials_at(
28350            self_: *mut whiteout_M3Model,
28351            index: usize,
28352        ) -> *mut whiteout_M3CreepMaterial;
28353        pub fn whiteout_m3_M3Model_get_volumeNoiseMaterials_count(
28354            self_: *mut whiteout_M3Model,
28355        ) -> usize;
28356        pub fn whiteout_m3_M3Model_resize_volumeNoiseMaterials(
28357            self_: *mut whiteout_M3Model,
28358            count: usize,
28359        );
28360        pub fn whiteout_m3_M3Model_get_volumeNoiseMaterials_at(
28361            self_: *mut whiteout_M3Model,
28362            index: usize,
28363        ) -> *mut whiteout_M3VolumeNoiseMaterial;
28364        pub fn whiteout_m3_M3Model_get_stbMaterials_count(self_: *mut whiteout_M3Model) -> usize;
28365        pub fn whiteout_m3_M3Model_resize_stbMaterials(self_: *mut whiteout_M3Model, count: usize);
28366        pub fn whiteout_m3_M3Model_get_stbMaterials_at(
28367            self_: *mut whiteout_M3Model,
28368            index: usize,
28369        ) -> *mut whiteout_M3STBMaterial;
28370        pub fn whiteout_m3_M3Model_get_reflectionMaterials_count(
28371            self_: *mut whiteout_M3Model,
28372        ) -> usize;
28373        pub fn whiteout_m3_M3Model_resize_reflectionMaterials(
28374            self_: *mut whiteout_M3Model,
28375            count: usize,
28376        );
28377        pub fn whiteout_m3_M3Model_get_reflectionMaterials_at(
28378            self_: *mut whiteout_M3Model,
28379            index: usize,
28380        ) -> *mut whiteout_M3ReflectionMaterial;
28381        pub fn whiteout_m3_M3Model_get_lensFlareMaterials_count(
28382            self_: *mut whiteout_M3Model,
28383        ) -> usize;
28384        pub fn whiteout_m3_M3Model_resize_lensFlareMaterials(
28385            self_: *mut whiteout_M3Model,
28386            count: usize,
28387        );
28388        pub fn whiteout_m3_M3Model_get_lensFlareMaterials_at(
28389            self_: *mut whiteout_M3Model,
28390            index: usize,
28391        ) -> *mut whiteout_M3LensFlare;
28392        pub fn whiteout_m3_M3Model_get_materialAddData_count(self_: *mut whiteout_M3Model)
28393            -> usize;
28394        pub fn whiteout_m3_M3Model_resize_materialAddData(
28395            self_: *mut whiteout_M3Model,
28396            count: usize,
28397        );
28398        pub fn whiteout_m3_M3Model_get_materialAddData_at(
28399            self_: *mut whiteout_M3Model,
28400            index: usize,
28401        ) -> *mut whiteout_M3MaterialAddData;
28402        pub fn whiteout_m3_M3Model_get_particleEmitters_count(
28403            self_: *mut whiteout_M3Model,
28404        ) -> usize;
28405        pub fn whiteout_m3_M3Model_resize_particleEmitters(
28406            self_: *mut whiteout_M3Model,
28407            count: usize,
28408        );
28409        pub fn whiteout_m3_M3Model_get_particleEmitters_at(
28410            self_: *mut whiteout_M3Model,
28411            index: usize,
28412        ) -> *mut whiteout_M3ParticleEmitter;
28413        pub fn whiteout_m3_M3Model_get_particleEmitterCopies_count(
28414            self_: *mut whiteout_M3Model,
28415        ) -> usize;
28416        pub fn whiteout_m3_M3Model_resize_particleEmitterCopies(
28417            self_: *mut whiteout_M3Model,
28418            count: usize,
28419        );
28420        pub fn whiteout_m3_M3Model_get_particleEmitterCopies_at(
28421            self_: *mut whiteout_M3Model,
28422            index: usize,
28423        ) -> *mut whiteout_M3ParticleEmitterCopy;
28424        pub fn whiteout_m3_M3Model_get_ribbonEmitters_count(self_: *mut whiteout_M3Model) -> usize;
28425        pub fn whiteout_m3_M3Model_resize_ribbonEmitters(
28426            self_: *mut whiteout_M3Model,
28427            count: usize,
28428        );
28429        pub fn whiteout_m3_M3Model_get_ribbonEmitters_at(
28430            self_: *mut whiteout_M3Model,
28431            index: usize,
28432        ) -> *mut whiteout_M3RibbonEmitter;
28433        pub fn whiteout_m3_M3Model_get_projections_count(self_: *mut whiteout_M3Model) -> usize;
28434        pub fn whiteout_m3_M3Model_resize_projections(self_: *mut whiteout_M3Model, count: usize);
28435        pub fn whiteout_m3_M3Model_get_projections_at(
28436            self_: *mut whiteout_M3Model,
28437            index: usize,
28438        ) -> *mut whiteout_M3Projector;
28439        pub fn whiteout_m3_M3Model_get_forces_count(self_: *mut whiteout_M3Model) -> usize;
28440        pub fn whiteout_m3_M3Model_resize_forces(self_: *mut whiteout_M3Model, count: usize);
28441        pub fn whiteout_m3_M3Model_get_forces_at(
28442            self_: *mut whiteout_M3Model,
28443            index: usize,
28444        ) -> *mut whiteout_M3Force;
28445        pub fn whiteout_m3_M3Model_get_warps_count(self_: *mut whiteout_M3Model) -> usize;
28446        pub fn whiteout_m3_M3Model_resize_warps(self_: *mut whiteout_M3Model, count: usize);
28447        pub fn whiteout_m3_M3Model_get_warps_at(
28448            self_: *mut whiteout_M3Model,
28449            index: usize,
28450        ) -> *mut whiteout_M3Warp;
28451        pub fn whiteout_m3_M3Model_get_viewVolumes_count(self_: *mut whiteout_M3Model) -> usize;
28452        pub fn whiteout_m3_M3Model_resize_viewVolumes(self_: *mut whiteout_M3Model, count: usize);
28453        pub fn whiteout_m3_M3Model_get_viewVolumes_at(
28454            self_: *mut whiteout_M3Model,
28455            index: usize,
28456        ) -> *mut whiteout_M3ViewVolume;
28457        pub fn whiteout_m3_M3Model_get_rigidBodies_count(self_: *mut whiteout_M3Model) -> usize;
28458        pub fn whiteout_m3_M3Model_resize_rigidBodies(self_: *mut whiteout_M3Model, count: usize);
28459        pub fn whiteout_m3_M3Model_get_rigidBodies_at(
28460            self_: *mut whiteout_M3Model,
28461            index: usize,
28462        ) -> *mut whiteout_M3RigidBody;
28463        pub fn whiteout_m3_M3Model_get_physicsConstraints_count(
28464            self_: *mut whiteout_M3Model,
28465        ) -> usize;
28466        pub fn whiteout_m3_M3Model_resize_physicsConstraints(
28467            self_: *mut whiteout_M3Model,
28468            count: usize,
28469        );
28470        pub fn whiteout_m3_M3Model_get_physicsConstraints_at(
28471            self_: *mut whiteout_M3Model,
28472            index: usize,
28473        ) -> *mut whiteout_M3PhysicsConstraint;
28474        pub fn whiteout_m3_M3Model_get_physicsJoints_count(self_: *mut whiteout_M3Model) -> usize;
28475        pub fn whiteout_m3_M3Model_resize_physicsJoints(self_: *mut whiteout_M3Model, count: usize);
28476        pub fn whiteout_m3_M3Model_get_physicsJoints_at(
28477            self_: *mut whiteout_M3Model,
28478            index: usize,
28479        ) -> *mut whiteout_M3PhysicsJoint;
28480        pub fn whiteout_m3_M3Model_get_clothPhysics_count(self_: *mut whiteout_M3Model) -> usize;
28481        pub fn whiteout_m3_M3Model_resize_clothPhysics(self_: *mut whiteout_M3Model, count: usize);
28482        pub fn whiteout_m3_M3Model_get_clothPhysics_at(
28483            self_: *mut whiteout_M3Model,
28484            index: usize,
28485        ) -> *mut whiteout_M3ClothPhysics;
28486        pub fn whiteout_m3_M3Model_get_ikTwoJoints_count(self_: *mut whiteout_M3Model) -> usize;
28487        pub fn whiteout_m3_M3Model_resize_ikTwoJoints(self_: *mut whiteout_M3Model, count: usize);
28488        pub fn whiteout_m3_M3Model_get_ikTwoJoints_at(
28489            self_: *mut whiteout_M3Model,
28490            index: usize,
28491        ) -> *mut whiteout_M3IKTwoJoint;
28492        pub fn whiteout_m3_M3Model_get_ikCCD_count(self_: *mut whiteout_M3Model) -> usize;
28493        pub fn whiteout_m3_M3Model_resize_ikCCD(self_: *mut whiteout_M3Model, count: usize);
28494        pub fn whiteout_m3_M3Model_get_ikCCD_at(
28495            self_: *mut whiteout_M3Model,
28496            index: usize,
28497        ) -> *mut whiteout_M3IKCCD;
28498        pub fn whiteout_m3_M3Model_get_ikJoints_count(self_: *mut whiteout_M3Model) -> usize;
28499        pub fn whiteout_m3_M3Model_resize_ikJoints(self_: *mut whiteout_M3Model, count: usize);
28500        pub fn whiteout_m3_M3Model_get_ikJoints_at(
28501            self_: *mut whiteout_M3Model,
28502            index: usize,
28503        ) -> *mut whiteout_M3IKJoint;
28504        pub fn whiteout_m3_M3Model_get_oneBoneSolvers_count(self_: *mut whiteout_M3Model) -> usize;
28505        pub fn whiteout_m3_M3Model_resize_oneBoneSolvers(
28506            self_: *mut whiteout_M3Model,
28507            count: usize,
28508        );
28509        pub fn whiteout_m3_M3Model_get_oneBoneSolvers_at(
28510            self_: *mut whiteout_M3Model,
28511            index: usize,
28512        ) -> *mut whiteout_M3OneBoneSolver;
28513        pub fn whiteout_m3_M3Model_get_turretBehaviors_count(self_: *mut whiteout_M3Model)
28514            -> usize;
28515        pub fn whiteout_m3_M3Model_resize_turretBehaviors(
28516            self_: *mut whiteout_M3Model,
28517            count: usize,
28518        );
28519        pub fn whiteout_m3_M3Model_get_turretBehaviors_at(
28520            self_: *mut whiteout_M3Model,
28521            index: usize,
28522        ) -> *mut whiteout_M3TurretBehavior;
28523        pub fn whiteout_m3_M3Model_get_triggerData_count(self_: *mut whiteout_M3Model) -> usize;
28524        pub fn whiteout_m3_M3Model_resize_triggerData(self_: *mut whiteout_M3Model, count: usize);
28525        pub fn whiteout_m3_M3Model_get_triggerData_at(
28526            self_: *mut whiteout_M3Model,
28527            index: usize,
28528        ) -> *mut whiteout_M3TriggerData;
28529        pub fn whiteout_m3_M3Model_get_initialReference_count(
28530            self_: *mut whiteout_M3Model,
28531        ) -> usize;
28532        pub fn whiteout_m3_M3Model_resize_initialReference(
28533            self_: *mut whiteout_M3Model,
28534            count: usize,
28535        );
28536        pub fn whiteout_m3_M3Model_get_initialReference_at(
28537            self_: *mut whiteout_M3Model,
28538            index: usize,
28539        ) -> *mut whiteout_M3InitialReference;
28540        pub fn whiteout_m3_M3Model_get_tightHitTestObject(
28541            self_: *mut whiteout_M3Model,
28542        ) -> *mut whiteout_M3HitTestShape;
28543        pub fn whiteout_m3_M3Model_set_tightHitTestObject(
28544            self_: *mut whiteout_M3Model,
28545            value: *const whiteout_M3HitTestShape,
28546        );
28547        pub fn whiteout_m3_M3Model_get_fuzzyHitTestObjects_count(
28548            self_: *mut whiteout_M3Model,
28549        ) -> usize;
28550        pub fn whiteout_m3_M3Model_resize_fuzzyHitTestObjects(
28551            self_: *mut whiteout_M3Model,
28552            count: usize,
28553        );
28554        pub fn whiteout_m3_M3Model_get_fuzzyHitTestObjects_at(
28555            self_: *mut whiteout_M3Model,
28556            index: usize,
28557        ) -> *mut whiteout_M3HitTestShape;
28558        pub fn whiteout_m3_M3Model_get_attachmentVolumes_count(
28559            self_: *mut whiteout_M3Model,
28560        ) -> usize;
28561        pub fn whiteout_m3_M3Model_resize_attachmentVolumes(
28562            self_: *mut whiteout_M3Model,
28563            count: usize,
28564        );
28565        pub fn whiteout_m3_M3Model_get_attachmentVolumes_at(
28566            self_: *mut whiteout_M3Model,
28567            index: usize,
28568        ) -> *mut whiteout_M3AttachmentVolume;
28569        pub fn whiteout_m3_M3Model_get_attachmentVolumesAddon0_count(
28570            self_: *mut whiteout_M3Model,
28571        ) -> usize;
28572        pub fn whiteout_m3_M3Model_resize_attachmentVolumesAddon0(
28573            self_: *mut whiteout_M3Model,
28574            count: usize,
28575        );
28576        pub fn whiteout_m3_M3Model_get_attachmentVolumesAddon0_data(
28577            self_: *mut whiteout_M3Model,
28578        ) -> *const u16;
28579        pub fn whiteout_m3_M3Model_assign_attachmentVolumesAddon0(
28580            self_: *mut whiteout_M3Model,
28581            data: *const u16,
28582            count: usize,
28583        );
28584        pub fn whiteout_m3_M3Model_get_attachmentVolumesAddon1_count(
28585            self_: *mut whiteout_M3Model,
28586        ) -> usize;
28587        pub fn whiteout_m3_M3Model_resize_attachmentVolumesAddon1(
28588            self_: *mut whiteout_M3Model,
28589            count: usize,
28590        );
28591        pub fn whiteout_m3_M3Model_get_attachmentVolumesAddon1_data(
28592            self_: *mut whiteout_M3Model,
28593        ) -> *const u16;
28594        pub fn whiteout_m3_M3Model_assign_attachmentVolumesAddon1(
28595            self_: *mut whiteout_M3Model,
28596            data: *const u16,
28597            count: usize,
28598        );
28599        pub fn whiteout_m3_M3Model_get_billboardBehaviors_count(
28600            self_: *mut whiteout_M3Model,
28601        ) -> usize;
28602        pub fn whiteout_m3_M3Model_resize_billboardBehaviors(
28603            self_: *mut whiteout_M3Model,
28604            count: usize,
28605        );
28606        pub fn whiteout_m3_M3Model_get_billboardBehaviors_at(
28607            self_: *mut whiteout_M3Model,
28608            index: usize,
28609        ) -> *mut whiteout_M3BillboardBehavior;
28610        pub fn whiteout_m3_M3Model_get_trailingModels_count(self_: *mut whiteout_M3Model) -> usize;
28611        pub fn whiteout_m3_M3Model_resize_trailingModels(
28612            self_: *mut whiteout_M3Model,
28613            count: usize,
28614        );
28615        pub fn whiteout_m3_M3Model_get_trailingModels_at(
28616            self_: *mut whiteout_M3Model,
28617            index: usize,
28618        ) -> *mut whiteout_M3TrailingModel;
28619        pub fn whiteout_m3_M3Model_get_m3aAnimHash(self_: *mut whiteout_M3Model) -> u32;
28620        pub fn whiteout_m3_M3Model_set_m3aAnimHash(self_: *mut whiteout_M3Model, value: u32);
28621        pub fn whiteout_m3_M3Model_get_m3aAnimHashes_count(self_: *mut whiteout_M3Model) -> usize;
28622        pub fn whiteout_m3_M3Model_resize_m3aAnimHashes(self_: *mut whiteout_M3Model, count: usize);
28623        pub fn whiteout_m3_M3Model_get_m3aAnimHashes_data(
28624            self_: *mut whiteout_M3Model,
28625        ) -> *const u32;
28626        pub fn whiteout_m3_M3Model_assign_m3aAnimHashes(
28627            self_: *mut whiteout_M3Model,
28628            data: *const u32,
28629            count: usize,
28630        );
28631        // Parser
28632        pub fn whiteout_m3_M3Parser_new() -> *mut whiteout_M3Parser;
28633        pub fn whiteout_m3_M3Parser_delete(self_: *mut whiteout_M3Parser);
28634        pub fn whiteout_m3_M3Parser_parse(
28635            self_: *mut whiteout_M3Parser,
28636            file_path: *const core::ffi::c_char,
28637        ) -> *mut whiteout_M3Model;
28638        pub fn whiteout_m3_M3Parser_parse_buffer(
28639            self_: *mut whiteout_M3Parser,
28640            buffer: *const u8,
28641            buffer_size: usize,
28642        ) -> *mut whiteout_M3Model;
28643        pub fn whiteout_m3_M3Parser_hasIssues(self_: *mut whiteout_M3Parser) -> i32;
28644        pub fn whiteout_m3_M3Parser_getIssues_count(self_: *mut whiteout_M3Parser) -> usize;
28645        pub fn whiteout_m3_M3Parser_getIssues_at(
28646            self_: *mut whiteout_M3Parser,
28647            index: usize,
28648        ) -> RawCString;
28649        // Writer
28650        pub fn whiteout_m3_M3Writer_new() -> *mut whiteout_M3Writer;
28651        pub fn whiteout_m3_M3Writer_delete(self_: *mut whiteout_M3Writer);
28652        pub fn whiteout_m3_M3Writer_write(
28653            self_: *mut whiteout_M3Writer,
28654            file_path: *const core::ffi::c_char,
28655            model: *mut whiteout_M3Model,
28656        );
28657        pub fn whiteout_m3_M3Writer_write_model(
28658            self_: *mut whiteout_M3Writer,
28659            model: *mut whiteout_M3Model,
28660        ) -> RawBytes;
28661        // AnimRefF32
28662        pub fn whiteout_m3_M3AnimRefF32_new() -> *mut whiteout_M3AnimRefF32;
28663        pub fn whiteout_m3_M3AnimRefF32_delete(self_: *mut whiteout_M3AnimRefF32);
28664        pub fn whiteout_m3_M3AnimRefF32_get_interpType(self_: *mut whiteout_M3AnimRefF32) -> u16;
28665        pub fn whiteout_m3_M3AnimRefF32_set_interpType(
28666            self_: *mut whiteout_M3AnimRefF32,
28667            value: u16,
28668        );
28669        pub fn whiteout_m3_M3AnimRefF32_get_flags(self_: *mut whiteout_M3AnimRefF32) -> u16;
28670        pub fn whiteout_m3_M3AnimRefF32_set_flags(self_: *mut whiteout_M3AnimRefF32, value: u16);
28671        pub fn whiteout_m3_M3AnimRefF32_get_animId(self_: *mut whiteout_M3AnimRefF32) -> u32;
28672        pub fn whiteout_m3_M3AnimRefF32_set_animId(self_: *mut whiteout_M3AnimRefF32, value: u32);
28673        pub fn whiteout_m3_M3AnimRefF32_get_initValue(self_: *mut whiteout_M3AnimRefF32) -> f32;
28674        pub fn whiteout_m3_M3AnimRefF32_set_initValue(
28675            self_: *mut whiteout_M3AnimRefF32,
28676            value: f32,
28677        );
28678        pub fn whiteout_m3_M3AnimRefF32_get_nullValue(self_: *mut whiteout_M3AnimRefF32) -> f32;
28679        pub fn whiteout_m3_M3AnimRefF32_set_nullValue(
28680            self_: *mut whiteout_M3AnimRefF32,
28681            value: f32,
28682        );
28683        pub fn whiteout_m3_M3AnimRefF32_get_unused(self_: *mut whiteout_M3AnimRefF32) -> i32;
28684        pub fn whiteout_m3_M3AnimRefF32_set_unused(self_: *mut whiteout_M3AnimRefF32, value: i32);
28685        // AnimRefVector3f
28686        pub fn whiteout_m3_M3AnimRefVector3f_new() -> *mut whiteout_M3AnimRefVector3f;
28687        pub fn whiteout_m3_M3AnimRefVector3f_delete(self_: *mut whiteout_M3AnimRefVector3f);
28688        pub fn whiteout_m3_M3AnimRefVector3f_get_interpType(
28689            self_: *mut whiteout_M3AnimRefVector3f,
28690        ) -> u16;
28691        pub fn whiteout_m3_M3AnimRefVector3f_set_interpType(
28692            self_: *mut whiteout_M3AnimRefVector3f,
28693            value: u16,
28694        );
28695        pub fn whiteout_m3_M3AnimRefVector3f_get_flags(
28696            self_: *mut whiteout_M3AnimRefVector3f,
28697        ) -> u16;
28698        pub fn whiteout_m3_M3AnimRefVector3f_set_flags(
28699            self_: *mut whiteout_M3AnimRefVector3f,
28700            value: u16,
28701        );
28702        pub fn whiteout_m3_M3AnimRefVector3f_get_animId(
28703            self_: *mut whiteout_M3AnimRefVector3f,
28704        ) -> u32;
28705        pub fn whiteout_m3_M3AnimRefVector3f_set_animId(
28706            self_: *mut whiteout_M3AnimRefVector3f,
28707            value: u32,
28708        );
28709        pub fn whiteout_m3_M3AnimRefVector3f_get_initValue(
28710            self_: *mut whiteout_M3AnimRefVector3f,
28711        ) -> *mut core::ffi::c_void;
28712        pub fn whiteout_m3_M3AnimRefVector3f_set_initValue(
28713            self_: *mut whiteout_M3AnimRefVector3f,
28714            value: *const core::ffi::c_void,
28715        );
28716        pub fn whiteout_m3_M3AnimRefVector3f_get_nullValue(
28717            self_: *mut whiteout_M3AnimRefVector3f,
28718        ) -> *mut core::ffi::c_void;
28719        pub fn whiteout_m3_M3AnimRefVector3f_set_nullValue(
28720            self_: *mut whiteout_M3AnimRefVector3f,
28721            value: *const core::ffi::c_void,
28722        );
28723        pub fn whiteout_m3_M3AnimRefVector3f_get_unused(
28724            self_: *mut whiteout_M3AnimRefVector3f,
28725        ) -> i32;
28726        pub fn whiteout_m3_M3AnimRefVector3f_set_unused(
28727            self_: *mut whiteout_M3AnimRefVector3f,
28728            value: i32,
28729        );
28730        // AnimRefM3ColorBGRA
28731        pub fn whiteout_m3_M3AnimRefM3ColorBGRA_new() -> *mut whiteout_M3AnimRefM3ColorBGRA;
28732        pub fn whiteout_m3_M3AnimRefM3ColorBGRA_delete(self_: *mut whiteout_M3AnimRefM3ColorBGRA);
28733        pub fn whiteout_m3_M3AnimRefM3ColorBGRA_get_interpType(
28734            self_: *mut whiteout_M3AnimRefM3ColorBGRA,
28735        ) -> u16;
28736        pub fn whiteout_m3_M3AnimRefM3ColorBGRA_set_interpType(
28737            self_: *mut whiteout_M3AnimRefM3ColorBGRA,
28738            value: u16,
28739        );
28740        pub fn whiteout_m3_M3AnimRefM3ColorBGRA_get_flags(
28741            self_: *mut whiteout_M3AnimRefM3ColorBGRA,
28742        ) -> u16;
28743        pub fn whiteout_m3_M3AnimRefM3ColorBGRA_set_flags(
28744            self_: *mut whiteout_M3AnimRefM3ColorBGRA,
28745            value: u16,
28746        );
28747        pub fn whiteout_m3_M3AnimRefM3ColorBGRA_get_animId(
28748            self_: *mut whiteout_M3AnimRefM3ColorBGRA,
28749        ) -> u32;
28750        pub fn whiteout_m3_M3AnimRefM3ColorBGRA_set_animId(
28751            self_: *mut whiteout_M3AnimRefM3ColorBGRA,
28752            value: u32,
28753        );
28754        pub fn whiteout_m3_M3AnimRefM3ColorBGRA_get_initValue(
28755            self_: *mut whiteout_M3AnimRefM3ColorBGRA,
28756        ) -> *mut whiteout_M3ColorBGRA;
28757        pub fn whiteout_m3_M3AnimRefM3ColorBGRA_set_initValue(
28758            self_: *mut whiteout_M3AnimRefM3ColorBGRA,
28759            value: *const whiteout_M3ColorBGRA,
28760        );
28761        pub fn whiteout_m3_M3AnimRefM3ColorBGRA_get_nullValue(
28762            self_: *mut whiteout_M3AnimRefM3ColorBGRA,
28763        ) -> *mut whiteout_M3ColorBGRA;
28764        pub fn whiteout_m3_M3AnimRefM3ColorBGRA_set_nullValue(
28765            self_: *mut whiteout_M3AnimRefM3ColorBGRA,
28766            value: *const whiteout_M3ColorBGRA,
28767        );
28768        pub fn whiteout_m3_M3AnimRefM3ColorBGRA_get_unused(
28769            self_: *mut whiteout_M3AnimRefM3ColorBGRA,
28770        ) -> i32;
28771        pub fn whiteout_m3_M3AnimRefM3ColorBGRA_set_unused(
28772            self_: *mut whiteout_M3AnimRefM3ColorBGRA,
28773            value: i32,
28774        );
28775        // AnimRefU16
28776        pub fn whiteout_m3_M3AnimRefU16_new() -> *mut whiteout_M3AnimRefU16;
28777        pub fn whiteout_m3_M3AnimRefU16_delete(self_: *mut whiteout_M3AnimRefU16);
28778        pub fn whiteout_m3_M3AnimRefU16_get_interpType(self_: *mut whiteout_M3AnimRefU16) -> u16;
28779        pub fn whiteout_m3_M3AnimRefU16_set_interpType(
28780            self_: *mut whiteout_M3AnimRefU16,
28781            value: u16,
28782        );
28783        pub fn whiteout_m3_M3AnimRefU16_get_flags(self_: *mut whiteout_M3AnimRefU16) -> u16;
28784        pub fn whiteout_m3_M3AnimRefU16_set_flags(self_: *mut whiteout_M3AnimRefU16, value: u16);
28785        pub fn whiteout_m3_M3AnimRefU16_get_animId(self_: *mut whiteout_M3AnimRefU16) -> u32;
28786        pub fn whiteout_m3_M3AnimRefU16_set_animId(self_: *mut whiteout_M3AnimRefU16, value: u32);
28787        pub fn whiteout_m3_M3AnimRefU16_get_initValue(self_: *mut whiteout_M3AnimRefU16) -> u16;
28788        pub fn whiteout_m3_M3AnimRefU16_set_initValue(
28789            self_: *mut whiteout_M3AnimRefU16,
28790            value: u16,
28791        );
28792        pub fn whiteout_m3_M3AnimRefU16_get_nullValue(self_: *mut whiteout_M3AnimRefU16) -> u16;
28793        pub fn whiteout_m3_M3AnimRefU16_set_nullValue(
28794            self_: *mut whiteout_M3AnimRefU16,
28795            value: u16,
28796        );
28797        pub fn whiteout_m3_M3AnimRefU16_get_unused(self_: *mut whiteout_M3AnimRefU16) -> i32;
28798        pub fn whiteout_m3_M3AnimRefU16_set_unused(self_: *mut whiteout_M3AnimRefU16, value: i32);
28799        // AnimRefVector2f
28800        pub fn whiteout_m3_M3AnimRefVector2f_new() -> *mut whiteout_M3AnimRefVector2f;
28801        pub fn whiteout_m3_M3AnimRefVector2f_delete(self_: *mut whiteout_M3AnimRefVector2f);
28802        pub fn whiteout_m3_M3AnimRefVector2f_get_interpType(
28803            self_: *mut whiteout_M3AnimRefVector2f,
28804        ) -> u16;
28805        pub fn whiteout_m3_M3AnimRefVector2f_set_interpType(
28806            self_: *mut whiteout_M3AnimRefVector2f,
28807            value: u16,
28808        );
28809        pub fn whiteout_m3_M3AnimRefVector2f_get_flags(
28810            self_: *mut whiteout_M3AnimRefVector2f,
28811        ) -> u16;
28812        pub fn whiteout_m3_M3AnimRefVector2f_set_flags(
28813            self_: *mut whiteout_M3AnimRefVector2f,
28814            value: u16,
28815        );
28816        pub fn whiteout_m3_M3AnimRefVector2f_get_animId(
28817            self_: *mut whiteout_M3AnimRefVector2f,
28818        ) -> u32;
28819        pub fn whiteout_m3_M3AnimRefVector2f_set_animId(
28820            self_: *mut whiteout_M3AnimRefVector2f,
28821            value: u32,
28822        );
28823        pub fn whiteout_m3_M3AnimRefVector2f_get_initValue(
28824            self_: *mut whiteout_M3AnimRefVector2f,
28825        ) -> *mut core::ffi::c_void;
28826        pub fn whiteout_m3_M3AnimRefVector2f_set_initValue(
28827            self_: *mut whiteout_M3AnimRefVector2f,
28828            value: *const core::ffi::c_void,
28829        );
28830        pub fn whiteout_m3_M3AnimRefVector2f_get_nullValue(
28831            self_: *mut whiteout_M3AnimRefVector2f,
28832        ) -> *mut core::ffi::c_void;
28833        pub fn whiteout_m3_M3AnimRefVector2f_set_nullValue(
28834            self_: *mut whiteout_M3AnimRefVector2f,
28835            value: *const core::ffi::c_void,
28836        );
28837        pub fn whiteout_m3_M3AnimRefVector2f_get_unused(
28838            self_: *mut whiteout_M3AnimRefVector2f,
28839        ) -> i32;
28840        pub fn whiteout_m3_M3AnimRefVector2f_set_unused(
28841            self_: *mut whiteout_M3AnimRefVector2f,
28842            value: i32,
28843        );
28844        // AnimRefU32
28845        pub fn whiteout_m3_M3AnimRefU32_new() -> *mut whiteout_M3AnimRefU32;
28846        pub fn whiteout_m3_M3AnimRefU32_delete(self_: *mut whiteout_M3AnimRefU32);
28847        pub fn whiteout_m3_M3AnimRefU32_get_interpType(self_: *mut whiteout_M3AnimRefU32) -> u16;
28848        pub fn whiteout_m3_M3AnimRefU32_set_interpType(
28849            self_: *mut whiteout_M3AnimRefU32,
28850            value: u16,
28851        );
28852        pub fn whiteout_m3_M3AnimRefU32_get_flags(self_: *mut whiteout_M3AnimRefU32) -> u16;
28853        pub fn whiteout_m3_M3AnimRefU32_set_flags(self_: *mut whiteout_M3AnimRefU32, value: u16);
28854        pub fn whiteout_m3_M3AnimRefU32_get_animId(self_: *mut whiteout_M3AnimRefU32) -> u32;
28855        pub fn whiteout_m3_M3AnimRefU32_set_animId(self_: *mut whiteout_M3AnimRefU32, value: u32);
28856        pub fn whiteout_m3_M3AnimRefU32_get_initValue(self_: *mut whiteout_M3AnimRefU32) -> u32;
28857        pub fn whiteout_m3_M3AnimRefU32_set_initValue(
28858            self_: *mut whiteout_M3AnimRefU32,
28859            value: u32,
28860        );
28861        pub fn whiteout_m3_M3AnimRefU32_get_nullValue(self_: *mut whiteout_M3AnimRefU32) -> u32;
28862        pub fn whiteout_m3_M3AnimRefU32_set_nullValue(
28863            self_: *mut whiteout_M3AnimRefU32,
28864            value: u32,
28865        );
28866        pub fn whiteout_m3_M3AnimRefU32_get_unused(self_: *mut whiteout_M3AnimRefU32) -> i32;
28867        pub fn whiteout_m3_M3AnimRefU32_set_unused(self_: *mut whiteout_M3AnimRefU32, value: i32);
28868        // AnimRefQuaternion
28869        pub fn whiteout_m3_M3AnimRefQuaternion_new() -> *mut whiteout_M3AnimRefQuaternion;
28870        pub fn whiteout_m3_M3AnimRefQuaternion_delete(self_: *mut whiteout_M3AnimRefQuaternion);
28871        pub fn whiteout_m3_M3AnimRefQuaternion_get_interpType(
28872            self_: *mut whiteout_M3AnimRefQuaternion,
28873        ) -> u16;
28874        pub fn whiteout_m3_M3AnimRefQuaternion_set_interpType(
28875            self_: *mut whiteout_M3AnimRefQuaternion,
28876            value: u16,
28877        );
28878        pub fn whiteout_m3_M3AnimRefQuaternion_get_flags(
28879            self_: *mut whiteout_M3AnimRefQuaternion,
28880        ) -> u16;
28881        pub fn whiteout_m3_M3AnimRefQuaternion_set_flags(
28882            self_: *mut whiteout_M3AnimRefQuaternion,
28883            value: u16,
28884        );
28885        pub fn whiteout_m3_M3AnimRefQuaternion_get_animId(
28886            self_: *mut whiteout_M3AnimRefQuaternion,
28887        ) -> u32;
28888        pub fn whiteout_m3_M3AnimRefQuaternion_set_animId(
28889            self_: *mut whiteout_M3AnimRefQuaternion,
28890            value: u32,
28891        );
28892        pub fn whiteout_m3_M3AnimRefQuaternion_get_initValue(
28893            self_: *mut whiteout_M3AnimRefQuaternion,
28894        ) -> *mut core::ffi::c_void;
28895        pub fn whiteout_m3_M3AnimRefQuaternion_set_initValue(
28896            self_: *mut whiteout_M3AnimRefQuaternion,
28897            value: *const core::ffi::c_void,
28898        );
28899        pub fn whiteout_m3_M3AnimRefQuaternion_get_nullValue(
28900            self_: *mut whiteout_M3AnimRefQuaternion,
28901        ) -> *mut core::ffi::c_void;
28902        pub fn whiteout_m3_M3AnimRefQuaternion_set_nullValue(
28903            self_: *mut whiteout_M3AnimRefQuaternion,
28904            value: *const core::ffi::c_void,
28905        );
28906        pub fn whiteout_m3_M3AnimRefQuaternion_get_unused(
28907            self_: *mut whiteout_M3AnimRefQuaternion,
28908        ) -> i32;
28909        pub fn whiteout_m3_M3AnimRefQuaternion_set_unused(
28910            self_: *mut whiteout_M3AnimRefQuaternion,
28911            value: i32,
28912        );
28913        // AnimRefM3Extent
28914        pub fn whiteout_m3_M3AnimRefM3Extent_new() -> *mut whiteout_M3AnimRefM3Extent;
28915        pub fn whiteout_m3_M3AnimRefM3Extent_delete(self_: *mut whiteout_M3AnimRefM3Extent);
28916        pub fn whiteout_m3_M3AnimRefM3Extent_get_interpType(
28917            self_: *mut whiteout_M3AnimRefM3Extent,
28918        ) -> u16;
28919        pub fn whiteout_m3_M3AnimRefM3Extent_set_interpType(
28920            self_: *mut whiteout_M3AnimRefM3Extent,
28921            value: u16,
28922        );
28923        pub fn whiteout_m3_M3AnimRefM3Extent_get_flags(
28924            self_: *mut whiteout_M3AnimRefM3Extent,
28925        ) -> u16;
28926        pub fn whiteout_m3_M3AnimRefM3Extent_set_flags(
28927            self_: *mut whiteout_M3AnimRefM3Extent,
28928            value: u16,
28929        );
28930        pub fn whiteout_m3_M3AnimRefM3Extent_get_animId(
28931            self_: *mut whiteout_M3AnimRefM3Extent,
28932        ) -> u32;
28933        pub fn whiteout_m3_M3AnimRefM3Extent_set_animId(
28934            self_: *mut whiteout_M3AnimRefM3Extent,
28935            value: u32,
28936        );
28937        pub fn whiteout_m3_M3AnimRefM3Extent_get_initValue(
28938            self_: *mut whiteout_M3AnimRefM3Extent,
28939        ) -> *mut whiteout_M3Extent;
28940        pub fn whiteout_m3_M3AnimRefM3Extent_set_initValue(
28941            self_: *mut whiteout_M3AnimRefM3Extent,
28942            value: *const whiteout_M3Extent,
28943        );
28944        pub fn whiteout_m3_M3AnimRefM3Extent_get_nullValue(
28945            self_: *mut whiteout_M3AnimRefM3Extent,
28946        ) -> *mut whiteout_M3Extent;
28947        pub fn whiteout_m3_M3AnimRefM3Extent_set_nullValue(
28948            self_: *mut whiteout_M3AnimRefM3Extent,
28949            value: *const whiteout_M3Extent,
28950        );
28951        pub fn whiteout_m3_M3AnimRefM3Extent_get_unused(
28952            self_: *mut whiteout_M3AnimRefM3Extent,
28953        ) -> i32;
28954        pub fn whiteout_m3_M3AnimRefM3Extent_set_unused(
28955            self_: *mut whiteout_M3AnimRefM3Extent,
28956            value: i32,
28957        );
28958    }
28959}