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    pub fn unknown_len() -> usize {
3084        // SAFETY: a compile-time constant on the native side.
3085        unsafe { ffi::whiteout_m3_M3AnimationState_unknown_size() }
3086    }
3087
3088    pub fn unknown(&self, index: usize) -> u8 {
3089        // SAFETY: scalar read. The native side does not bounds-
3090        // check, so callers stay within `unknown_len()`.
3091        unsafe { ffi::whiteout_m3_M3AnimationState_get_unknown_at(self.raw.as_ptr(), index) }
3092    }
3093
3094    pub fn set_unknown(&mut self, index: usize, value: u8) {
3095        // SAFETY: as above.
3096        unsafe { ffi::whiteout_m3_M3AnimationState_set_unknown_at(self.raw.as_ptr(), index, value) }
3097    }
3098}
3099
3100impl Default for AnimationState {
3101    fn default() -> Self {
3102        Self::new()
3103    }
3104}
3105
3106/// BSET — Bone animation set (v0, 32 bytes)
3107///
3108/// Maps a bone to specific animation sequences with fallback support. In practice, always null in observed corpus data.
3109pub struct BoneAnimationSet {
3110    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3BoneAnimationSet>,
3111}
3112
3113impl Drop for BoneAnimationSet {
3114    fn drop(&mut self) {
3115        // SAFETY: `raw` came from a native constructor and Drop runs once.
3116        unsafe { ffi::whiteout_m3_M3BoneAnimationSet_delete(self.raw.as_ptr()) }
3117    }
3118}
3119
3120impl BoneAnimationSet {
3121    /// # Safety
3122    /// `raw` must be a live handle this value takes ownership of.
3123    #[allow(dead_code)] // used by whichever methods return this type
3124    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3BoneAnimationSet) -> Option<Self> {
3125        core::ptr::NonNull::new(raw).map(|raw| BoneAnimationSet { raw })
3126    }
3127}
3128
3129// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
3130// is deliberately NOT implemented — the C++ types make no documented
3131// guarantee about concurrent use, and claiming one we haven't verified
3132// would be unsound. See `@bind thread_safe` in the plan.
3133unsafe impl Send for BoneAnimationSet {}
3134
3135impl core::fmt::Debug for BoneAnimationSet {
3136    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3137        f.debug_struct("BoneAnimationSet").finish_non_exhaustive()
3138    }
3139}
3140
3141impl BoneAnimationSet {
3142    /// # Panics
3143    /// Panics if the native allocation fails.
3144    pub fn new() -> Self {
3145        // SAFETY: the native constructor returns a live handle; a null here
3146        // means the library is unusable.
3147        unsafe {
3148            let raw = ffi::whiteout_m3_M3BoneAnimationSet_new();
3149            Self::from_raw(raw).expect("native BoneAnimationSet allocation failed")
3150        }
3151    }
3152
3153    /// Primary sequence index
3154    pub fn animation_sequence_index(&self) -> u16 {
3155        // SAFETY: plain scalar read through a live handle.
3156        unsafe { ffi::whiteout_m3_M3BoneAnimationSet_get_animationSequenceIndex(self.raw.as_ptr()) }
3157    }
3158
3159    pub fn set_animation_sequence_index(&mut self, value: u16) {
3160        // SAFETY: plain scalar write through a live handle.
3161        unsafe {
3162            ffi::whiteout_m3_M3BoneAnimationSet_set_animationSequenceIndex(self.raw.as_ptr(), value)
3163        }
3164    }
3165
3166    /// Fallback sequence index
3167    pub fn fallback_sequence_index(&self) -> u16 {
3168        // SAFETY: plain scalar read through a live handle.
3169        unsafe { ffi::whiteout_m3_M3BoneAnimationSet_get_fallbackSequenceIndex(self.raw.as_ptr()) }
3170    }
3171
3172    pub fn set_fallback_sequence_index(&mut self, value: u16) {
3173        // SAFETY: plain scalar write through a live handle.
3174        unsafe {
3175            ffi::whiteout_m3_M3BoneAnimationSet_set_fallbackSequenceIndex(self.raw.as_ptr(), value)
3176        }
3177    }
3178
3179    /// Set name (`Ref<CHAR>`)
3180    pub fn name(&self) -> String {
3181        // SAFETY: the native side hands over an owned CString.
3182        unsafe {
3183            crate::support::take_string(ffi::whiteout_m3_M3BoneAnimationSet_get_name(
3184                self.raw.as_ptr(),
3185            ))
3186        }
3187    }
3188
3189    pub fn set_name(&mut self, value: &str) {
3190        let value = std::ffi::CString::new(value).unwrap_or_default();
3191        // SAFETY: the pointer outlives the call.
3192        unsafe { ffi::whiteout_m3_M3BoneAnimationSet_set_name(self.raw.as_ptr(), value.as_ptr()) }
3193    }
3194
3195    /// Split item indices (U16_)
3196    /// Zero-copy view of the underlying `std::vector`.
3197    pub fn split_items(&self) -> &[u16] {
3198        // SAFETY: `_data`/`_count` describe one contiguous C++
3199        // allocation, borrowed for as long as `self` is.
3200        unsafe {
3201            let n = ffi::whiteout_m3_M3BoneAnimationSet_get_splitItems_count(self.raw.as_ptr());
3202            let p = ffi::whiteout_m3_M3BoneAnimationSet_get_splitItems_data(self.raw.as_ptr());
3203            if p.is_null() || n == 0 {
3204                &[]
3205            } else {
3206                core::slice::from_raw_parts(p, n)
3207            }
3208        }
3209    }
3210
3211    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
3212    pub fn split_items_mut(&mut self) -> &mut [u16] {
3213        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
3214        unsafe {
3215            let n = ffi::whiteout_m3_M3BoneAnimationSet_get_splitItems_count(self.raw.as_ptr());
3216            let p = ffi::whiteout_m3_M3BoneAnimationSet_get_splitItems_data(self.raw.as_ptr())
3217                as *mut u16;
3218            if p.is_null() || n == 0 {
3219                &mut []
3220            } else {
3221                core::slice::from_raw_parts_mut(p, n)
3222            }
3223        }
3224    }
3225
3226    pub fn set_split_items(&mut self, values: &[u16]) {
3227        // SAFETY: the native side copies `values` before returning.
3228        unsafe {
3229            ffi::whiteout_m3_M3BoneAnimationSet_assign_splitItems(
3230                self.raw.as_ptr(),
3231                values.as_ptr() as *const _,
3232                values.len(),
3233            )
3234        }
3235    }
3236
3237    pub fn resize_split_items(&mut self, count: usize) {
3238        // SAFETY: reallocation is safe here precisely because
3239        // `&mut self` means no slice borrow is outstanding.
3240        unsafe { ffi::whiteout_m3_M3BoneAnimationSet_resize_splitItems(self.raw.as_ptr(), count) }
3241    }
3242}
3243
3244impl Default for BoneAnimationSet {
3245    fn default() -> Self {
3246        Self::new()
3247    }
3248}
3249
3250/// PAR_ — Particle emitter (v10–v24, 1300–1496 bytes)
3251///
3252/// 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.
3253pub struct ParticleEmitter {
3254    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3ParticleEmitter>,
3255}
3256
3257impl Drop for ParticleEmitter {
3258    fn drop(&mut self) {
3259        // SAFETY: `raw` came from a native constructor and Drop runs once.
3260        unsafe { ffi::whiteout_m3_M3ParticleEmitter_delete(self.raw.as_ptr()) }
3261    }
3262}
3263
3264impl ParticleEmitter {
3265    /// # Safety
3266    /// `raw` must be a live handle this value takes ownership of.
3267    #[allow(dead_code)] // used by whichever methods return this type
3268    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3ParticleEmitter) -> Option<Self> {
3269        core::ptr::NonNull::new(raw).map(|raw| ParticleEmitter { raw })
3270    }
3271}
3272
3273// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
3274// is deliberately NOT implemented — the C++ types make no documented
3275// guarantee about concurrent use, and claiming one we haven't verified
3276// would be unsound. See `@bind thread_safe` in the plan.
3277unsafe impl Send for ParticleEmitter {}
3278
3279impl core::fmt::Debug for ParticleEmitter {
3280    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3281        f.debug_struct("ParticleEmitter").finish_non_exhaustive()
3282    }
3283}
3284
3285impl ParticleEmitter {
3286    /// # Panics
3287    /// Panics if the native allocation fails.
3288    pub fn new() -> Self {
3289        // SAFETY: the native constructor returns a live handle; a null here
3290        // means the library is unusable.
3291        unsafe {
3292            let raw = ffi::whiteout_m3_M3ParticleEmitter_new();
3293            Self::from_raw(raw).expect("native ParticleEmitter allocation failed")
3294        }
3295    }
3296
3297    /// Index into BONE array
3298    pub fn bone_index(&self) -> u32 {
3299        // SAFETY: plain scalar read through a live handle.
3300        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_boneIndex(self.raw.as_ptr()) }
3301    }
3302
3303    pub fn set_bone_index(&mut self, value: u32) {
3304        // SAFETY: plain scalar write through a live handle.
3305        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_boneIndex(self.raw.as_ptr(), value) }
3306    }
3307
3308    /// Index into MATM material map array
3309    pub fn material_index(&self) -> u32 {
3310        // SAFETY: plain scalar read through a live handle.
3311        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_materialIndex(self.raw.as_ptr()) }
3312    }
3313
3314    pub fn set_material_index(&mut self, value: u32) {
3315        // SAFETY: plain scalar write through a live handle.
3316        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_materialIndex(self.raw.as_ptr(), value) }
3317    }
3318
3319    pub fn additional_flags(&self) -> ParticleAdditionalFlag {
3320        // SAFETY: scalar read; a flag set accepts any bits.
3321        ParticleAdditionalFlag(unsafe {
3322            ffi::whiteout_m3_M3ParticleEmitter_get_additionalFlags(self.raw.as_ptr())
3323        })
3324    }
3325
3326    pub fn set_additional_flags(&mut self, value: ParticleAdditionalFlag) {
3327        // SAFETY: scalar write through a live handle.
3328        unsafe {
3329            ffi::whiteout_m3_M3ParticleEmitter_set_additionalFlags(self.raw.as_ptr(), value.0)
3330        }
3331    }
3332
3333    /// Initial particle speed
3334    /// Borrows the field in place — no copy, no allocation.
3335    pub fn initial_speed(&self) -> crate::support::Ref<'_, AnimRefF32> {
3336        // SAFETY: an interior pointer into `self`, valid for this
3337        // borrow and never freed by the `Ref`.
3338        unsafe {
3339            crate::support::Ref::new(AnimRefF32 {
3340                raw: core::ptr::NonNull::new_unchecked(
3341                    ffi::whiteout_m3_M3ParticleEmitter_get_initialSpeed(self.raw.as_ptr()),
3342                ),
3343            })
3344        }
3345    }
3346
3347    pub fn initial_speed_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
3348        // SAFETY: as above; `&mut self` guarantees exclusivity.
3349        unsafe {
3350            crate::support::RefMut::new(AnimRefF32 {
3351                raw: core::ptr::NonNull::new_unchecked(
3352                    ffi::whiteout_m3_M3ParticleEmitter_get_initialSpeed(self.raw.as_ptr()),
3353                ),
3354            })
3355        }
3356    }
3357
3358    /// Random speed variation
3359    /// Borrows the field in place — no copy, no allocation.
3360    pub fn initial_speed_random(&self) -> crate::support::Ref<'_, AnimRefF32> {
3361        // SAFETY: an interior pointer into `self`, valid for this
3362        // borrow and never freed by the `Ref`.
3363        unsafe {
3364            crate::support::Ref::new(AnimRefF32 {
3365                raw: core::ptr::NonNull::new_unchecked(
3366                    ffi::whiteout_m3_M3ParticleEmitter_get_initialSpeedRandom(self.raw.as_ptr()),
3367                ),
3368            })
3369        }
3370    }
3371
3372    pub fn initial_speed_random_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
3373        // SAFETY: as above; `&mut self` guarantees exclusivity.
3374        unsafe {
3375            crate::support::RefMut::new(AnimRefF32 {
3376                raw: core::ptr::NonNull::new_unchecked(
3377                    ffi::whiteout_m3_M3ParticleEmitter_get_initialSpeedRandom(self.raw.as_ptr()),
3378                ),
3379            })
3380        }
3381    }
3382
3383    /// Initial yaw angle
3384    /// Borrows the field in place — no copy, no allocation.
3385    pub fn initial_yaw(&self) -> crate::support::Ref<'_, AnimRefF32> {
3386        // SAFETY: an interior pointer into `self`, valid for this
3387        // borrow and never freed by the `Ref`.
3388        unsafe {
3389            crate::support::Ref::new(AnimRefF32 {
3390                raw: core::ptr::NonNull::new_unchecked(
3391                    ffi::whiteout_m3_M3ParticleEmitter_get_initialYaw(self.raw.as_ptr()),
3392                ),
3393            })
3394        }
3395    }
3396
3397    pub fn initial_yaw_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
3398        // SAFETY: as above; `&mut self` guarantees exclusivity.
3399        unsafe {
3400            crate::support::RefMut::new(AnimRefF32 {
3401                raw: core::ptr::NonNull::new_unchecked(
3402                    ffi::whiteout_m3_M3ParticleEmitter_get_initialYaw(self.raw.as_ptr()),
3403                ),
3404            })
3405        }
3406    }
3407
3408    /// Initial pitch angle
3409    /// Borrows the field in place — no copy, no allocation.
3410    pub fn initial_pitch(&self) -> crate::support::Ref<'_, AnimRefF32> {
3411        // SAFETY: an interior pointer into `self`, valid for this
3412        // borrow and never freed by the `Ref`.
3413        unsafe {
3414            crate::support::Ref::new(AnimRefF32 {
3415                raw: core::ptr::NonNull::new_unchecked(
3416                    ffi::whiteout_m3_M3ParticleEmitter_get_initialPitch(self.raw.as_ptr()),
3417                ),
3418            })
3419        }
3420    }
3421
3422    pub fn initial_pitch_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
3423        // SAFETY: as above; `&mut self` guarantees exclusivity.
3424        unsafe {
3425            crate::support::RefMut::new(AnimRefF32 {
3426                raw: core::ptr::NonNull::new_unchecked(
3427                    ffi::whiteout_m3_M3ParticleEmitter_get_initialPitch(self.raw.as_ptr()),
3428                ),
3429            })
3430        }
3431    }
3432
3433    /// Initial horizontal spread
3434    /// Borrows the field in place — no copy, no allocation.
3435    pub fn initial_horizontal(&self) -> crate::support::Ref<'_, AnimRefF32> {
3436        // SAFETY: an interior pointer into `self`, valid for this
3437        // borrow and never freed by the `Ref`.
3438        unsafe {
3439            crate::support::Ref::new(AnimRefF32 {
3440                raw: core::ptr::NonNull::new_unchecked(
3441                    ffi::whiteout_m3_M3ParticleEmitter_get_initialHorizontal(self.raw.as_ptr()),
3442                ),
3443            })
3444        }
3445    }
3446
3447    pub fn initial_horizontal_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
3448        // SAFETY: as above; `&mut self` guarantees exclusivity.
3449        unsafe {
3450            crate::support::RefMut::new(AnimRefF32 {
3451                raw: core::ptr::NonNull::new_unchecked(
3452                    ffi::whiteout_m3_M3ParticleEmitter_get_initialHorizontal(self.raw.as_ptr()),
3453                ),
3454            })
3455        }
3456    }
3457
3458    /// Initial vertical spread
3459    /// Borrows the field in place — no copy, no allocation.
3460    pub fn initial_vertical(&self) -> crate::support::Ref<'_, AnimRefF32> {
3461        // SAFETY: an interior pointer into `self`, valid for this
3462        // borrow and never freed by the `Ref`.
3463        unsafe {
3464            crate::support::Ref::new(AnimRefF32 {
3465                raw: core::ptr::NonNull::new_unchecked(
3466                    ffi::whiteout_m3_M3ParticleEmitter_get_initialVertical(self.raw.as_ptr()),
3467                ),
3468            })
3469        }
3470    }
3471
3472    pub fn initial_vertical_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
3473        // SAFETY: as above; `&mut self` guarantees exclusivity.
3474        unsafe {
3475            crate::support::RefMut::new(AnimRefF32 {
3476                raw: core::ptr::NonNull::new_unchecked(
3477                    ffi::whiteout_m3_M3ParticleEmitter_get_initialVertical(self.raw.as_ptr()),
3478                ),
3479            })
3480        }
3481    }
3482
3483    /// Base particle lifetime
3484    /// Borrows the field in place — no copy, no allocation.
3485    pub fn lifetime(&self) -> crate::support::Ref<'_, AnimRefF32> {
3486        // SAFETY: an interior pointer into `self`, valid for this
3487        // borrow and never freed by the `Ref`.
3488        unsafe {
3489            crate::support::Ref::new(AnimRefF32 {
3490                raw: core::ptr::NonNull::new_unchecked(
3491                    ffi::whiteout_m3_M3ParticleEmitter_get_lifetime(self.raw.as_ptr()),
3492                ),
3493            })
3494        }
3495    }
3496
3497    pub fn lifetime_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
3498        // SAFETY: as above; `&mut self` guarantees exclusivity.
3499        unsafe {
3500            crate::support::RefMut::new(AnimRefF32 {
3501                raw: core::ptr::NonNull::new_unchecked(
3502                    ffi::whiteout_m3_M3ParticleEmitter_get_lifetime(self.raw.as_ptr()),
3503                ),
3504            })
3505        }
3506    }
3507
3508    /// Random lifetime variation
3509    /// Borrows the field in place — no copy, no allocation.
3510    pub fn lifetime_random(&self) -> crate::support::Ref<'_, AnimRefF32> {
3511        // SAFETY: an interior pointer into `self`, valid for this
3512        // borrow and never freed by the `Ref`.
3513        unsafe {
3514            crate::support::Ref::new(AnimRefF32 {
3515                raw: core::ptr::NonNull::new_unchecked(
3516                    ffi::whiteout_m3_M3ParticleEmitter_get_lifetimeRandom(self.raw.as_ptr()),
3517                ),
3518            })
3519        }
3520    }
3521
3522    pub fn lifetime_random_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
3523        // SAFETY: as above; `&mut self` guarantees exclusivity.
3524        unsafe {
3525            crate::support::RefMut::new(AnimRefF32 {
3526                raw: core::ptr::NonNull::new_unchecked(
3527                    ffi::whiteout_m3_M3ParticleEmitter_get_lifetimeRandom(self.raw.as_ptr()),
3528                ),
3529            })
3530        }
3531    }
3532
3533    /// Kill radius (particles beyond this are destroyed)
3534    pub fn kill_radius(&self) -> f32 {
3535        // SAFETY: plain scalar read through a live handle.
3536        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_killRadius(self.raw.as_ptr()) }
3537    }
3538
3539    pub fn set_kill_radius(&mut self, value: f32) {
3540        // SAFETY: plain scalar write through a live handle.
3541        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_killRadius(self.raw.as_ptr(), value) }
3542    }
3543
3544    /// Gravity X component (expected 0)
3545    pub fn gravity_x(&self) -> u32 {
3546        // SAFETY: plain scalar read through a live handle.
3547        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_gravityX(self.raw.as_ptr()) }
3548    }
3549
3550    pub fn set_gravity_x(&mut self, value: u32) {
3551        // SAFETY: plain scalar write through a live handle.
3552        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_gravityX(self.raw.as_ptr(), value) }
3553    }
3554
3555    /// Gravity Y component (expected 0)
3556    pub fn gravity_y(&self) -> u32 {
3557        // SAFETY: plain scalar read through a live handle.
3558        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_gravityY(self.raw.as_ptr()) }
3559    }
3560
3561    pub fn set_gravity_y(&mut self, value: u32) {
3562        // SAFETY: plain scalar write through a live handle.
3563        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_gravityY(self.raw.as_ptr(), value) }
3564    }
3565
3566    /// Gravity Z component
3567    pub fn gravity(&self) -> f32 {
3568        // SAFETY: plain scalar read through a live handle.
3569        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_gravity(self.raw.as_ptr()) }
3570    }
3571
3572    pub fn set_gravity(&mut self, value: f32) {
3573        // SAFETY: plain scalar write through a live handle.
3574        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_gravity(self.raw.as_ptr(), value) }
3575    }
3576
3577    /// Size midpoint time (0–1, v12+)
3578    pub fn size_mid_time(&self) -> f32 {
3579        // SAFETY: plain scalar read through a live handle.
3580        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_sizeMidTime(self.raw.as_ptr()) }
3581    }
3582
3583    pub fn set_size_mid_time(&mut self, value: f32) {
3584        // SAFETY: plain scalar write through a live handle.
3585        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_sizeMidTime(self.raw.as_ptr(), value) }
3586    }
3587
3588    /// Color midpoint time (0–1, v12+)
3589    pub fn color_mid_time(&self) -> f32 {
3590        // SAFETY: plain scalar read through a live handle.
3591        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_colorMidTime(self.raw.as_ptr()) }
3592    }
3593
3594    pub fn set_color_mid_time(&mut self, value: f32) {
3595        // SAFETY: plain scalar write through a live handle.
3596        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_colorMidTime(self.raw.as_ptr(), value) }
3597    }
3598
3599    /// Alpha midpoint time (0–1, v12+)
3600    pub fn alpha_mid_time(&self) -> f32 {
3601        // SAFETY: plain scalar read through a live handle.
3602        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_alphaMidTime(self.raw.as_ptr()) }
3603    }
3604
3605    pub fn set_alpha_mid_time(&mut self, value: f32) {
3606        // SAFETY: plain scalar write through a live handle.
3607        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_alphaMidTime(self.raw.as_ptr(), value) }
3608    }
3609
3610    /// Rotation midpoint time (0–1, v12+)
3611    pub fn rotation_mid_time(&self) -> f32 {
3612        // SAFETY: plain scalar read through a live handle.
3613        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_rotationMidTime(self.raw.as_ptr()) }
3614    }
3615
3616    pub fn set_rotation_mid_time(&mut self, value: f32) {
3617        // SAFETY: plain scalar write through a live handle.
3618        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_rotationMidTime(self.raw.as_ptr(), value) }
3619    }
3620
3621    /// Size hold time at midpoint (v14+)
3622    pub fn size_mid_hold_time(&self) -> f32 {
3623        // SAFETY: plain scalar read through a live handle.
3624        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_sizeMidHoldTime(self.raw.as_ptr()) }
3625    }
3626
3627    pub fn set_size_mid_hold_time(&mut self, value: f32) {
3628        // SAFETY: plain scalar write through a live handle.
3629        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_sizeMidHoldTime(self.raw.as_ptr(), value) }
3630    }
3631
3632    /// Color hold time at midpoint (v14+)
3633    pub fn color_mid_hold_time(&self) -> f32 {
3634        // SAFETY: plain scalar read through a live handle.
3635        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_colorMidHoldTime(self.raw.as_ptr()) }
3636    }
3637
3638    pub fn set_color_mid_hold_time(&mut self, value: f32) {
3639        // SAFETY: plain scalar write through a live handle.
3640        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_colorMidHoldTime(self.raw.as_ptr(), value) }
3641    }
3642
3643    /// Alpha hold time at midpoint (v14+)
3644    pub fn alpha_mid_hold_time(&self) -> f32 {
3645        // SAFETY: plain scalar read through a live handle.
3646        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_alphaMidHoldTime(self.raw.as_ptr()) }
3647    }
3648
3649    pub fn set_alpha_mid_hold_time(&mut self, value: f32) {
3650        // SAFETY: plain scalar write through a live handle.
3651        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_alphaMidHoldTime(self.raw.as_ptr(), value) }
3652    }
3653
3654    /// Rotation hold time at midpoint (v14+)
3655    pub fn rotation_mid_hold_time(&self) -> f32 {
3656        // SAFETY: plain scalar read through a live handle.
3657        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_rotationMidHoldTime(self.raw.as_ptr()) }
3658    }
3659
3660    pub fn set_rotation_mid_hold_time(&mut self, value: f32) {
3661        // SAFETY: plain scalar write through a live handle.
3662        unsafe {
3663            ffi::whiteout_m3_M3ParticleEmitter_set_rotationMidHoldTime(self.raw.as_ptr(), value)
3664        }
3665    }
3666
3667    /// Size curve (start, mid, end)
3668    /// Borrows the field in place — no copy, no allocation.
3669    pub fn size_animation(&self) -> crate::support::Ref<'_, AnimRefVector3f> {
3670        // SAFETY: an interior pointer into `self`, valid for this
3671        // borrow and never freed by the `Ref`.
3672        unsafe {
3673            crate::support::Ref::new(AnimRefVector3f {
3674                raw: core::ptr::NonNull::new_unchecked(
3675                    ffi::whiteout_m3_M3ParticleEmitter_get_sizeAnimation(self.raw.as_ptr()),
3676                ),
3677            })
3678        }
3679    }
3680
3681    pub fn size_animation_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector3f> {
3682        // SAFETY: as above; `&mut self` guarantees exclusivity.
3683        unsafe {
3684            crate::support::RefMut::new(AnimRefVector3f {
3685                raw: core::ptr::NonNull::new_unchecked(
3686                    ffi::whiteout_m3_M3ParticleEmitter_get_sizeAnimation(self.raw.as_ptr()),
3687                ),
3688            })
3689        }
3690    }
3691
3692    /// Rotation curve (start, mid, end)
3693    /// Borrows the field in place — no copy, no allocation.
3694    pub fn rotation_animation(&self) -> crate::support::Ref<'_, AnimRefVector3f> {
3695        // SAFETY: an interior pointer into `self`, valid for this
3696        // borrow and never freed by the `Ref`.
3697        unsafe {
3698            crate::support::Ref::new(AnimRefVector3f {
3699                raw: core::ptr::NonNull::new_unchecked(
3700                    ffi::whiteout_m3_M3ParticleEmitter_get_rotationAnimation(self.raw.as_ptr()),
3701                ),
3702            })
3703        }
3704    }
3705
3706    pub fn rotation_animation_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector3f> {
3707        // SAFETY: as above; `&mut self` guarantees exclusivity.
3708        unsafe {
3709            crate::support::RefMut::new(AnimRefVector3f {
3710                raw: core::ptr::NonNull::new_unchecked(
3711                    ffi::whiteout_m3_M3ParticleEmitter_get_rotationAnimation(self.raw.as_ptr()),
3712                ),
3713            })
3714        }
3715    }
3716
3717    /// Color at birth
3718    /// Borrows the field in place — no copy, no allocation.
3719    pub fn color_start(&self) -> crate::support::Ref<'_, AnimRefM3ColorBGRA> {
3720        // SAFETY: an interior pointer into `self`, valid for this
3721        // borrow and never freed by the `Ref`.
3722        unsafe {
3723            crate::support::Ref::new(AnimRefM3ColorBGRA {
3724                raw: core::ptr::NonNull::new_unchecked(
3725                    ffi::whiteout_m3_M3ParticleEmitter_get_colorStart(self.raw.as_ptr()),
3726                ),
3727            })
3728        }
3729    }
3730
3731    pub fn color_start_mut(&mut self) -> crate::support::RefMut<'_, AnimRefM3ColorBGRA> {
3732        // SAFETY: as above; `&mut self` guarantees exclusivity.
3733        unsafe {
3734            crate::support::RefMut::new(AnimRefM3ColorBGRA {
3735                raw: core::ptr::NonNull::new_unchecked(
3736                    ffi::whiteout_m3_M3ParticleEmitter_get_colorStart(self.raw.as_ptr()),
3737                ),
3738            })
3739        }
3740    }
3741
3742    /// Color at midpoint
3743    /// Borrows the field in place — no copy, no allocation.
3744    pub fn color_mid(&self) -> crate::support::Ref<'_, AnimRefM3ColorBGRA> {
3745        // SAFETY: an interior pointer into `self`, valid for this
3746        // borrow and never freed by the `Ref`.
3747        unsafe {
3748            crate::support::Ref::new(AnimRefM3ColorBGRA {
3749                raw: core::ptr::NonNull::new_unchecked(
3750                    ffi::whiteout_m3_M3ParticleEmitter_get_colorMid(self.raw.as_ptr()),
3751                ),
3752            })
3753        }
3754    }
3755
3756    pub fn color_mid_mut(&mut self) -> crate::support::RefMut<'_, AnimRefM3ColorBGRA> {
3757        // SAFETY: as above; `&mut self` guarantees exclusivity.
3758        unsafe {
3759            crate::support::RefMut::new(AnimRefM3ColorBGRA {
3760                raw: core::ptr::NonNull::new_unchecked(
3761                    ffi::whiteout_m3_M3ParticleEmitter_get_colorMid(self.raw.as_ptr()),
3762                ),
3763            })
3764        }
3765    }
3766
3767    /// Color at death
3768    /// Borrows the field in place — no copy, no allocation.
3769    pub fn color_end(&self) -> crate::support::Ref<'_, AnimRefM3ColorBGRA> {
3770        // SAFETY: an interior pointer into `self`, valid for this
3771        // borrow and never freed by the `Ref`.
3772        unsafe {
3773            crate::support::Ref::new(AnimRefM3ColorBGRA {
3774                raw: core::ptr::NonNull::new_unchecked(
3775                    ffi::whiteout_m3_M3ParticleEmitter_get_colorEnd(self.raw.as_ptr()),
3776                ),
3777            })
3778        }
3779    }
3780
3781    pub fn color_end_mut(&mut self) -> crate::support::RefMut<'_, AnimRefM3ColorBGRA> {
3782        // SAFETY: as above; `&mut self` guarantees exclusivity.
3783        unsafe {
3784            crate::support::RefMut::new(AnimRefM3ColorBGRA {
3785                raw: core::ptr::NonNull::new_unchecked(
3786                    ffi::whiteout_m3_M3ParticleEmitter_get_colorEnd(self.raw.as_ptr()),
3787                ),
3788            })
3789        }
3790    }
3791
3792    /// Air drag coefficient
3793    pub fn drag(&self) -> f32 {
3794        // SAFETY: plain scalar read through a live handle.
3795        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_drag(self.raw.as_ptr()) }
3796    }
3797
3798    pub fn set_drag(&mut self, value: f32) {
3799        // SAFETY: plain scalar write through a live handle.
3800        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_drag(self.raw.as_ptr(), value) }
3801    }
3802
3803    /// Particle mass
3804    pub fn mass(&self) -> f32 {
3805        // SAFETY: plain scalar read through a live handle.
3806        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_mass(self.raw.as_ptr()) }
3807    }
3808
3809    pub fn set_mass(&mut self, value: f32) {
3810        // SAFETY: plain scalar write through a live handle.
3811        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_mass(self.raw.as_ptr(), value) }
3812    }
3813
3814    /// Random mass variation multiplier
3815    pub fn mass_random(&self) -> f32 {
3816        // SAFETY: plain scalar read through a live handle.
3817        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_massRandom(self.raw.as_ptr()) }
3818    }
3819
3820    pub fn set_mass_random(&mut self, value: f32) {
3821        // SAFETY: plain scalar write through a live handle.
3822        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_massRandom(self.raw.as_ptr(), value) }
3823    }
3824
3825    /// Mass–size coupling (v12+)
3826    pub fn mass_size_multiplier(&self) -> f32 {
3827        // SAFETY: plain scalar read through a live handle.
3828        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_massSizeMultiplier(self.raw.as_ptr()) }
3829    }
3830
3831    pub fn set_mass_size_multiplier(&mut self, value: f32) {
3832        // SAFETY: plain scalar write through a live handle.
3833        unsafe {
3834            ffi::whiteout_m3_M3ParticleEmitter_set_massSizeMultiplier(self.raw.as_ptr(), value)
3835        }
3836    }
3837
3838    /// Local force channel bitmask
3839    pub fn local_forces(&self) -> u16 {
3840        // SAFETY: plain scalar read through a live handle.
3841        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_localForces(self.raw.as_ptr()) }
3842    }
3843
3844    pub fn set_local_forces(&mut self, value: u16) {
3845        // SAFETY: plain scalar write through a live handle.
3846        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_localForces(self.raw.as_ptr(), value) }
3847    }
3848
3849    /// World force channel bitmask
3850    pub fn world_forces(&self) -> u16 {
3851        // SAFETY: plain scalar read through a live handle.
3852        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_worldForces(self.raw.as_ptr()) }
3853    }
3854
3855    pub fn set_world_forces(&mut self, value: u16) {
3856        // SAFETY: plain scalar write through a live handle.
3857        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_worldForces(self.raw.as_ptr(), value) }
3858    }
3859
3860    /// Fallback local force channels
3861    pub fn local_forces_fallback(&self) -> u16 {
3862        // SAFETY: plain scalar read through a live handle.
3863        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_localForcesFallback(self.raw.as_ptr()) }
3864    }
3865
3866    pub fn set_local_forces_fallback(&mut self, value: u16) {
3867        // SAFETY: plain scalar write through a live handle.
3868        unsafe {
3869            ffi::whiteout_m3_M3ParticleEmitter_set_localForcesFallback(self.raw.as_ptr(), value)
3870        }
3871    }
3872
3873    /// Fallback world force channels
3874    pub fn world_forces_fallback(&self) -> u16 {
3875        // SAFETY: plain scalar read through a live handle.
3876        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_worldForcesFallback(self.raw.as_ptr()) }
3877    }
3878
3879    pub fn set_world_forces_fallback(&mut self, value: u16) {
3880        // SAFETY: plain scalar write through a live handle.
3881        unsafe {
3882            ffi::whiteout_m3_M3ParticleEmitter_set_worldForcesFallback(self.raw.as_ptr(), value)
3883        }
3884    }
3885
3886    /// World force mass multiplier (v24+)
3887    pub fn world_forces_mass_multiplier(&self) -> f32 {
3888        // SAFETY: plain scalar read through a live handle.
3889        unsafe {
3890            ffi::whiteout_m3_M3ParticleEmitter_get_worldForcesMassMultiplier(self.raw.as_ptr())
3891        }
3892    }
3893
3894    pub fn set_world_forces_mass_multiplier(&mut self, value: f32) {
3895        // SAFETY: plain scalar write through a live handle.
3896        unsafe {
3897            ffi::whiteout_m3_M3ParticleEmitter_set_worldForcesMassMultiplier(
3898                self.raw.as_ptr(),
3899                value,
3900            )
3901        }
3902    }
3903
3904    /// Noise displacement amplitude
3905    pub fn noise_amplitude(&self) -> f32 {
3906        // SAFETY: plain scalar read through a live handle.
3907        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_noiseAmplitude(self.raw.as_ptr()) }
3908    }
3909
3910    pub fn set_noise_amplitude(&mut self, value: f32) {
3911        // SAFETY: plain scalar write through a live handle.
3912        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_noiseAmplitude(self.raw.as_ptr(), value) }
3913    }
3914
3915    /// Noise spatial frequency
3916    pub fn noise_frequency(&self) -> f32 {
3917        // SAFETY: plain scalar read through a live handle.
3918        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_noiseFrequency(self.raw.as_ptr()) }
3919    }
3920
3921    pub fn set_noise_frequency(&mut self, value: f32) {
3922        // SAFETY: plain scalar write through a live handle.
3923        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_noiseFrequency(self.raw.as_ptr(), value) }
3924    }
3925
3926    /// Noise temporal coherence
3927    pub fn noise_coherence(&self) -> f32 {
3928        // SAFETY: plain scalar read through a live handle.
3929        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_noiseCoherence(self.raw.as_ptr()) }
3930    }
3931
3932    pub fn set_noise_coherence(&mut self, value: f32) {
3933        // SAFETY: plain scalar write through a live handle.
3934        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_noiseCoherence(self.raw.as_ptr(), value) }
3935    }
3936
3937    /// Noise edge sharpness
3938    pub fn noise_edge(&self) -> f32 {
3939        // SAFETY: plain scalar read through a live handle.
3940        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_noiseEdge(self.raw.as_ptr()) }
3941    }
3942
3943    pub fn set_noise_edge(&mut self, value: f32) {
3944        // SAFETY: plain scalar write through a live handle.
3945        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_noiseEdge(self.raw.as_ptr(), value) }
3946    }
3947
3948    /// Index + length (v11+)
3949    pub fn index_plus_length(&self) -> u32 {
3950        // SAFETY: plain scalar read through a live handle.
3951        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_indexPlusLength(self.raw.as_ptr()) }
3952    }
3953
3954    pub fn set_index_plus_length(&mut self, value: u32) {
3955        // SAFETY: plain scalar write through a live handle.
3956        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_indexPlusLength(self.raw.as_ptr(), value) }
3957    }
3958
3959    /// Maximum live particle count
3960    pub fn max_particles(&self) -> u32 {
3961        // SAFETY: plain scalar read through a live handle.
3962        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_maxParticles(self.raw.as_ptr()) }
3963    }
3964
3965    pub fn set_max_particles(&mut self, value: u32) {
3966        // SAFETY: plain scalar write through a live handle.
3967        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_maxParticles(self.raw.as_ptr(), value) }
3968    }
3969
3970    /// Animated emission rate (particles/sec)
3971    /// Borrows the field in place — no copy, no allocation.
3972    pub fn emission_rate(&self) -> crate::support::Ref<'_, AnimRefF32> {
3973        // SAFETY: an interior pointer into `self`, valid for this
3974        // borrow and never freed by the `Ref`.
3975        unsafe {
3976            crate::support::Ref::new(AnimRefF32 {
3977                raw: core::ptr::NonNull::new_unchecked(
3978                    ffi::whiteout_m3_M3ParticleEmitter_get_emissionRate(self.raw.as_ptr()),
3979                ),
3980            })
3981        }
3982    }
3983
3984    pub fn emission_rate_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
3985        // SAFETY: as above; `&mut self` guarantees exclusivity.
3986        unsafe {
3987            crate::support::RefMut::new(AnimRefF32 {
3988                raw: core::ptr::NonNull::new_unchecked(
3989                    ffi::whiteout_m3_M3ParticleEmitter_get_emissionRate(self.raw.as_ptr()),
3990                ),
3991            })
3992        }
3993    }
3994
3995    /// Emission shape
3996    pub fn emitter_shape(&self) -> EmitterShape {
3997        // SAFETY: scalar read; the discriminant is validated below.
3998        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_emitterShape(self.raw.as_ptr()) }
3999            .try_into()
4000            .expect("unknown enum discriminant from the native library")
4001    }
4002
4003    pub fn set_emitter_shape(&mut self, value: EmitterShape) {
4004        // SAFETY: scalar write through a live handle.
4005        unsafe {
4006            ffi::whiteout_m3_M3ParticleEmitter_set_emitterShape(self.raw.as_ptr(), value as i32)
4007        }
4008    }
4009
4010    /// Animated outer shape dimensions
4011    /// Borrows the field in place — no copy, no allocation.
4012    pub fn shape_outer(&self) -> crate::support::Ref<'_, AnimRefVector3f> {
4013        // SAFETY: an interior pointer into `self`, valid for this
4014        // borrow and never freed by the `Ref`.
4015        unsafe {
4016            crate::support::Ref::new(AnimRefVector3f {
4017                raw: core::ptr::NonNull::new_unchecked(
4018                    ffi::whiteout_m3_M3ParticleEmitter_get_shapeOuter(self.raw.as_ptr()),
4019                ),
4020            })
4021        }
4022    }
4023
4024    pub fn shape_outer_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector3f> {
4025        // SAFETY: as above; `&mut self` guarantees exclusivity.
4026        unsafe {
4027            crate::support::RefMut::new(AnimRefVector3f {
4028                raw: core::ptr::NonNull::new_unchecked(
4029                    ffi::whiteout_m3_M3ParticleEmitter_get_shapeOuter(self.raw.as_ptr()),
4030                ),
4031            })
4032        }
4033    }
4034
4035    /// Animated inner shape dimensions
4036    /// Borrows the field in place — no copy, no allocation.
4037    pub fn shape_inner(&self) -> crate::support::Ref<'_, AnimRefVector3f> {
4038        // SAFETY: an interior pointer into `self`, valid for this
4039        // borrow and never freed by the `Ref`.
4040        unsafe {
4041            crate::support::Ref::new(AnimRefVector3f {
4042                raw: core::ptr::NonNull::new_unchecked(
4043                    ffi::whiteout_m3_M3ParticleEmitter_get_shapeInner(self.raw.as_ptr()),
4044                ),
4045            })
4046        }
4047    }
4048
4049    pub fn shape_inner_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector3f> {
4050        // SAFETY: as above; `&mut self` guarantees exclusivity.
4051        unsafe {
4052            crate::support::RefMut::new(AnimRefVector3f {
4053                raw: core::ptr::NonNull::new_unchecked(
4054                    ffi::whiteout_m3_M3ParticleEmitter_get_shapeInner(self.raw.as_ptr()),
4055                ),
4056            })
4057        }
4058    }
4059
4060    /// Animated outer radius
4061    /// Borrows the field in place — no copy, no allocation.
4062    pub fn outer_radius(&self) -> crate::support::Ref<'_, AnimRefF32> {
4063        // SAFETY: an interior pointer into `self`, valid for this
4064        // borrow and never freed by the `Ref`.
4065        unsafe {
4066            crate::support::Ref::new(AnimRefF32 {
4067                raw: core::ptr::NonNull::new_unchecked(
4068                    ffi::whiteout_m3_M3ParticleEmitter_get_outerRadius(self.raw.as_ptr()),
4069                ),
4070            })
4071        }
4072    }
4073
4074    pub fn outer_radius_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
4075        // SAFETY: as above; `&mut self` guarantees exclusivity.
4076        unsafe {
4077            crate::support::RefMut::new(AnimRefF32 {
4078                raw: core::ptr::NonNull::new_unchecked(
4079                    ffi::whiteout_m3_M3ParticleEmitter_get_outerRadius(self.raw.as_ptr()),
4080                ),
4081            })
4082        }
4083    }
4084
4085    /// Animated inner radius
4086    /// Borrows the field in place — no copy, no allocation.
4087    pub fn inner_radius(&self) -> crate::support::Ref<'_, AnimRefF32> {
4088        // SAFETY: an interior pointer into `self`, valid for this
4089        // borrow and never freed by the `Ref`.
4090        unsafe {
4091            crate::support::Ref::new(AnimRefF32 {
4092                raw: core::ptr::NonNull::new_unchecked(
4093                    ffi::whiteout_m3_M3ParticleEmitter_get_innerRadius(self.raw.as_ptr()),
4094                ),
4095            })
4096        }
4097    }
4098
4099    pub fn inner_radius_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
4100        // SAFETY: as above; `&mut self` guarantees exclusivity.
4101        unsafe {
4102            crate::support::RefMut::new(AnimRefF32 {
4103                raw: core::ptr::NonNull::new_unchecked(
4104                    ffi::whiteout_m3_M3ParticleEmitter_get_innerRadius(self.raw.as_ptr()),
4105                ),
4106            })
4107        }
4108    }
4109
4110    /// Shape region indices (U32_, v14+), which mesh region from div to use
4111    /// Zero-copy view of the underlying `std::vector`.
4112    pub fn shape_regions(&self) -> &[u32] {
4113        // SAFETY: `_data`/`_count` describe one contiguous C++
4114        // allocation, borrowed for as long as `self` is.
4115        unsafe {
4116            let n = ffi::whiteout_m3_M3ParticleEmitter_get_shapeRegions_count(self.raw.as_ptr());
4117            let p = ffi::whiteout_m3_M3ParticleEmitter_get_shapeRegions_data(self.raw.as_ptr());
4118            if p.is_null() || n == 0 {
4119                &[]
4120            } else {
4121                core::slice::from_raw_parts(p, n)
4122            }
4123        }
4124    }
4125
4126    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
4127    pub fn shape_regions_mut(&mut self) -> &mut [u32] {
4128        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
4129        unsafe {
4130            let n = ffi::whiteout_m3_M3ParticleEmitter_get_shapeRegions_count(self.raw.as_ptr());
4131            let p = ffi::whiteout_m3_M3ParticleEmitter_get_shapeRegions_data(self.raw.as_ptr())
4132                as *mut u32;
4133            if p.is_null() || n == 0 {
4134                &mut []
4135            } else {
4136                core::slice::from_raw_parts_mut(p, n)
4137            }
4138        }
4139    }
4140
4141    pub fn set_shape_regions(&mut self, values: &[u32]) {
4142        // SAFETY: the native side copies `values` before returning.
4143        unsafe {
4144            ffi::whiteout_m3_M3ParticleEmitter_assign_shapeRegions(
4145                self.raw.as_ptr(),
4146                values.as_ptr() as *const _,
4147                values.len(),
4148            )
4149        }
4150    }
4151
4152    pub fn resize_shape_regions(&mut self, count: usize) {
4153        // SAFETY: reallocation is safe here precisely because
4154        // `&mut self` means no slice borrow is outstanding.
4155        unsafe { ffi::whiteout_m3_M3ParticleEmitter_resize_shapeRegions(self.raw.as_ptr(), count) }
4156    }
4157
4158    /// Velocity randomization type
4159    pub fn velocity_type(&self) -> u32 {
4160        // SAFETY: plain scalar read through a live handle.
4161        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_velocityType(self.raw.as_ptr()) }
4162    }
4163
4164    pub fn set_velocity_type(&mut self, value: u32) {
4165        // SAFETY: plain scalar write through a live handle.
4166        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_velocityType(self.raw.as_ptr(), value) }
4167    }
4168
4169    /// Enable size randomization
4170    pub fn size_random_enable(&self) -> u32 {
4171        // SAFETY: plain scalar read through a live handle.
4172        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_sizeRandomEnable(self.raw.as_ptr()) }
4173    }
4174
4175    pub fn set_size_random_enable(&mut self, value: u32) {
4176        // SAFETY: plain scalar write through a live handle.
4177        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_sizeRandomEnable(self.raw.as_ptr(), value) }
4178    }
4179
4180    /// Random size curve
4181    /// Borrows the field in place — no copy, no allocation.
4182    pub fn size_random_animation(&self) -> crate::support::Ref<'_, AnimRefVector3f> {
4183        // SAFETY: an interior pointer into `self`, valid for this
4184        // borrow and never freed by the `Ref`.
4185        unsafe {
4186            crate::support::Ref::new(AnimRefVector3f {
4187                raw: core::ptr::NonNull::new_unchecked(
4188                    ffi::whiteout_m3_M3ParticleEmitter_get_sizeRandomAnimation(self.raw.as_ptr()),
4189                ),
4190            })
4191        }
4192    }
4193
4194    pub fn size_random_animation_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector3f> {
4195        // SAFETY: as above; `&mut self` guarantees exclusivity.
4196        unsafe {
4197            crate::support::RefMut::new(AnimRefVector3f {
4198                raw: core::ptr::NonNull::new_unchecked(
4199                    ffi::whiteout_m3_M3ParticleEmitter_get_sizeRandomAnimation(self.raw.as_ptr()),
4200                ),
4201            })
4202        }
4203    }
4204
4205    /// Enable rotation randomization
4206    pub fn rotation_random_enable(&self) -> u32 {
4207        // SAFETY: plain scalar read through a live handle.
4208        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_rotationRandomEnable(self.raw.as_ptr()) }
4209    }
4210
4211    pub fn set_rotation_random_enable(&mut self, value: u32) {
4212        // SAFETY: plain scalar write through a live handle.
4213        unsafe {
4214            ffi::whiteout_m3_M3ParticleEmitter_set_rotationRandomEnable(self.raw.as_ptr(), value)
4215        }
4216    }
4217
4218    /// Random rotation curve
4219    /// Borrows the field in place — no copy, no allocation.
4220    pub fn rotation_random_animation(&self) -> crate::support::Ref<'_, AnimRefVector3f> {
4221        // SAFETY: an interior pointer into `self`, valid for this
4222        // borrow and never freed by the `Ref`.
4223        unsafe {
4224            crate::support::Ref::new(AnimRefVector3f {
4225                raw: core::ptr::NonNull::new_unchecked(
4226                    ffi::whiteout_m3_M3ParticleEmitter_get_rotationRandomAnimation(
4227                        self.raw.as_ptr(),
4228                    ),
4229                ),
4230            })
4231        }
4232    }
4233
4234    pub fn rotation_random_animation_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector3f> {
4235        // SAFETY: as above; `&mut self` guarantees exclusivity.
4236        unsafe {
4237            crate::support::RefMut::new(AnimRefVector3f {
4238                raw: core::ptr::NonNull::new_unchecked(
4239                    ffi::whiteout_m3_M3ParticleEmitter_get_rotationRandomAnimation(
4240                        self.raw.as_ptr(),
4241                    ),
4242                ),
4243            })
4244        }
4245    }
4246
4247    /// Enable color randomization
4248    pub fn color_random_enable(&self) -> u32 {
4249        // SAFETY: plain scalar read through a live handle.
4250        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_colorRandomEnable(self.raw.as_ptr()) }
4251    }
4252
4253    pub fn set_color_random_enable(&mut self, value: u32) {
4254        // SAFETY: plain scalar write through a live handle.
4255        unsafe {
4256            ffi::whiteout_m3_M3ParticleEmitter_set_colorRandomEnable(self.raw.as_ptr(), value)
4257        }
4258    }
4259
4260    /// Random color at birth
4261    /// Borrows the field in place — no copy, no allocation.
4262    pub fn color_start_random(&self) -> crate::support::Ref<'_, AnimRefM3ColorBGRA> {
4263        // SAFETY: an interior pointer into `self`, valid for this
4264        // borrow and never freed by the `Ref`.
4265        unsafe {
4266            crate::support::Ref::new(AnimRefM3ColorBGRA {
4267                raw: core::ptr::NonNull::new_unchecked(
4268                    ffi::whiteout_m3_M3ParticleEmitter_get_colorStartRandom(self.raw.as_ptr()),
4269                ),
4270            })
4271        }
4272    }
4273
4274    pub fn color_start_random_mut(&mut self) -> crate::support::RefMut<'_, AnimRefM3ColorBGRA> {
4275        // SAFETY: as above; `&mut self` guarantees exclusivity.
4276        unsafe {
4277            crate::support::RefMut::new(AnimRefM3ColorBGRA {
4278                raw: core::ptr::NonNull::new_unchecked(
4279                    ffi::whiteout_m3_M3ParticleEmitter_get_colorStartRandom(self.raw.as_ptr()),
4280                ),
4281            })
4282        }
4283    }
4284
4285    /// Random color at midpoint
4286    /// Borrows the field in place — no copy, no allocation.
4287    pub fn color_mid_random(&self) -> crate::support::Ref<'_, AnimRefM3ColorBGRA> {
4288        // SAFETY: an interior pointer into `self`, valid for this
4289        // borrow and never freed by the `Ref`.
4290        unsafe {
4291            crate::support::Ref::new(AnimRefM3ColorBGRA {
4292                raw: core::ptr::NonNull::new_unchecked(
4293                    ffi::whiteout_m3_M3ParticleEmitter_get_colorMidRandom(self.raw.as_ptr()),
4294                ),
4295            })
4296        }
4297    }
4298
4299    pub fn color_mid_random_mut(&mut self) -> crate::support::RefMut<'_, AnimRefM3ColorBGRA> {
4300        // SAFETY: as above; `&mut self` guarantees exclusivity.
4301        unsafe {
4302            crate::support::RefMut::new(AnimRefM3ColorBGRA {
4303                raw: core::ptr::NonNull::new_unchecked(
4304                    ffi::whiteout_m3_M3ParticleEmitter_get_colorMidRandom(self.raw.as_ptr()),
4305                ),
4306            })
4307        }
4308    }
4309
4310    /// Random color at death
4311    /// Borrows the field in place — no copy, no allocation.
4312    pub fn color_end_random(&self) -> crate::support::Ref<'_, AnimRefM3ColorBGRA> {
4313        // SAFETY: an interior pointer into `self`, valid for this
4314        // borrow and never freed by the `Ref`.
4315        unsafe {
4316            crate::support::Ref::new(AnimRefM3ColorBGRA {
4317                raw: core::ptr::NonNull::new_unchecked(
4318                    ffi::whiteout_m3_M3ParticleEmitter_get_colorEndRandom(self.raw.as_ptr()),
4319                ),
4320            })
4321        }
4322    }
4323
4324    pub fn color_end_random_mut(&mut self) -> crate::support::RefMut<'_, AnimRefM3ColorBGRA> {
4325        // SAFETY: as above; `&mut self` guarantees exclusivity.
4326        unsafe {
4327            crate::support::RefMut::new(AnimRefM3ColorBGRA {
4328                raw: core::ptr::NonNull::new_unchecked(
4329                    ffi::whiteout_m3_M3ParticleEmitter_get_colorEndRandom(self.raw.as_ptr()),
4330                ),
4331            })
4332        }
4333    }
4334
4335    /// Enable alpha randomization
4336    pub fn alpha_random_enable(&self) -> u32 {
4337        // SAFETY: plain scalar read through a live handle.
4338        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_alphaRandomEnable(self.raw.as_ptr()) }
4339    }
4340
4341    pub fn set_alpha_random_enable(&mut self, value: u32) {
4342        // SAFETY: plain scalar write through a live handle.
4343        unsafe {
4344            ffi::whiteout_m3_M3ParticleEmitter_set_alphaRandomEnable(self.raw.as_ptr(), value)
4345        }
4346    }
4347
4348    /// Animated squirt burst count
4349    /// Borrows the field in place — no copy, no allocation.
4350    pub fn squirt_amount(&self) -> crate::support::Ref<'_, AnimRefU16> {
4351        // SAFETY: an interior pointer into `self`, valid for this
4352        // borrow and never freed by the `Ref`.
4353        unsafe {
4354            crate::support::Ref::new(AnimRefU16 {
4355                raw: core::ptr::NonNull::new_unchecked(
4356                    ffi::whiteout_m3_M3ParticleEmitter_get_squirtAmount(self.raw.as_ptr()),
4357                ),
4358            })
4359        }
4360    }
4361
4362    pub fn squirt_amount_mut(&mut self) -> crate::support::RefMut<'_, AnimRefU16> {
4363        // SAFETY: as above; `&mut self` guarantees exclusivity.
4364        unsafe {
4365            crate::support::RefMut::new(AnimRefU16 {
4366                raw: core::ptr::NonNull::new_unchecked(
4367                    ffi::whiteout_m3_M3ParticleEmitter_get_squirtAmount(self.raw.as_ptr()),
4368                ),
4369            })
4370        }
4371    }
4372
4373    /// Flipbook start initial frame index
4374    pub fn flipbook_start_init_index(&self) -> u8 {
4375        // SAFETY: plain scalar read through a live handle.
4376        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_flipbookStartInitIndex(self.raw.as_ptr()) }
4377    }
4378
4379    pub fn set_flipbook_start_init_index(&mut self, value: u8) {
4380        // SAFETY: plain scalar write through a live handle.
4381        unsafe {
4382            ffi::whiteout_m3_M3ParticleEmitter_set_flipbookStartInitIndex(self.raw.as_ptr(), value)
4383        }
4384    }
4385
4386    /// Flipbook start stop frame index
4387    pub fn flipbook_start_stop_index(&self) -> u8 {
4388        // SAFETY: plain scalar read through a live handle.
4389        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_flipbookStartStopIndex(self.raw.as_ptr()) }
4390    }
4391
4392    pub fn set_flipbook_start_stop_index(&mut self, value: u8) {
4393        // SAFETY: plain scalar write through a live handle.
4394        unsafe {
4395            ffi::whiteout_m3_M3ParticleEmitter_set_flipbookStartStopIndex(self.raw.as_ptr(), value)
4396        }
4397    }
4398
4399    /// Flipbook end initial frame index
4400    pub fn flipbook_end_init_index(&self) -> u8 {
4401        // SAFETY: plain scalar read through a live handle.
4402        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_flipbookEndInitIndex(self.raw.as_ptr()) }
4403    }
4404
4405    pub fn set_flipbook_end_init_index(&mut self, value: u8) {
4406        // SAFETY: plain scalar write through a live handle.
4407        unsafe {
4408            ffi::whiteout_m3_M3ParticleEmitter_set_flipbookEndInitIndex(self.raw.as_ptr(), value)
4409        }
4410    }
4411
4412    /// Flipbook end stop frame index
4413    pub fn flipbook_end_stop_index(&self) -> u8 {
4414        // SAFETY: plain scalar read through a live handle.
4415        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_flipbookEndStopIndex(self.raw.as_ptr()) }
4416    }
4417
4418    pub fn set_flipbook_end_stop_index(&mut self, value: u8) {
4419        // SAFETY: plain scalar write through a live handle.
4420        unsafe {
4421            ffi::whiteout_m3_M3ParticleEmitter_set_flipbookEndStopIndex(self.raw.as_ptr(), value)
4422        }
4423    }
4424
4425    /// Flipbook midpoint time (0–1)
4426    pub fn flipbook_mid_time(&self) -> f32 {
4427        // SAFETY: plain scalar read through a live handle.
4428        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_flipbookMidTime(self.raw.as_ptr()) }
4429    }
4430
4431    pub fn set_flipbook_mid_time(&mut self, value: f32) {
4432        // SAFETY: plain scalar write through a live handle.
4433        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_flipbookMidTime(self.raw.as_ptr(), value) }
4434    }
4435
4436    /// Flipbook grid columns
4437    pub fn flipbook_columns(&self) -> u16 {
4438        // SAFETY: plain scalar read through a live handle.
4439        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_flipbookColumns(self.raw.as_ptr()) }
4440    }
4441
4442    pub fn set_flipbook_columns(&mut self, value: u16) {
4443        // SAFETY: plain scalar write through a live handle.
4444        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_flipbookColumns(self.raw.as_ptr(), value) }
4445    }
4446
4447    /// Flipbook grid rows
4448    pub fn flipbook_rows(&self) -> u16 {
4449        // SAFETY: plain scalar read through a live handle.
4450        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_flipbookRows(self.raw.as_ptr()) }
4451    }
4452
4453    pub fn set_flipbook_rows(&mut self, value: u16) {
4454        // SAFETY: plain scalar write through a live handle.
4455        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_flipbookRows(self.raw.as_ptr(), value) }
4456    }
4457
4458    /// Column fraction (v12+)
4459    pub fn flipbook_column_fraction(&self) -> f32 {
4460        // SAFETY: plain scalar read through a live handle.
4461        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_flipbookColumnFraction(self.raw.as_ptr()) }
4462    }
4463
4464    pub fn set_flipbook_column_fraction(&mut self, value: f32) {
4465        // SAFETY: plain scalar write through a live handle.
4466        unsafe {
4467            ffi::whiteout_m3_M3ParticleEmitter_set_flipbookColumnFraction(self.raw.as_ptr(), value)
4468        }
4469    }
4470
4471    /// Row fraction (v12+)
4472    pub fn flipbook_row_fraction(&self) -> f32 {
4473        // SAFETY: plain scalar read through a live handle.
4474        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_flipbookRowFraction(self.raw.as_ptr()) }
4475    }
4476
4477    pub fn set_flipbook_row_fraction(&mut self, value: f32) {
4478        // SAFETY: plain scalar write through a live handle.
4479        unsafe {
4480            ffi::whiteout_m3_M3ParticleEmitter_set_flipbookRowFraction(self.raw.as_ptr(), value)
4481        }
4482    }
4483
4484    /// Bounce coefficient
4485    pub fn bounce(&self) -> f32 {
4486        // SAFETY: plain scalar read through a live handle.
4487        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_bounce(self.raw.as_ptr()) }
4488    }
4489
4490    pub fn set_bounce(&mut self, value: f32) {
4491        // SAFETY: plain scalar write through a live handle.
4492        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_bounce(self.raw.as_ptr(), value) }
4493    }
4494
4495    /// Friction coefficient
4496    pub fn friction(&self) -> f32 {
4497        // SAFETY: plain scalar read through a live handle.
4498        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_friction(self.raw.as_ptr()) }
4499    }
4500
4501    pub fn set_friction(&mut self, value: f32) {
4502        // SAFETY: plain scalar write through a live handle.
4503        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_friction(self.raw.as_ptr(), value) }
4504    }
4505
4506    /// Emitter index to spawn on collision (-1 = none)
4507    pub fn collision_spawn_index(&self) -> i32 {
4508        // SAFETY: plain scalar read through a live handle.
4509        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_collisionSpawnIndex(self.raw.as_ptr()) }
4510    }
4511
4512    pub fn set_collision_spawn_index(&mut self, value: i32) {
4513        // SAFETY: plain scalar write through a live handle.
4514        unsafe {
4515            ffi::whiteout_m3_M3ParticleEmitter_set_collisionSpawnIndex(self.raw.as_ptr(), value)
4516        }
4517    }
4518
4519    /// Minimum spawn count on collision
4520    pub fn collision_spawn_min(&self) -> u32 {
4521        // SAFETY: plain scalar read through a live handle.
4522        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_collisionSpawnMin(self.raw.as_ptr()) }
4523    }
4524
4525    pub fn set_collision_spawn_min(&mut self, value: u32) {
4526        // SAFETY: plain scalar write through a live handle.
4527        unsafe {
4528            ffi::whiteout_m3_M3ParticleEmitter_set_collisionSpawnMin(self.raw.as_ptr(), value)
4529        }
4530    }
4531
4532    /// Maximum spawn count on collision
4533    pub fn collision_spawn_max(&self) -> u32 {
4534        // SAFETY: plain scalar read through a live handle.
4535        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_collisionSpawnMax(self.raw.as_ptr()) }
4536    }
4537
4538    pub fn set_collision_spawn_max(&mut self, value: u32) {
4539        // SAFETY: plain scalar write through a live handle.
4540        unsafe {
4541            ffi::whiteout_m3_M3ParticleEmitter_set_collisionSpawnMax(self.raw.as_ptr(), value)
4542        }
4543    }
4544
4545    /// Spawn probability on collision
4546    pub fn collision_spawn_chance(&self) -> f32 {
4547        // SAFETY: plain scalar read through a live handle.
4548        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_collisionSpawnChance(self.raw.as_ptr()) }
4549    }
4550
4551    pub fn set_collision_spawn_chance(&mut self, value: f32) {
4552        // SAFETY: plain scalar write through a live handle.
4553        unsafe {
4554            ffi::whiteout_m3_M3ParticleEmitter_set_collisionSpawnChance(self.raw.as_ptr(), value)
4555        }
4556    }
4557
4558    /// Spawn energy transfer
4559    pub fn collision_spawn_energy(&self) -> f32 {
4560        // SAFETY: plain scalar read through a live handle.
4561        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_collisionSpawnEnergy(self.raw.as_ptr()) }
4562    }
4563
4564    pub fn set_collision_spawn_energy(&mut self, value: f32) {
4565        // SAFETY: plain scalar write through a live handle.
4566        unsafe {
4567            ffi::whiteout_m3_M3ParticleEmitter_set_collisionSpawnEnergy(self.raw.as_ptr(), value)
4568        }
4569    }
4570
4571    /// Die after N bounces
4572    pub fn collision_die_bounce(&self) -> u32 {
4573        // SAFETY: plain scalar read through a live handle.
4574        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_collisionDieBounce(self.raw.as_ptr()) }
4575    }
4576
4577    pub fn set_collision_die_bounce(&mut self, value: u32) {
4578        // SAFETY: plain scalar write through a live handle.
4579        unsafe {
4580            ffi::whiteout_m3_M3ParticleEmitter_set_collisionDieBounce(self.raw.as_ptr(), value)
4581        }
4582    }
4583
4584    /// Visual type → shader b_iInstanceType
4585    pub fn instance_type(&self) -> ParticleInstanceType {
4586        // SAFETY: scalar read; the discriminant is validated below.
4587        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_instanceType(self.raw.as_ptr()) }
4588            .try_into()
4589            .expect("unknown enum discriminant from the native library")
4590    }
4591
4592    pub fn set_instance_type(&mut self, value: ParticleInstanceType) {
4593        // SAFETY: scalar write through a live handle.
4594        unsafe {
4595            ffi::whiteout_m3_M3ParticleEmitter_set_instanceType(self.raw.as_ptr(), value as i32)
4596        }
4597    }
4598
4599    /// Tail length for Tail/Trail types
4600    pub fn tail_length(&self) -> f32 {
4601        // SAFETY: plain scalar read through a live handle.
4602        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_tailLength(self.raw.as_ptr()) }
4603    }
4604
4605    pub fn set_tail_length(&mut self, value: f32) {
4606        // SAFETY: plain scalar write through a live handle.
4607        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_tailLength(self.raw.as_ptr(), value) }
4608    }
4609
4610    /// Instance orientation angles
4611    pub fn instance_angle(&self) -> crate::math::Vector3f {
4612        // SAFETY: the getter returns an interior pointer to a
4613        // layout-identical POD; we copy it out immediately.
4614        unsafe {
4615            *(ffi::whiteout_m3_M3ParticleEmitter_get_instanceAngle(self.raw.as_ptr())
4616                as *const crate::math::Vector3f)
4617        }
4618    }
4619
4620    pub fn set_instance_angle(&mut self, value: crate::math::Vector3f) {
4621        // SAFETY: as above, in the other direction.
4622        unsafe {
4623            ffi::whiteout_m3_M3ParticleEmitter_set_instanceAngle(
4624                self.raw.as_ptr(),
4625                &value as *const crate::math::Vector3f as *const _,
4626            )
4627        }
4628    }
4629
4630    /// Instance distance (v17+)
4631    pub fn instance_distance(&self) -> f32 {
4632        // SAFETY: plain scalar read through a live handle.
4633        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_instanceDistance(self.raw.as_ptr()) }
4634    }
4635
4636    pub fn set_instance_distance(&mut self, value: f32) {
4637        // SAFETY: plain scalar write through a live handle.
4638        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_instanceDistance(self.raw.as_ptr(), value) }
4639    }
4640
4641    /// Pitch variation type
4642    pub fn pitch_type(&self) -> u32 {
4643        // SAFETY: plain scalar read through a live handle.
4644        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_pitchType(self.raw.as_ptr()) }
4645    }
4646
4647    pub fn set_pitch_type(&mut self, value: u32) {
4648        // SAFETY: plain scalar write through a live handle.
4649        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_pitchType(self.raw.as_ptr(), value) }
4650    }
4651
4652    /// Pitch variation amplitude
4653    /// Borrows the field in place — no copy, no allocation.
4654    pub fn pitch_amplitude(&self) -> crate::support::Ref<'_, AnimRefF32> {
4655        // SAFETY: an interior pointer into `self`, valid for this
4656        // borrow and never freed by the `Ref`.
4657        unsafe {
4658            crate::support::Ref::new(AnimRefF32 {
4659                raw: core::ptr::NonNull::new_unchecked(
4660                    ffi::whiteout_m3_M3ParticleEmitter_get_pitchAmplitude(self.raw.as_ptr()),
4661                ),
4662            })
4663        }
4664    }
4665
4666    pub fn pitch_amplitude_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
4667        // SAFETY: as above; `&mut self` guarantees exclusivity.
4668        unsafe {
4669            crate::support::RefMut::new(AnimRefF32 {
4670                raw: core::ptr::NonNull::new_unchecked(
4671                    ffi::whiteout_m3_M3ParticleEmitter_get_pitchAmplitude(self.raw.as_ptr()),
4672                ),
4673            })
4674        }
4675    }
4676
4677    /// Pitch variation frequency
4678    /// Borrows the field in place — no copy, no allocation.
4679    pub fn pitch_frequency(&self) -> crate::support::Ref<'_, AnimRefF32> {
4680        // SAFETY: an interior pointer into `self`, valid for this
4681        // borrow and never freed by the `Ref`.
4682        unsafe {
4683            crate::support::Ref::new(AnimRefF32 {
4684                raw: core::ptr::NonNull::new_unchecked(
4685                    ffi::whiteout_m3_M3ParticleEmitter_get_pitchFrequency(self.raw.as_ptr()),
4686                ),
4687            })
4688        }
4689    }
4690
4691    pub fn pitch_frequency_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
4692        // SAFETY: as above; `&mut self` guarantees exclusivity.
4693        unsafe {
4694            crate::support::RefMut::new(AnimRefF32 {
4695                raw: core::ptr::NonNull::new_unchecked(
4696                    ffi::whiteout_m3_M3ParticleEmitter_get_pitchFrequency(self.raw.as_ptr()),
4697                ),
4698            })
4699        }
4700    }
4701
4702    /// Yaw variation type
4703    pub fn yaw_type(&self) -> u32 {
4704        // SAFETY: plain scalar read through a live handle.
4705        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_yawType(self.raw.as_ptr()) }
4706    }
4707
4708    pub fn set_yaw_type(&mut self, value: u32) {
4709        // SAFETY: plain scalar write through a live handle.
4710        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_yawType(self.raw.as_ptr(), value) }
4711    }
4712
4713    /// Yaw variation amplitude
4714    /// Borrows the field in place — no copy, no allocation.
4715    pub fn yaw_amplitude(&self) -> crate::support::Ref<'_, AnimRefF32> {
4716        // SAFETY: an interior pointer into `self`, valid for this
4717        // borrow and never freed by the `Ref`.
4718        unsafe {
4719            crate::support::Ref::new(AnimRefF32 {
4720                raw: core::ptr::NonNull::new_unchecked(
4721                    ffi::whiteout_m3_M3ParticleEmitter_get_yawAmplitude(self.raw.as_ptr()),
4722                ),
4723            })
4724        }
4725    }
4726
4727    pub fn yaw_amplitude_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
4728        // SAFETY: as above; `&mut self` guarantees exclusivity.
4729        unsafe {
4730            crate::support::RefMut::new(AnimRefF32 {
4731                raw: core::ptr::NonNull::new_unchecked(
4732                    ffi::whiteout_m3_M3ParticleEmitter_get_yawAmplitude(self.raw.as_ptr()),
4733                ),
4734            })
4735        }
4736    }
4737
4738    /// Yaw variation frequency
4739    /// Borrows the field in place — no copy, no allocation.
4740    pub fn yaw_frequency(&self) -> crate::support::Ref<'_, AnimRefF32> {
4741        // SAFETY: an interior pointer into `self`, valid for this
4742        // borrow and never freed by the `Ref`.
4743        unsafe {
4744            crate::support::Ref::new(AnimRefF32 {
4745                raw: core::ptr::NonNull::new_unchecked(
4746                    ffi::whiteout_m3_M3ParticleEmitter_get_yawFrequency(self.raw.as_ptr()),
4747                ),
4748            })
4749        }
4750    }
4751
4752    pub fn yaw_frequency_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
4753        // SAFETY: as above; `&mut self` guarantees exclusivity.
4754        unsafe {
4755            crate::support::RefMut::new(AnimRefF32 {
4756                raw: core::ptr::NonNull::new_unchecked(
4757                    ffi::whiteout_m3_M3ParticleEmitter_get_yawFrequency(self.raw.as_ptr()),
4758                ),
4759            })
4760        }
4761    }
4762
4763    /// Speed variation type
4764    pub fn speed_type(&self) -> u32 {
4765        // SAFETY: plain scalar read through a live handle.
4766        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_speedType(self.raw.as_ptr()) }
4767    }
4768
4769    pub fn set_speed_type(&mut self, value: u32) {
4770        // SAFETY: plain scalar write through a live handle.
4771        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_speedType(self.raw.as_ptr(), value) }
4772    }
4773
4774    /// Speed variation amplitude
4775    /// Borrows the field in place — no copy, no allocation.
4776    pub fn speed_amplitude(&self) -> crate::support::Ref<'_, AnimRefF32> {
4777        // SAFETY: an interior pointer into `self`, valid for this
4778        // borrow and never freed by the `Ref`.
4779        unsafe {
4780            crate::support::Ref::new(AnimRefF32 {
4781                raw: core::ptr::NonNull::new_unchecked(
4782                    ffi::whiteout_m3_M3ParticleEmitter_get_speedAmplitude(self.raw.as_ptr()),
4783                ),
4784            })
4785        }
4786    }
4787
4788    pub fn speed_amplitude_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
4789        // SAFETY: as above; `&mut self` guarantees exclusivity.
4790        unsafe {
4791            crate::support::RefMut::new(AnimRefF32 {
4792                raw: core::ptr::NonNull::new_unchecked(
4793                    ffi::whiteout_m3_M3ParticleEmitter_get_speedAmplitude(self.raw.as_ptr()),
4794                ),
4795            })
4796        }
4797    }
4798
4799    /// Speed variation frequency
4800    /// Borrows the field in place — no copy, no allocation.
4801    pub fn speed_frequency(&self) -> crate::support::Ref<'_, AnimRefF32> {
4802        // SAFETY: an interior pointer into `self`, valid for this
4803        // borrow and never freed by the `Ref`.
4804        unsafe {
4805            crate::support::Ref::new(AnimRefF32 {
4806                raw: core::ptr::NonNull::new_unchecked(
4807                    ffi::whiteout_m3_M3ParticleEmitter_get_speedFrequency(self.raw.as_ptr()),
4808                ),
4809            })
4810        }
4811    }
4812
4813    pub fn speed_frequency_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
4814        // SAFETY: as above; `&mut self` guarantees exclusivity.
4815        unsafe {
4816            crate::support::RefMut::new(AnimRefF32 {
4817                raw: core::ptr::NonNull::new_unchecked(
4818                    ffi::whiteout_m3_M3ParticleEmitter_get_speedFrequency(self.raw.as_ptr()),
4819                ),
4820            })
4821        }
4822    }
4823
4824    /// Size variation type
4825    pub fn size_type(&self) -> u32 {
4826        // SAFETY: plain scalar read through a live handle.
4827        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_sizeType(self.raw.as_ptr()) }
4828    }
4829
4830    pub fn set_size_type(&mut self, value: u32) {
4831        // SAFETY: plain scalar write through a live handle.
4832        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_sizeType(self.raw.as_ptr(), value) }
4833    }
4834
4835    /// Size variation amplitude
4836    /// Borrows the field in place — no copy, no allocation.
4837    pub fn size_amplitude(&self) -> crate::support::Ref<'_, AnimRefF32> {
4838        // SAFETY: an interior pointer into `self`, valid for this
4839        // borrow and never freed by the `Ref`.
4840        unsafe {
4841            crate::support::Ref::new(AnimRefF32 {
4842                raw: core::ptr::NonNull::new_unchecked(
4843                    ffi::whiteout_m3_M3ParticleEmitter_get_sizeAmplitude(self.raw.as_ptr()),
4844                ),
4845            })
4846        }
4847    }
4848
4849    pub fn size_amplitude_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
4850        // SAFETY: as above; `&mut self` guarantees exclusivity.
4851        unsafe {
4852            crate::support::RefMut::new(AnimRefF32 {
4853                raw: core::ptr::NonNull::new_unchecked(
4854                    ffi::whiteout_m3_M3ParticleEmitter_get_sizeAmplitude(self.raw.as_ptr()),
4855                ),
4856            })
4857        }
4858    }
4859
4860    /// Size variation frequency
4861    /// Borrows the field in place — no copy, no allocation.
4862    pub fn size_frequency(&self) -> crate::support::Ref<'_, AnimRefF32> {
4863        // SAFETY: an interior pointer into `self`, valid for this
4864        // borrow and never freed by the `Ref`.
4865        unsafe {
4866            crate::support::Ref::new(AnimRefF32 {
4867                raw: core::ptr::NonNull::new_unchecked(
4868                    ffi::whiteout_m3_M3ParticleEmitter_get_sizeFrequency(self.raw.as_ptr()),
4869                ),
4870            })
4871        }
4872    }
4873
4874    pub fn size_frequency_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
4875        // SAFETY: as above; `&mut self` guarantees exclusivity.
4876        unsafe {
4877            crate::support::RefMut::new(AnimRefF32 {
4878                raw: core::ptr::NonNull::new_unchecked(
4879                    ffi::whiteout_m3_M3ParticleEmitter_get_sizeFrequency(self.raw.as_ptr()),
4880                ),
4881            })
4882        }
4883    }
4884
4885    /// Alpha variation type
4886    pub fn alpha_type(&self) -> u32 {
4887        // SAFETY: plain scalar read through a live handle.
4888        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_alphaType(self.raw.as_ptr()) }
4889    }
4890
4891    pub fn set_alpha_type(&mut self, value: u32) {
4892        // SAFETY: plain scalar write through a live handle.
4893        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_alphaType(self.raw.as_ptr(), value) }
4894    }
4895
4896    /// Alpha variation amplitude
4897    /// Borrows the field in place — no copy, no allocation.
4898    pub fn alpha_amplitude(&self) -> crate::support::Ref<'_, AnimRefF32> {
4899        // SAFETY: an interior pointer into `self`, valid for this
4900        // borrow and never freed by the `Ref`.
4901        unsafe {
4902            crate::support::Ref::new(AnimRefF32 {
4903                raw: core::ptr::NonNull::new_unchecked(
4904                    ffi::whiteout_m3_M3ParticleEmitter_get_alphaAmplitude(self.raw.as_ptr()),
4905                ),
4906            })
4907        }
4908    }
4909
4910    pub fn alpha_amplitude_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
4911        // SAFETY: as above; `&mut self` guarantees exclusivity.
4912        unsafe {
4913            crate::support::RefMut::new(AnimRefF32 {
4914                raw: core::ptr::NonNull::new_unchecked(
4915                    ffi::whiteout_m3_M3ParticleEmitter_get_alphaAmplitude(self.raw.as_ptr()),
4916                ),
4917            })
4918        }
4919    }
4920
4921    /// Alpha variation frequency
4922    /// Borrows the field in place — no copy, no allocation.
4923    pub fn alpha_frequency(&self) -> crate::support::Ref<'_, AnimRefF32> {
4924        // SAFETY: an interior pointer into `self`, valid for this
4925        // borrow and never freed by the `Ref`.
4926        unsafe {
4927            crate::support::Ref::new(AnimRefF32 {
4928                raw: core::ptr::NonNull::new_unchecked(
4929                    ffi::whiteout_m3_M3ParticleEmitter_get_alphaFrequency(self.raw.as_ptr()),
4930                ),
4931            })
4932        }
4933    }
4934
4935    pub fn alpha_frequency_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
4936        // SAFETY: as above; `&mut self` guarantees exclusivity.
4937        unsafe {
4938            crate::support::RefMut::new(AnimRefF32 {
4939                raw: core::ptr::NonNull::new_unchecked(
4940                    ffi::whiteout_m3_M3ParticleEmitter_get_alphaFrequency(self.raw.as_ptr()),
4941                ),
4942            })
4943        }
4944    }
4945
4946    /// Color variation type
4947    pub fn color_type(&self) -> u32 {
4948        // SAFETY: plain scalar read through a live handle.
4949        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_colorType(self.raw.as_ptr()) }
4950    }
4951
4952    pub fn set_color_type(&mut self, value: u32) {
4953        // SAFETY: plain scalar write through a live handle.
4954        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_colorType(self.raw.as_ptr(), value) }
4955    }
4956
4957    /// Color variation amplitude
4958    /// Borrows the field in place — no copy, no allocation.
4959    pub fn color_amplitude(&self) -> crate::support::Ref<'_, AnimRefF32> {
4960        // SAFETY: an interior pointer into `self`, valid for this
4961        // borrow and never freed by the `Ref`.
4962        unsafe {
4963            crate::support::Ref::new(AnimRefF32 {
4964                raw: core::ptr::NonNull::new_unchecked(
4965                    ffi::whiteout_m3_M3ParticleEmitter_get_colorAmplitude(self.raw.as_ptr()),
4966                ),
4967            })
4968        }
4969    }
4970
4971    pub fn color_amplitude_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
4972        // SAFETY: as above; `&mut self` guarantees exclusivity.
4973        unsafe {
4974            crate::support::RefMut::new(AnimRefF32 {
4975                raw: core::ptr::NonNull::new_unchecked(
4976                    ffi::whiteout_m3_M3ParticleEmitter_get_colorAmplitude(self.raw.as_ptr()),
4977                ),
4978            })
4979        }
4980    }
4981
4982    /// Color variation frequency
4983    /// Borrows the field in place — no copy, no allocation.
4984    pub fn color_frequency(&self) -> crate::support::Ref<'_, AnimRefF32> {
4985        // SAFETY: an interior pointer into `self`, valid for this
4986        // borrow and never freed by the `Ref`.
4987        unsafe {
4988            crate::support::Ref::new(AnimRefF32 {
4989                raw: core::ptr::NonNull::new_unchecked(
4990                    ffi::whiteout_m3_M3ParticleEmitter_get_colorFrequency(self.raw.as_ptr()),
4991                ),
4992            })
4993        }
4994    }
4995
4996    pub fn color_frequency_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
4997        // SAFETY: as above; `&mut self` guarantees exclusivity.
4998        unsafe {
4999            crate::support::RefMut::new(AnimRefF32 {
5000                raw: core::ptr::NonNull::new_unchecked(
5001                    ffi::whiteout_m3_M3ParticleEmitter_get_colorFrequency(self.raw.as_ptr()),
5002                ),
5003            })
5004        }
5005    }
5006
5007    /// Rotation variation type
5008    pub fn rotation_type(&self) -> u32 {
5009        // SAFETY: plain scalar read through a live handle.
5010        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_rotationType(self.raw.as_ptr()) }
5011    }
5012
5013    pub fn set_rotation_type(&mut self, value: u32) {
5014        // SAFETY: plain scalar write through a live handle.
5015        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_rotationType(self.raw.as_ptr(), value) }
5016    }
5017
5018    /// Rotation variation amplitude
5019    /// Borrows the field in place — no copy, no allocation.
5020    pub fn rotation_amplitude(&self) -> crate::support::Ref<'_, AnimRefF32> {
5021        // SAFETY: an interior pointer into `self`, valid for this
5022        // borrow and never freed by the `Ref`.
5023        unsafe {
5024            crate::support::Ref::new(AnimRefF32 {
5025                raw: core::ptr::NonNull::new_unchecked(
5026                    ffi::whiteout_m3_M3ParticleEmitter_get_rotationAmplitude(self.raw.as_ptr()),
5027                ),
5028            })
5029        }
5030    }
5031
5032    pub fn rotation_amplitude_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
5033        // SAFETY: as above; `&mut self` guarantees exclusivity.
5034        unsafe {
5035            crate::support::RefMut::new(AnimRefF32 {
5036                raw: core::ptr::NonNull::new_unchecked(
5037                    ffi::whiteout_m3_M3ParticleEmitter_get_rotationAmplitude(self.raw.as_ptr()),
5038                ),
5039            })
5040        }
5041    }
5042
5043    /// Rotation variation frequency
5044    /// Borrows the field in place — no copy, no allocation.
5045    pub fn rotation_frequency(&self) -> crate::support::Ref<'_, AnimRefF32> {
5046        // SAFETY: an interior pointer into `self`, valid for this
5047        // borrow and never freed by the `Ref`.
5048        unsafe {
5049            crate::support::Ref::new(AnimRefF32 {
5050                raw: core::ptr::NonNull::new_unchecked(
5051                    ffi::whiteout_m3_M3ParticleEmitter_get_rotationFrequency(self.raw.as_ptr()),
5052                ),
5053            })
5054        }
5055    }
5056
5057    pub fn rotation_frequency_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
5058        // SAFETY: as above; `&mut self` guarantees exclusivity.
5059        unsafe {
5060            crate::support::RefMut::new(AnimRefF32 {
5061                raw: core::ptr::NonNull::new_unchecked(
5062                    ffi::whiteout_m3_M3ParticleEmitter_get_rotationFrequency(self.raw.as_ptr()),
5063                ),
5064            })
5065        }
5066    }
5067
5068    /// Horizontal variation type
5069    pub fn horizontal_type(&self) -> u32 {
5070        // SAFETY: plain scalar read through a live handle.
5071        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_horizontalType(self.raw.as_ptr()) }
5072    }
5073
5074    pub fn set_horizontal_type(&mut self, value: u32) {
5075        // SAFETY: plain scalar write through a live handle.
5076        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_horizontalType(self.raw.as_ptr(), value) }
5077    }
5078
5079    /// Horizontal variation amplitude
5080    /// Borrows the field in place — no copy, no allocation.
5081    pub fn horizontal_amplitude(&self) -> crate::support::Ref<'_, AnimRefF32> {
5082        // SAFETY: an interior pointer into `self`, valid for this
5083        // borrow and never freed by the `Ref`.
5084        unsafe {
5085            crate::support::Ref::new(AnimRefF32 {
5086                raw: core::ptr::NonNull::new_unchecked(
5087                    ffi::whiteout_m3_M3ParticleEmitter_get_horizontalAmplitude(self.raw.as_ptr()),
5088                ),
5089            })
5090        }
5091    }
5092
5093    pub fn horizontal_amplitude_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
5094        // SAFETY: as above; `&mut self` guarantees exclusivity.
5095        unsafe {
5096            crate::support::RefMut::new(AnimRefF32 {
5097                raw: core::ptr::NonNull::new_unchecked(
5098                    ffi::whiteout_m3_M3ParticleEmitter_get_horizontalAmplitude(self.raw.as_ptr()),
5099                ),
5100            })
5101        }
5102    }
5103
5104    /// Horizontal variation frequency
5105    /// Borrows the field in place — no copy, no allocation.
5106    pub fn horizontal_frequency(&self) -> crate::support::Ref<'_, AnimRefF32> {
5107        // SAFETY: an interior pointer into `self`, valid for this
5108        // borrow and never freed by the `Ref`.
5109        unsafe {
5110            crate::support::Ref::new(AnimRefF32 {
5111                raw: core::ptr::NonNull::new_unchecked(
5112                    ffi::whiteout_m3_M3ParticleEmitter_get_horizontalFrequency(self.raw.as_ptr()),
5113                ),
5114            })
5115        }
5116    }
5117
5118    pub fn horizontal_frequency_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
5119        // SAFETY: as above; `&mut self` guarantees exclusivity.
5120        unsafe {
5121            crate::support::RefMut::new(AnimRefF32 {
5122                raw: core::ptr::NonNull::new_unchecked(
5123                    ffi::whiteout_m3_M3ParticleEmitter_get_horizontalFrequency(self.raw.as_ptr()),
5124                ),
5125            })
5126        }
5127    }
5128
5129    /// Vertical variation type
5130    pub fn vertical_type(&self) -> u32 {
5131        // SAFETY: plain scalar read through a live handle.
5132        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_verticalType(self.raw.as_ptr()) }
5133    }
5134
5135    pub fn set_vertical_type(&mut self, value: u32) {
5136        // SAFETY: plain scalar write through a live handle.
5137        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_verticalType(self.raw.as_ptr(), value) }
5138    }
5139
5140    /// Vertical variation amplitude
5141    /// Borrows the field in place — no copy, no allocation.
5142    pub fn vertical_amplitude(&self) -> crate::support::Ref<'_, AnimRefF32> {
5143        // SAFETY: an interior pointer into `self`, valid for this
5144        // borrow and never freed by the `Ref`.
5145        unsafe {
5146            crate::support::Ref::new(AnimRefF32 {
5147                raw: core::ptr::NonNull::new_unchecked(
5148                    ffi::whiteout_m3_M3ParticleEmitter_get_verticalAmplitude(self.raw.as_ptr()),
5149                ),
5150            })
5151        }
5152    }
5153
5154    pub fn vertical_amplitude_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
5155        // SAFETY: as above; `&mut self` guarantees exclusivity.
5156        unsafe {
5157            crate::support::RefMut::new(AnimRefF32 {
5158                raw: core::ptr::NonNull::new_unchecked(
5159                    ffi::whiteout_m3_M3ParticleEmitter_get_verticalAmplitude(self.raw.as_ptr()),
5160                ),
5161            })
5162        }
5163    }
5164
5165    /// Vertical variation frequency;
5166    /// Borrows the field in place — no copy, no allocation.
5167    pub fn vertical_frequency(&self) -> crate::support::Ref<'_, AnimRefF32> {
5168        // SAFETY: an interior pointer into `self`, valid for this
5169        // borrow and never freed by the `Ref`.
5170        unsafe {
5171            crate::support::Ref::new(AnimRefF32 {
5172                raw: core::ptr::NonNull::new_unchecked(
5173                    ffi::whiteout_m3_M3ParticleEmitter_get_verticalFrequency(self.raw.as_ptr()),
5174                ),
5175            })
5176        }
5177    }
5178
5179    pub fn vertical_frequency_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
5180        // SAFETY: as above; `&mut self` guarantees exclusivity.
5181        unsafe {
5182            crate::support::RefMut::new(AnimRefF32 {
5183                raw: core::ptr::NonNull::new_unchecked(
5184                    ffi::whiteout_m3_M3ParticleEmitter_get_verticalFrequency(self.raw.as_ptr()),
5185                ),
5186            })
5187        }
5188    }
5189
5190    /// Animated parent velocity influence
5191    /// Borrows the field in place — no copy, no allocation.
5192    pub fn particle_velocity(&self) -> crate::support::Ref<'_, AnimRefF32> {
5193        // SAFETY: an interior pointer into `self`, valid for this
5194        // borrow and never freed by the `Ref`.
5195        unsafe {
5196            crate::support::Ref::new(AnimRefF32 {
5197                raw: core::ptr::NonNull::new_unchecked(
5198                    ffi::whiteout_m3_M3ParticleEmitter_get_particleVelocity(self.raw.as_ptr()),
5199                ),
5200            })
5201        }
5202    }
5203
5204    pub fn particle_velocity_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
5205        // SAFETY: as above; `&mut self` guarantees exclusivity.
5206        unsafe {
5207            crate::support::RefMut::new(AnimRefF32 {
5208                raw: core::ptr::NonNull::new_unchecked(
5209                    ffi::whiteout_m3_M3ParticleEmitter_get_particleVelocity(self.raw.as_ptr()),
5210                ),
5211            })
5212        }
5213    }
5214
5215    /// Animated phase shift (v22+)
5216    /// Borrows the field in place — no copy, no allocation.
5217    pub fn phase_shift(&self) -> crate::support::Ref<'_, AnimRefF32> {
5218        // SAFETY: an interior pointer into `self`, valid for this
5219        // borrow and never freed by the `Ref`.
5220        unsafe {
5221            crate::support::Ref::new(AnimRefF32 {
5222                raw: core::ptr::NonNull::new_unchecked(
5223                    ffi::whiteout_m3_M3ParticleEmitter_get_phaseShift(self.raw.as_ptr()),
5224                ),
5225            })
5226        }
5227    }
5228
5229    pub fn phase_shift_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
5230        // SAFETY: as above; `&mut self` guarantees exclusivity.
5231        unsafe {
5232            crate::support::RefMut::new(AnimRefF32 {
5233                raw: core::ptr::NonNull::new_unchecked(
5234                    ffi::whiteout_m3_M3ParticleEmitter_get_phaseShift(self.raw.as_ptr()),
5235                ),
5236            })
5237        }
5238    }
5239
5240    /// Main particle flags
5241    pub fn flags(&self) -> ParticleFlag {
5242        // SAFETY: scalar read; a flag set accepts any bits.
5243        ParticleFlag(unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_flags(self.raw.as_ptr()) })
5244    }
5245
5246    pub fn set_flags(&mut self, value: ParticleFlag) {
5247        // SAFETY: scalar write through a live handle.
5248        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_flags(self.raw.as_ptr(), value.0) }
5249    }
5250
5251    /// Rotation flags (v18+)
5252    pub fn rotation_flags(&self) -> ParticleRotationFlag {
5253        // SAFETY: scalar read; the discriminant is validated below.
5254        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_rotationFlags(self.raw.as_ptr()) }
5255            .try_into()
5256            .expect("unknown enum discriminant from the native library")
5257    }
5258
5259    pub fn set_rotation_flags(&mut self, value: ParticleRotationFlag) {
5260        // SAFETY: scalar write through a live handle.
5261        unsafe {
5262            ffi::whiteout_m3_M3ParticleEmitter_set_rotationFlags(self.raw.as_ptr(), value as i32)
5263        }
5264    }
5265
5266    pub fn color_smoothing(&self) -> InterpolationMode {
5267        // SAFETY: scalar read; the discriminant is validated below.
5268        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_colorSmoothing(self.raw.as_ptr()) }
5269            .try_into()
5270            .expect("unknown enum discriminant from the native library")
5271    }
5272
5273    pub fn set_color_smoothing(&mut self, value: InterpolationMode) {
5274        // SAFETY: scalar write through a live handle.
5275        unsafe {
5276            ffi::whiteout_m3_M3ParticleEmitter_set_colorSmoothing(self.raw.as_ptr(), value as i32)
5277        }
5278    }
5279
5280    pub fn size_smoothing(&self) -> InterpolationMode {
5281        // SAFETY: scalar read; the discriminant is validated below.
5282        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_sizeSmoothing(self.raw.as_ptr()) }
5283            .try_into()
5284            .expect("unknown enum discriminant from the native library")
5285    }
5286
5287    pub fn set_size_smoothing(&mut self, value: InterpolationMode) {
5288        // SAFETY: scalar write through a live handle.
5289        unsafe {
5290            ffi::whiteout_m3_M3ParticleEmitter_set_sizeSmoothing(self.raw.as_ptr(), value as i32)
5291        }
5292    }
5293
5294    pub fn rotation_smoothing(&self) -> InterpolationMode {
5295        // SAFETY: scalar read; the discriminant is validated below.
5296        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_rotationSmoothing(self.raw.as_ptr()) }
5297            .try_into()
5298            .expect("unknown enum discriminant from the native library")
5299    }
5300
5301    pub fn set_rotation_smoothing(&mut self, value: InterpolationMode) {
5302        // SAFETY: scalar write through a live handle.
5303        unsafe {
5304            ffi::whiteout_m3_M3ParticleEmitter_set_rotationSmoothing(
5305                self.raw.as_ptr(),
5306                value as i32,
5307            )
5308        }
5309    }
5310
5311    /// Animated alpha threshold
5312    /// Borrows the field in place — no copy, no allocation.
5313    pub fn alpha_threshold(&self) -> crate::support::Ref<'_, AnimRefF32> {
5314        // SAFETY: an interior pointer into `self`, valid for this
5315        // borrow and never freed by the `Ref`.
5316        unsafe {
5317            crate::support::Ref::new(AnimRefF32 {
5318                raw: core::ptr::NonNull::new_unchecked(
5319                    ffi::whiteout_m3_M3ParticleEmitter_get_alphaThreshold(self.raw.as_ptr()),
5320                ),
5321            })
5322        }
5323    }
5324
5325    pub fn alpha_threshold_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
5326        // SAFETY: as above; `&mut self` guarantees exclusivity.
5327        unsafe {
5328            crate::support::RefMut::new(AnimRefF32 {
5329                raw: core::ptr::NonNull::new_unchecked(
5330                    ffi::whiteout_m3_M3ParticleEmitter_get_alphaThreshold(self.raw.as_ptr()),
5331                ),
5332            })
5333        }
5334    }
5335
5336    /// Animated UV offset
5337    /// Borrows the field in place — no copy, no allocation.
5338    pub fn uv_offset(&self) -> crate::support::Ref<'_, AnimRefVector2f> {
5339        // SAFETY: an interior pointer into `self`, valid for this
5340        // borrow and never freed by the `Ref`.
5341        unsafe {
5342            crate::support::Ref::new(AnimRefVector2f {
5343                raw: core::ptr::NonNull::new_unchecked(
5344                    ffi::whiteout_m3_M3ParticleEmitter_get_uvOffset(self.raw.as_ptr()),
5345                ),
5346            })
5347        }
5348    }
5349
5350    pub fn uv_offset_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector2f> {
5351        // SAFETY: as above; `&mut self` guarantees exclusivity.
5352        unsafe {
5353            crate::support::RefMut::new(AnimRefVector2f {
5354                raw: core::ptr::NonNull::new_unchecked(
5355                    ffi::whiteout_m3_M3ParticleEmitter_get_uvOffset(self.raw.as_ptr()),
5356                ),
5357            })
5358        }
5359    }
5360
5361    /// Animated UV rotation angles
5362    /// Borrows the field in place — no copy, no allocation.
5363    pub fn uv_angle(&self) -> crate::support::Ref<'_, AnimRefVector3f> {
5364        // SAFETY: an interior pointer into `self`, valid for this
5365        // borrow and never freed by the `Ref`.
5366        unsafe {
5367            crate::support::Ref::new(AnimRefVector3f {
5368                raw: core::ptr::NonNull::new_unchecked(
5369                    ffi::whiteout_m3_M3ParticleEmitter_get_uvAngle(self.raw.as_ptr()),
5370                ),
5371            })
5372        }
5373    }
5374
5375    pub fn uv_angle_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector3f> {
5376        // SAFETY: as above; `&mut self` guarantees exclusivity.
5377        unsafe {
5378            crate::support::RefMut::new(AnimRefVector3f {
5379                raw: core::ptr::NonNull::new_unchecked(
5380                    ffi::whiteout_m3_M3ParticleEmitter_get_uvAngle(self.raw.as_ptr()),
5381                ),
5382            })
5383        }
5384    }
5385
5386    /// Animated UV tiling
5387    /// Borrows the field in place — no copy, no allocation.
5388    pub fn uv_tiling(&self) -> crate::support::Ref<'_, AnimRefVector2f> {
5389        // SAFETY: an interior pointer into `self`, valid for this
5390        // borrow and never freed by the `Ref`.
5391        unsafe {
5392            crate::support::Ref::new(AnimRefVector2f {
5393                raw: core::ptr::NonNull::new_unchecked(
5394                    ffi::whiteout_m3_M3ParticleEmitter_get_uvTiling(self.raw.as_ptr()),
5395                ),
5396            })
5397        }
5398    }
5399
5400    pub fn uv_tiling_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector2f> {
5401        // SAFETY: as above; `&mut self` guarantees exclusivity.
5402        unsafe {
5403            crate::support::RefMut::new(AnimRefVector2f {
5404                raw: core::ptr::NonNull::new_unchecked(
5405                    ffi::whiteout_m3_M3ParticleEmitter_get_uvTiling(self.raw.as_ptr()),
5406                ),
5407            })
5408        }
5409    }
5410
5411    /// Spline control points (SVC3)
5412    pub fn spline_line_data_len(&self) -> usize {
5413        // SAFETY: scalar read through a live handle.
5414        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_splineLineData_count(self.raw.as_ptr()) }
5415    }
5416
5417    /// Borrows element `index` in place. `None` when out of range.
5418    pub fn spline_line_data(
5419        &self,
5420        index: usize,
5421    ) -> Option<crate::support::Ref<'_, AnimRefVector3f>> {
5422        if index >= self.spline_line_data_len() {
5423            return None;
5424        }
5425        // SAFETY: index checked above; the pointer is interior to `self`.
5426        unsafe {
5427            Some(crate::support::Ref::new(AnimRefVector3f {
5428                raw: core::ptr::NonNull::new_unchecked(
5429                    ffi::whiteout_m3_M3ParticleEmitter_get_splineLineData_at(
5430                        self.raw.as_ptr(),
5431                        index,
5432                    ),
5433                ),
5434            }))
5435        }
5436    }
5437
5438    pub fn spline_line_data_mut(
5439        &mut self,
5440        index: usize,
5441    ) -> Option<crate::support::RefMut<'_, AnimRefVector3f>> {
5442        if index >= self.spline_line_data_len() {
5443            return None;
5444        }
5445        // SAFETY: as above; `&mut self` guarantees exclusivity.
5446        unsafe {
5447            Some(crate::support::RefMut::new(AnimRefVector3f {
5448                raw: core::ptr::NonNull::new_unchecked(
5449                    ffi::whiteout_m3_M3ParticleEmitter_get_splineLineData_at(
5450                        self.raw.as_ptr(),
5451                        index,
5452                    ),
5453                ),
5454            }))
5455        }
5456    }
5457
5458    /// Iterate the elements, borrowing each in turn.
5459    pub fn spline_line_data_iter(
5460        &self,
5461    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, AnimRefVector3f>> {
5462        (0..self.spline_line_data_len())
5463            .map(move |i| self.spline_line_data(i).expect("index below len"))
5464    }
5465
5466    pub fn resize_spline_line_data(&mut self, count: usize) {
5467        // SAFETY: exclusive access, so no borrow is outstanding.
5468        unsafe {
5469            ffi::whiteout_m3_M3ParticleEmitter_resize_splineLineData(self.raw.as_ptr(), count)
5470        }
5471    }
5472
5473    /// Wind influence multiplier
5474    pub fn wind_multiplier(&self) -> f32 {
5475        // SAFETY: plain scalar read through a live handle.
5476        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_windMultiplier(self.raw.as_ptr()) }
5477    }
5478
5479    pub fn set_wind_multiplier(&mut self, value: f32) {
5480        // SAFETY: plain scalar write through a live handle.
5481        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_windMultiplier(self.raw.as_ptr(), value) }
5482    }
5483
5484    /// LOD reduction level
5485    pub fn lod_reduce(&self) -> u32 {
5486        // SAFETY: plain scalar read through a live handle.
5487        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_lodReduce(self.raw.as_ptr()) }
5488    }
5489
5490    pub fn set_lod_reduce(&mut self, value: u32) {
5491        // SAFETY: plain scalar write through a live handle.
5492        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_lodReduce(self.raw.as_ptr(), value) }
5493    }
5494
5495    /// LOD cut-off level
5496    pub fn lod_cut(&self) -> u32 {
5497        // SAFETY: plain scalar read through a live handle.
5498        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_lodCut(self.raw.as_ptr()) }
5499    }
5500
5501    pub fn set_lod_cut(&mut self, value: u32) {
5502        // SAFETY: plain scalar write through a live handle.
5503        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_lodCut(self.raw.as_ptr(), value) }
5504    }
5505
5506    /// Animated lower bound
5507    /// Borrows the field in place — no copy, no allocation.
5508    pub fn lower_bound(&self) -> crate::support::Ref<'_, AnimRefF32> {
5509        // SAFETY: an interior pointer into `self`, valid for this
5510        // borrow and never freed by the `Ref`.
5511        unsafe {
5512            crate::support::Ref::new(AnimRefF32 {
5513                raw: core::ptr::NonNull::new_unchecked(
5514                    ffi::whiteout_m3_M3ParticleEmitter_get_lowerBound(self.raw.as_ptr()),
5515                ),
5516            })
5517        }
5518    }
5519
5520    pub fn lower_bound_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
5521        // SAFETY: as above; `&mut self` guarantees exclusivity.
5522        unsafe {
5523            crate::support::RefMut::new(AnimRefF32 {
5524                raw: core::ptr::NonNull::new_unchecked(
5525                    ffi::whiteout_m3_M3ParticleEmitter_get_lowerBound(self.raw.as_ptr()),
5526                ),
5527            })
5528        }
5529    }
5530
5531    /// Animated upper bound
5532    /// Borrows the field in place — no copy, no allocation.
5533    pub fn upper_bound(&self) -> crate::support::Ref<'_, AnimRefF32> {
5534        // SAFETY: an interior pointer into `self`, valid for this
5535        // borrow and never freed by the `Ref`.
5536        unsafe {
5537            crate::support::Ref::new(AnimRefF32 {
5538                raw: core::ptr::NonNull::new_unchecked(
5539                    ffi::whiteout_m3_M3ParticleEmitter_get_upperBound(self.raw.as_ptr()),
5540                ),
5541            })
5542        }
5543    }
5544
5545    pub fn upper_bound_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
5546        // SAFETY: as above; `&mut self` guarantees exclusivity.
5547        unsafe {
5548            crate::support::RefMut::new(AnimRefF32 {
5549                raw: core::ptr::NonNull::new_unchecked(
5550                    ffi::whiteout_m3_M3ParticleEmitter_get_upperBound(self.raw.as_ptr()),
5551                ),
5552            })
5553        }
5554    }
5555
5556    pub fn trail_link_index(&self) -> i32 {
5557        // SAFETY: plain scalar read through a live handle.
5558        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_trailLinkIndex(self.raw.as_ptr()) }
5559    }
5560
5561    pub fn set_trail_link_index(&mut self, value: i32) {
5562        // SAFETY: plain scalar write through a live handle.
5563        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_trailLinkIndex(self.raw.as_ptr(), value) }
5564    }
5565
5566    /// Trail spawn probability
5567    pub fn trail_chance(&self) -> f32 {
5568        // SAFETY: plain scalar read through a live handle.
5569        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_trailChance(self.raw.as_ptr()) }
5570    }
5571
5572    pub fn set_trail_chance(&mut self, value: f32) {
5573        // SAFETY: plain scalar write through a live handle.
5574        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_trailChance(self.raw.as_ptr(), value) }
5575    }
5576
5577    /// Animated trail emission rate
5578    /// Borrows the field in place — no copy, no allocation.
5579    pub fn trail_emission_rate(&self) -> crate::support::Ref<'_, AnimRefF32> {
5580        // SAFETY: an interior pointer into `self`, valid for this
5581        // borrow and never freed by the `Ref`.
5582        unsafe {
5583            crate::support::Ref::new(AnimRefF32 {
5584                raw: core::ptr::NonNull::new_unchecked(
5585                    ffi::whiteout_m3_M3ParticleEmitter_get_trailEmissionRate(self.raw.as_ptr()),
5586                ),
5587            })
5588        }
5589    }
5590
5591    pub fn trail_emission_rate_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
5592        // SAFETY: as above; `&mut self` guarantees exclusivity.
5593        unsafe {
5594            crate::support::RefMut::new(AnimRefF32 {
5595                raw: core::ptr::NonNull::new_unchecked(
5596                    ffi::whiteout_m3_M3ParticleEmitter_get_trailEmissionRate(self.raw.as_ptr()),
5597                ),
5598            })
5599        }
5600    }
5601
5602    /// Linked projector index (-1 = none)
5603    pub fn splat_projection_index(&self) -> i32 {
5604        // SAFETY: plain scalar read through a live handle.
5605        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_splatProjectionIndex(self.raw.as_ptr()) }
5606    }
5607
5608    pub fn set_splat_projection_index(&mut self, value: i32) {
5609        // SAFETY: plain scalar write through a live handle.
5610        unsafe {
5611            ffi::whiteout_m3_M3ParticleEmitter_set_splatProjectionIndex(self.raw.as_ptr(), value)
5612        }
5613    }
5614
5615    /// Splat spawn probability
5616    pub fn splat_chance(&self) -> f32 {
5617        // SAFETY: plain scalar read through a live handle.
5618        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_splatChance(self.raw.as_ptr()) }
5619    }
5620
5621    pub fn set_splat_chance(&mut self, value: f32) {
5622        // SAFETY: plain scalar write through a live handle.
5623        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_splatChance(self.raw.as_ptr(), value) }
5624    }
5625
5626    /// Emitter copy indices (U32_)
5627    /// Zero-copy view of the underlying `std::vector`.
5628    pub fn copy_indices(&self) -> &[u32] {
5629        // SAFETY: `_data`/`_count` describe one contiguous C++
5630        // allocation, borrowed for as long as `self` is.
5631        unsafe {
5632            let n = ffi::whiteout_m3_M3ParticleEmitter_get_copyIndices_count(self.raw.as_ptr());
5633            let p = ffi::whiteout_m3_M3ParticleEmitter_get_copyIndices_data(self.raw.as_ptr());
5634            if p.is_null() || n == 0 {
5635                &[]
5636            } else {
5637                core::slice::from_raw_parts(p, n)
5638            }
5639        }
5640    }
5641
5642    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
5643    pub fn copy_indices_mut(&mut self) -> &mut [u32] {
5644        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
5645        unsafe {
5646            let n = ffi::whiteout_m3_M3ParticleEmitter_get_copyIndices_count(self.raw.as_ptr());
5647            let p = ffi::whiteout_m3_M3ParticleEmitter_get_copyIndices_data(self.raw.as_ptr())
5648                as *mut u32;
5649            if p.is_null() || n == 0 {
5650                &mut []
5651            } else {
5652                core::slice::from_raw_parts_mut(p, n)
5653            }
5654        }
5655    }
5656
5657    pub fn set_copy_indices(&mut self, values: &[u32]) {
5658        // SAFETY: the native side copies `values` before returning.
5659        unsafe {
5660            ffi::whiteout_m3_M3ParticleEmitter_assign_copyIndices(
5661                self.raw.as_ptr(),
5662                values.as_ptr() as *const _,
5663                values.len(),
5664            )
5665        }
5666    }
5667
5668    pub fn resize_copy_indices(&mut self, count: usize) {
5669        // SAFETY: reallocation is safe here precisely because
5670        // `&mut self` means no slice borrow is outstanding.
5671        unsafe { ffi::whiteout_m3_M3ParticleEmitter_resize_copyIndices(self.raw.as_ptr(), count) }
5672    }
5673
5674    /// Ribbon spawn probability on bounce (v23+)
5675    pub fn spawn_ribbon_on_bounce_chance(&self) -> f32 {
5676        // SAFETY: plain scalar read through a live handle.
5677        unsafe {
5678            ffi::whiteout_m3_M3ParticleEmitter_get_spawnRibbonOnBounceChance(self.raw.as_ptr())
5679        }
5680    }
5681
5682    pub fn set_spawn_ribbon_on_bounce_chance(&mut self, value: f32) {
5683        // SAFETY: plain scalar write through a live handle.
5684        unsafe {
5685            ffi::whiteout_m3_M3ParticleEmitter_set_spawnRibbonOnBounceChance(
5686                self.raw.as_ptr(),
5687                value,
5688            )
5689        }
5690    }
5691
5692    /// Index into RIB_ array (-1 = none, v23+)
5693    pub fn ribbon_link_index(&self) -> i32 {
5694        // SAFETY: plain scalar read through a live handle.
5695        unsafe { ffi::whiteout_m3_M3ParticleEmitter_get_ribbonLinkIndex(self.raw.as_ptr()) }
5696    }
5697
5698    pub fn set_ribbon_link_index(&mut self, value: i32) {
5699        // SAFETY: plain scalar write through a live handle.
5700        unsafe { ffi::whiteout_m3_M3ParticleEmitter_set_ribbonLinkIndex(self.raw.as_ptr(), value) }
5701    }
5702}
5703
5704impl Default for ParticleEmitter {
5705    fn default() -> Self {
5706        Self::new()
5707    }
5708}
5709
5710/// PARC — Particle emitter copy (v0, 40 bytes)
5711///
5712/// Lightweight copy of a particle emitter with overridden emission rate, squirt amount, and bone index. References the original PAR_ via Model.copyIndices.
5713pub struct ParticleEmitterCopy {
5714    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3ParticleEmitterCopy>,
5715}
5716
5717impl Drop for ParticleEmitterCopy {
5718    fn drop(&mut self) {
5719        // SAFETY: `raw` came from a native constructor and Drop runs once.
5720        unsafe { ffi::whiteout_m3_M3ParticleEmitterCopy_delete(self.raw.as_ptr()) }
5721    }
5722}
5723
5724impl ParticleEmitterCopy {
5725    /// # Safety
5726    /// `raw` must be a live handle this value takes ownership of.
5727    #[allow(dead_code)] // used by whichever methods return this type
5728    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3ParticleEmitterCopy) -> Option<Self> {
5729        core::ptr::NonNull::new(raw).map(|raw| ParticleEmitterCopy { raw })
5730    }
5731}
5732
5733// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
5734// is deliberately NOT implemented — the C++ types make no documented
5735// guarantee about concurrent use, and claiming one we haven't verified
5736// would be unsound. See `@bind thread_safe` in the plan.
5737unsafe impl Send for ParticleEmitterCopy {}
5738
5739impl core::fmt::Debug for ParticleEmitterCopy {
5740    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
5741        f.debug_struct("ParticleEmitterCopy")
5742            .finish_non_exhaustive()
5743    }
5744}
5745
5746impl ParticleEmitterCopy {
5747    /// # Panics
5748    /// Panics if the native allocation fails.
5749    pub fn new() -> Self {
5750        // SAFETY: the native constructor returns a live handle; a null here
5751        // means the library is unusable.
5752        unsafe {
5753            let raw = ffi::whiteout_m3_M3ParticleEmitterCopy_new();
5754            Self::from_raw(raw).expect("native ParticleEmitterCopy allocation failed")
5755        }
5756    }
5757
5758    /// Overridden emission rate
5759    /// Borrows the field in place — no copy, no allocation.
5760    pub fn emission_rate(&self) -> crate::support::Ref<'_, AnimRefF32> {
5761        // SAFETY: an interior pointer into `self`, valid for this
5762        // borrow and never freed by the `Ref`.
5763        unsafe {
5764            crate::support::Ref::new(AnimRefF32 {
5765                raw: core::ptr::NonNull::new_unchecked(
5766                    ffi::whiteout_m3_M3ParticleEmitterCopy_get_emissionRate(self.raw.as_ptr()),
5767                ),
5768            })
5769        }
5770    }
5771
5772    pub fn emission_rate_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
5773        // SAFETY: as above; `&mut self` guarantees exclusivity.
5774        unsafe {
5775            crate::support::RefMut::new(AnimRefF32 {
5776                raw: core::ptr::NonNull::new_unchecked(
5777                    ffi::whiteout_m3_M3ParticleEmitterCopy_get_emissionRate(self.raw.as_ptr()),
5778                ),
5779            })
5780        }
5781    }
5782
5783    /// Overridden squirt burst count
5784    /// Borrows the field in place — no copy, no allocation.
5785    pub fn squirt_amount(&self) -> crate::support::Ref<'_, AnimRefU16> {
5786        // SAFETY: an interior pointer into `self`, valid for this
5787        // borrow and never freed by the `Ref`.
5788        unsafe {
5789            crate::support::Ref::new(AnimRefU16 {
5790                raw: core::ptr::NonNull::new_unchecked(
5791                    ffi::whiteout_m3_M3ParticleEmitterCopy_get_squirtAmount(self.raw.as_ptr()),
5792                ),
5793            })
5794        }
5795    }
5796
5797    pub fn squirt_amount_mut(&mut self) -> crate::support::RefMut<'_, AnimRefU16> {
5798        // SAFETY: as above; `&mut self` guarantees exclusivity.
5799        unsafe {
5800            crate::support::RefMut::new(AnimRefU16 {
5801                raw: core::ptr::NonNull::new_unchecked(
5802                    ffi::whiteout_m3_M3ParticleEmitterCopy_get_squirtAmount(self.raw.as_ptr()),
5803                ),
5804            })
5805        }
5806    }
5807
5808    /// Index into BONE array
5809    pub fn bone_index(&self) -> u32 {
5810        // SAFETY: plain scalar read through a live handle.
5811        unsafe { ffi::whiteout_m3_M3ParticleEmitterCopy_get_boneIndex(self.raw.as_ptr()) }
5812    }
5813
5814    pub fn set_bone_index(&mut self, value: u32) {
5815        // SAFETY: plain scalar write through a live handle.
5816        unsafe { ffi::whiteout_m3_M3ParticleEmitterCopy_set_boneIndex(self.raw.as_ptr(), value) }
5817    }
5818}
5819
5820impl Default for ParticleEmitterCopy {
5821    fn default() -> Self {
5822        Self::new()
5823    }
5824}
5825
5826/// SRIB — Spline ribbon segment (v0, 272 bytes)
5827///
5828/// Defines a single segment of a spline-based ribbon with emission offset/vector, velocity, bone binding, and pitch/yaw/velocity variation channels.
5829pub struct SplineRibbon {
5830    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3SplineRibbon>,
5831}
5832
5833impl Drop for SplineRibbon {
5834    fn drop(&mut self) {
5835        // SAFETY: `raw` came from a native constructor and Drop runs once.
5836        unsafe { ffi::whiteout_m3_M3SplineRibbon_delete(self.raw.as_ptr()) }
5837    }
5838}
5839
5840impl SplineRibbon {
5841    /// # Safety
5842    /// `raw` must be a live handle this value takes ownership of.
5843    #[allow(dead_code)] // used by whichever methods return this type
5844    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3SplineRibbon) -> Option<Self> {
5845        core::ptr::NonNull::new(raw).map(|raw| SplineRibbon { raw })
5846    }
5847}
5848
5849// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
5850// is deliberately NOT implemented — the C++ types make no documented
5851// guarantee about concurrent use, and claiming one we haven't verified
5852// would be unsound. See `@bind thread_safe` in the plan.
5853unsafe impl Send for SplineRibbon {}
5854
5855impl core::fmt::Debug for SplineRibbon {
5856    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
5857        f.debug_struct("SplineRibbon").finish_non_exhaustive()
5858    }
5859}
5860
5861impl SplineRibbon {
5862    /// # Panics
5863    /// Panics if the native allocation fails.
5864    pub fn new() -> Self {
5865        // SAFETY: the native constructor returns a live handle; a null here
5866        // means the library is unusable.
5867        unsafe {
5868            let raw = ffi::whiteout_m3_M3SplineRibbon_new();
5869            Self::from_raw(raw).expect("native SplineRibbon allocation failed")
5870        }
5871    }
5872
5873    /// Emission point offset from bone
5874    pub fn emission_offset(&self) -> crate::math::Vector3f {
5875        // SAFETY: the getter returns an interior pointer to a
5876        // layout-identical POD; we copy it out immediately.
5877        unsafe {
5878            *(ffi::whiteout_m3_M3SplineRibbon_get_emissionOffset(self.raw.as_ptr())
5879                as *const crate::math::Vector3f)
5880        }
5881    }
5882
5883    pub fn set_emission_offset(&mut self, value: crate::math::Vector3f) {
5884        // SAFETY: as above, in the other direction.
5885        unsafe {
5886            ffi::whiteout_m3_M3SplineRibbon_set_emissionOffset(
5887                self.raw.as_ptr(),
5888                &value as *const crate::math::Vector3f as *const _,
5889            )
5890        }
5891    }
5892
5893    /// Emission direction vector
5894    pub fn emission_vector(&self) -> crate::math::Vector3f {
5895        // SAFETY: the getter returns an interior pointer to a
5896        // layout-identical POD; we copy it out immediately.
5897        unsafe {
5898            *(ffi::whiteout_m3_M3SplineRibbon_get_emissionVector(self.raw.as_ptr())
5899                as *const crate::math::Vector3f)
5900        }
5901    }
5902
5903    pub fn set_emission_vector(&mut self, value: crate::math::Vector3f) {
5904        // SAFETY: as above, in the other direction.
5905        unsafe {
5906            ffi::whiteout_m3_M3SplineRibbon_set_emissionVector(
5907                self.raw.as_ptr(),
5908                &value as *const crate::math::Vector3f as *const _,
5909            )
5910        }
5911    }
5912
5913    /// Animated base velocity
5914    /// Borrows the field in place — no copy, no allocation.
5915    pub fn velocity(&self) -> crate::support::Ref<'_, AnimRefF32> {
5916        // SAFETY: an interior pointer into `self`, valid for this
5917        // borrow and never freed by the `Ref`.
5918        unsafe {
5919            crate::support::Ref::new(AnimRefF32 {
5920                raw: core::ptr::NonNull::new_unchecked(
5921                    ffi::whiteout_m3_M3SplineRibbon_get_velocity(self.raw.as_ptr()),
5922                ),
5923            })
5924        }
5925    }
5926
5927    pub fn velocity_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
5928        // SAFETY: as above; `&mut self` guarantees exclusivity.
5929        unsafe {
5930            crate::support::RefMut::new(AnimRefF32 {
5931                raw: core::ptr::NonNull::new_unchecked(
5932                    ffi::whiteout_m3_M3SplineRibbon_get_velocity(self.raw.as_ptr()),
5933                ),
5934            })
5935        }
5936    }
5937
5938    /// Reserved (always 0)
5939    pub fn reserved(&self) -> u32 {
5940        // SAFETY: plain scalar read through a live handle.
5941        unsafe { ffi::whiteout_m3_M3SplineRibbon_get_reserved(self.raw.as_ptr()) }
5942    }
5943
5944    pub fn set_reserved(&mut self, value: u32) {
5945        // SAFETY: plain scalar write through a live handle.
5946        unsafe { ffi::whiteout_m3_M3SplineRibbon_set_reserved(self.raw.as_ptr(), value) }
5947    }
5948
5949    /// Index into BONE array
5950    pub fn bone_index(&self) -> u32 {
5951        // SAFETY: plain scalar read through a live handle.
5952        unsafe { ffi::whiteout_m3_M3SplineRibbon_get_boneIndex(self.raw.as_ptr()) }
5953    }
5954
5955    pub fn set_bone_index(&mut self, value: u32) {
5956        // SAFETY: plain scalar write through a live handle.
5957        unsafe { ffi::whiteout_m3_M3SplineRibbon_set_boneIndex(self.raw.as_ptr(), value) }
5958    }
5959
5960    /// Animated base velocity factor
5961    /// Borrows the field in place — no copy, no allocation.
5962    pub fn velocity_base_factor(&self) -> crate::support::Ref<'_, AnimRefF32> {
5963        // SAFETY: an interior pointer into `self`, valid for this
5964        // borrow and never freed by the `Ref`.
5965        unsafe {
5966            crate::support::Ref::new(AnimRefF32 {
5967                raw: core::ptr::NonNull::new_unchecked(
5968                    ffi::whiteout_m3_M3SplineRibbon_get_velocityBaseFactor(self.raw.as_ptr()),
5969                ),
5970            })
5971        }
5972    }
5973
5974    pub fn velocity_base_factor_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
5975        // SAFETY: as above; `&mut self` guarantees exclusivity.
5976        unsafe {
5977            crate::support::RefMut::new(AnimRefF32 {
5978                raw: core::ptr::NonNull::new_unchecked(
5979                    ffi::whiteout_m3_M3SplineRibbon_get_velocityBaseFactor(self.raw.as_ptr()),
5980                ),
5981            })
5982        }
5983    }
5984
5985    /// Animated end velocity factor
5986    /// Borrows the field in place — no copy, no allocation.
5987    pub fn velocity_end_factor(&self) -> crate::support::Ref<'_, AnimRefF32> {
5988        // SAFETY: an interior pointer into `self`, valid for this
5989        // borrow and never freed by the `Ref`.
5990        unsafe {
5991            crate::support::Ref::new(AnimRefF32 {
5992                raw: core::ptr::NonNull::new_unchecked(
5993                    ffi::whiteout_m3_M3SplineRibbon_get_velocityEndFactor(self.raw.as_ptr()),
5994                ),
5995            })
5996        }
5997    }
5998
5999    pub fn velocity_end_factor_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
6000        // SAFETY: as above; `&mut self` guarantees exclusivity.
6001        unsafe {
6002            crate::support::RefMut::new(AnimRefF32 {
6003                raw: core::ptr::NonNull::new_unchecked(
6004                    ffi::whiteout_m3_M3SplineRibbon_get_velocityEndFactor(self.raw.as_ptr()),
6005                ),
6006            })
6007        }
6008    }
6009
6010    /// Yaw variation type
6011    pub fn yaw_type(&self) -> u32 {
6012        // SAFETY: plain scalar read through a live handle.
6013        unsafe { ffi::whiteout_m3_M3SplineRibbon_get_yawType(self.raw.as_ptr()) }
6014    }
6015
6016    pub fn set_yaw_type(&mut self, value: u32) {
6017        // SAFETY: plain scalar write through a live handle.
6018        unsafe { ffi::whiteout_m3_M3SplineRibbon_set_yawType(self.raw.as_ptr(), value) }
6019    }
6020
6021    /// Yaw variation amplitude
6022    /// Borrows the field in place — no copy, no allocation.
6023    pub fn yaw_amplitude(&self) -> crate::support::Ref<'_, AnimRefF32> {
6024        // SAFETY: an interior pointer into `self`, valid for this
6025        // borrow and never freed by the `Ref`.
6026        unsafe {
6027            crate::support::Ref::new(AnimRefF32 {
6028                raw: core::ptr::NonNull::new_unchecked(
6029                    ffi::whiteout_m3_M3SplineRibbon_get_yawAmplitude(self.raw.as_ptr()),
6030                ),
6031            })
6032        }
6033    }
6034
6035    pub fn yaw_amplitude_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
6036        // SAFETY: as above; `&mut self` guarantees exclusivity.
6037        unsafe {
6038            crate::support::RefMut::new(AnimRefF32 {
6039                raw: core::ptr::NonNull::new_unchecked(
6040                    ffi::whiteout_m3_M3SplineRibbon_get_yawAmplitude(self.raw.as_ptr()),
6041                ),
6042            })
6043        }
6044    }
6045
6046    /// Yaw variation frequency
6047    /// Borrows the field in place — no copy, no allocation.
6048    pub fn yaw_frequency(&self) -> crate::support::Ref<'_, AnimRefF32> {
6049        // SAFETY: an interior pointer into `self`, valid for this
6050        // borrow and never freed by the `Ref`.
6051        unsafe {
6052            crate::support::Ref::new(AnimRefF32 {
6053                raw: core::ptr::NonNull::new_unchecked(
6054                    ffi::whiteout_m3_M3SplineRibbon_get_yawFrequency(self.raw.as_ptr()),
6055                ),
6056            })
6057        }
6058    }
6059
6060    pub fn yaw_frequency_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
6061        // SAFETY: as above; `&mut self` guarantees exclusivity.
6062        unsafe {
6063            crate::support::RefMut::new(AnimRefF32 {
6064                raw: core::ptr::NonNull::new_unchecked(
6065                    ffi::whiteout_m3_M3SplineRibbon_get_yawFrequency(self.raw.as_ptr()),
6066                ),
6067            })
6068        }
6069    }
6070
6071    /// Pitch variation type
6072    pub fn pitch_type(&self) -> u32 {
6073        // SAFETY: plain scalar read through a live handle.
6074        unsafe { ffi::whiteout_m3_M3SplineRibbon_get_pitchType(self.raw.as_ptr()) }
6075    }
6076
6077    pub fn set_pitch_type(&mut self, value: u32) {
6078        // SAFETY: plain scalar write through a live handle.
6079        unsafe { ffi::whiteout_m3_M3SplineRibbon_set_pitchType(self.raw.as_ptr(), value) }
6080    }
6081
6082    /// Pitch variation amplitude
6083    /// Borrows the field in place — no copy, no allocation.
6084    pub fn pitch_amplitude(&self) -> crate::support::Ref<'_, AnimRefF32> {
6085        // SAFETY: an interior pointer into `self`, valid for this
6086        // borrow and never freed by the `Ref`.
6087        unsafe {
6088            crate::support::Ref::new(AnimRefF32 {
6089                raw: core::ptr::NonNull::new_unchecked(
6090                    ffi::whiteout_m3_M3SplineRibbon_get_pitchAmplitude(self.raw.as_ptr()),
6091                ),
6092            })
6093        }
6094    }
6095
6096    pub fn pitch_amplitude_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
6097        // SAFETY: as above; `&mut self` guarantees exclusivity.
6098        unsafe {
6099            crate::support::RefMut::new(AnimRefF32 {
6100                raw: core::ptr::NonNull::new_unchecked(
6101                    ffi::whiteout_m3_M3SplineRibbon_get_pitchAmplitude(self.raw.as_ptr()),
6102                ),
6103            })
6104        }
6105    }
6106
6107    /// Pitch variation frequency
6108    /// Borrows the field in place — no copy, no allocation.
6109    pub fn pitch_frequency(&self) -> crate::support::Ref<'_, AnimRefF32> {
6110        // SAFETY: an interior pointer into `self`, valid for this
6111        // borrow and never freed by the `Ref`.
6112        unsafe {
6113            crate::support::Ref::new(AnimRefF32 {
6114                raw: core::ptr::NonNull::new_unchecked(
6115                    ffi::whiteout_m3_M3SplineRibbon_get_pitchFrequency(self.raw.as_ptr()),
6116                ),
6117            })
6118        }
6119    }
6120
6121    pub fn pitch_frequency_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
6122        // SAFETY: as above; `&mut self` guarantees exclusivity.
6123        unsafe {
6124            crate::support::RefMut::new(AnimRefF32 {
6125                raw: core::ptr::NonNull::new_unchecked(
6126                    ffi::whiteout_m3_M3SplineRibbon_get_pitchFrequency(self.raw.as_ptr()),
6127                ),
6128            })
6129        }
6130    }
6131
6132    /// Velocity variation type
6133    pub fn velocity_type(&self) -> u32 {
6134        // SAFETY: plain scalar read through a live handle.
6135        unsafe { ffi::whiteout_m3_M3SplineRibbon_get_velocityType(self.raw.as_ptr()) }
6136    }
6137
6138    pub fn set_velocity_type(&mut self, value: u32) {
6139        // SAFETY: plain scalar write through a live handle.
6140        unsafe { ffi::whiteout_m3_M3SplineRibbon_set_velocityType(self.raw.as_ptr(), value) }
6141    }
6142
6143    /// Velocity variation amplitude
6144    /// Borrows the field in place — no copy, no allocation.
6145    pub fn velocity_amplitude(&self) -> crate::support::Ref<'_, AnimRefF32> {
6146        // SAFETY: an interior pointer into `self`, valid for this
6147        // borrow and never freed by the `Ref`.
6148        unsafe {
6149            crate::support::Ref::new(AnimRefF32 {
6150                raw: core::ptr::NonNull::new_unchecked(
6151                    ffi::whiteout_m3_M3SplineRibbon_get_velocityAmplitude(self.raw.as_ptr()),
6152                ),
6153            })
6154        }
6155    }
6156
6157    pub fn velocity_amplitude_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
6158        // SAFETY: as above; `&mut self` guarantees exclusivity.
6159        unsafe {
6160            crate::support::RefMut::new(AnimRefF32 {
6161                raw: core::ptr::NonNull::new_unchecked(
6162                    ffi::whiteout_m3_M3SplineRibbon_get_velocityAmplitude(self.raw.as_ptr()),
6163                ),
6164            })
6165        }
6166    }
6167
6168    /// Velocity variation frequency
6169    /// Borrows the field in place — no copy, no allocation.
6170    pub fn velocity_frequency(&self) -> crate::support::Ref<'_, AnimRefF32> {
6171        // SAFETY: an interior pointer into `self`, valid for this
6172        // borrow and never freed by the `Ref`.
6173        unsafe {
6174            crate::support::Ref::new(AnimRefF32 {
6175                raw: core::ptr::NonNull::new_unchecked(
6176                    ffi::whiteout_m3_M3SplineRibbon_get_velocityFrequency(self.raw.as_ptr()),
6177                ),
6178            })
6179        }
6180    }
6181
6182    pub fn velocity_frequency_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
6183        // SAFETY: as above; `&mut self` guarantees exclusivity.
6184        unsafe {
6185            crate::support::RefMut::new(AnimRefF32 {
6186                raw: core::ptr::NonNull::new_unchecked(
6187                    ffi::whiteout_m3_M3SplineRibbon_get_velocityFrequency(self.raw.as_ptr()),
6188                ),
6189            })
6190        }
6191    }
6192
6193    /// Animated yaw angle
6194    /// Borrows the field in place — no copy, no allocation.
6195    pub fn yaw(&self) -> crate::support::Ref<'_, AnimRefF32> {
6196        // SAFETY: an interior pointer into `self`, valid for this
6197        // borrow and never freed by the `Ref`.
6198        unsafe {
6199            crate::support::Ref::new(AnimRefF32 {
6200                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3SplineRibbon_get_yaw(
6201                    self.raw.as_ptr(),
6202                )),
6203            })
6204        }
6205    }
6206
6207    pub fn yaw_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
6208        // SAFETY: as above; `&mut self` guarantees exclusivity.
6209        unsafe {
6210            crate::support::RefMut::new(AnimRefF32 {
6211                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3SplineRibbon_get_yaw(
6212                    self.raw.as_ptr(),
6213                )),
6214            })
6215        }
6216    }
6217
6218    /// Animated pitch angle
6219    /// Borrows the field in place — no copy, no allocation.
6220    pub fn pitch(&self) -> crate::support::Ref<'_, AnimRefF32> {
6221        // SAFETY: an interior pointer into `self`, valid for this
6222        // borrow and never freed by the `Ref`.
6223        unsafe {
6224            crate::support::Ref::new(AnimRefF32 {
6225                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3SplineRibbon_get_pitch(
6226                    self.raw.as_ptr(),
6227                )),
6228            })
6229        }
6230    }
6231
6232    pub fn pitch_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
6233        // SAFETY: as above; `&mut self` guarantees exclusivity.
6234        unsafe {
6235            crate::support::RefMut::new(AnimRefF32 {
6236                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3SplineRibbon_get_pitch(
6237                    self.raw.as_ptr(),
6238                )),
6239            })
6240        }
6241    }
6242
6243    /// Precomputed ≈ 0.01 / |emissionVector|
6244    pub fn emission_vector_norm_factor(&self) -> f32 {
6245        // SAFETY: plain scalar read through a live handle.
6246        unsafe { ffi::whiteout_m3_M3SplineRibbon_get_emissionVectorNormFactor(self.raw.as_ptr()) }
6247    }
6248
6249    pub fn set_emission_vector_norm_factor(&mut self, value: f32) {
6250        // SAFETY: plain scalar write through a live handle.
6251        unsafe {
6252            ffi::whiteout_m3_M3SplineRibbon_set_emissionVectorNormFactor(self.raw.as_ptr(), value)
6253        }
6254    }
6255
6256    /// Precomputed ≈ 0.01 / velocity.initValue
6257    pub fn velocity_norm_factor(&self) -> f32 {
6258        // SAFETY: plain scalar read through a live handle.
6259        unsafe { ffi::whiteout_m3_M3SplineRibbon_get_velocityNormFactor(self.raw.as_ptr()) }
6260    }
6261
6262    pub fn set_velocity_norm_factor(&mut self, value: f32) {
6263        // SAFETY: plain scalar write through a live handle.
6264        unsafe { ffi::whiteout_m3_M3SplineRibbon_set_velocityNormFactor(self.raw.as_ptr(), value) }
6265    }
6266}
6267
6268impl Default for SplineRibbon {
6269    fn default() -> Self {
6270        Self::new()
6271    }
6272}
6273
6274/// RIB_ — Ribbon emitter (v4–v9, 744–760 bytes)
6275///
6276/// 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.
6277pub struct RibbonEmitter {
6278    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3RibbonEmitter>,
6279}
6280
6281impl Drop for RibbonEmitter {
6282    fn drop(&mut self) {
6283        // SAFETY: `raw` came from a native constructor and Drop runs once.
6284        unsafe { ffi::whiteout_m3_M3RibbonEmitter_delete(self.raw.as_ptr()) }
6285    }
6286}
6287
6288impl RibbonEmitter {
6289    /// # Safety
6290    /// `raw` must be a live handle this value takes ownership of.
6291    #[allow(dead_code)] // used by whichever methods return this type
6292    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3RibbonEmitter) -> Option<Self> {
6293        core::ptr::NonNull::new(raw).map(|raw| RibbonEmitter { raw })
6294    }
6295}
6296
6297// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
6298// is deliberately NOT implemented — the C++ types make no documented
6299// guarantee about concurrent use, and claiming one we haven't verified
6300// would be unsound. See `@bind thread_safe` in the plan.
6301unsafe impl Send for RibbonEmitter {}
6302
6303impl core::fmt::Debug for RibbonEmitter {
6304    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
6305        f.debug_struct("RibbonEmitter").finish_non_exhaustive()
6306    }
6307}
6308
6309impl RibbonEmitter {
6310    /// # Panics
6311    /// Panics if the native allocation fails.
6312    pub fn new() -> Self {
6313        // SAFETY: the native constructor returns a live handle; a null here
6314        // means the library is unusable.
6315        unsafe {
6316            let raw = ffi::whiteout_m3_M3RibbonEmitter_new();
6317            Self::from_raw(raw).expect("native RibbonEmitter allocation failed")
6318        }
6319    }
6320
6321    /// Primary bone index
6322    pub fn bone_index(&self) -> u16 {
6323        // SAFETY: plain scalar read through a live handle.
6324        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_boneIndex(self.raw.as_ptr()) }
6325    }
6326
6327    pub fn set_bone_index(&mut self, value: u16) {
6328        // SAFETY: plain scalar write through a live handle.
6329        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_boneIndex(self.raw.as_ptr(), value) }
6330    }
6331
6332    /// Fallback bone index
6333    pub fn bone_index_fallback(&self) -> u16 {
6334        // SAFETY: plain scalar read through a live handle.
6335        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_boneIndexFallback(self.raw.as_ptr()) }
6336    }
6337
6338    pub fn set_bone_index_fallback(&mut self, value: u16) {
6339        // SAFETY: plain scalar write through a live handle.
6340        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_boneIndexFallback(self.raw.as_ptr(), value) }
6341    }
6342
6343    /// Index into MATM material map array
6344    pub fn material_index(&self) -> u32 {
6345        // SAFETY: plain scalar read through a live handle.
6346        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_materialIndex(self.raw.as_ptr()) }
6347    }
6348
6349    pub fn set_material_index(&mut self, value: u32) {
6350        // SAFETY: plain scalar write through a live handle.
6351        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_materialIndex(self.raw.as_ptr(), value) }
6352    }
6353
6354    /// Additional flags (v8+)
6355    pub fn additional_flags(&self) -> RibbonAdditionalFlag {
6356        // SAFETY: scalar read; a flag set accepts any bits.
6357        RibbonAdditionalFlag(unsafe {
6358            ffi::whiteout_m3_M3RibbonEmitter_get_additionalFlags(self.raw.as_ptr())
6359        })
6360    }
6361
6362    pub fn set_additional_flags(&mut self, value: RibbonAdditionalFlag) {
6363        // SAFETY: scalar write through a live handle.
6364        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_additionalFlags(self.raw.as_ptr(), value.0) }
6365    }
6366
6367    /// Initial ribbon segment speed
6368    /// Borrows the field in place — no copy, no allocation.
6369    pub fn initial_speed(&self) -> crate::support::Ref<'_, AnimRefF32> {
6370        // SAFETY: an interior pointer into `self`, valid for this
6371        // borrow and never freed by the `Ref`.
6372        unsafe {
6373            crate::support::Ref::new(AnimRefF32 {
6374                raw: core::ptr::NonNull::new_unchecked(
6375                    ffi::whiteout_m3_M3RibbonEmitter_get_initialSpeed(self.raw.as_ptr()),
6376                ),
6377            })
6378        }
6379    }
6380
6381    pub fn initial_speed_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
6382        // SAFETY: as above; `&mut self` guarantees exclusivity.
6383        unsafe {
6384            crate::support::RefMut::new(AnimRefF32 {
6385                raw: core::ptr::NonNull::new_unchecked(
6386                    ffi::whiteout_m3_M3RibbonEmitter_get_initialSpeed(self.raw.as_ptr()),
6387                ),
6388            })
6389        }
6390    }
6391
6392    /// Random speed variation
6393    /// Borrows the field in place — no copy, no allocation.
6394    pub fn initial_speed_random(&self) -> crate::support::Ref<'_, AnimRefF32> {
6395        // SAFETY: an interior pointer into `self`, valid for this
6396        // borrow and never freed by the `Ref`.
6397        unsafe {
6398            crate::support::Ref::new(AnimRefF32 {
6399                raw: core::ptr::NonNull::new_unchecked(
6400                    ffi::whiteout_m3_M3RibbonEmitter_get_initialSpeedRandom(self.raw.as_ptr()),
6401                ),
6402            })
6403        }
6404    }
6405
6406    pub fn initial_speed_random_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
6407        // SAFETY: as above; `&mut self` guarantees exclusivity.
6408        unsafe {
6409            crate::support::RefMut::new(AnimRefF32 {
6410                raw: core::ptr::NonNull::new_unchecked(
6411                    ffi::whiteout_m3_M3RibbonEmitter_get_initialSpeedRandom(self.raw.as_ptr()),
6412                ),
6413            })
6414        }
6415    }
6416
6417    /// Initial yaw angle
6418    /// Borrows the field in place — no copy, no allocation.
6419    pub fn initial_yaw(&self) -> crate::support::Ref<'_, AnimRefF32> {
6420        // SAFETY: an interior pointer into `self`, valid for this
6421        // borrow and never freed by the `Ref`.
6422        unsafe {
6423            crate::support::Ref::new(AnimRefF32 {
6424                raw: core::ptr::NonNull::new_unchecked(
6425                    ffi::whiteout_m3_M3RibbonEmitter_get_initialYaw(self.raw.as_ptr()),
6426                ),
6427            })
6428        }
6429    }
6430
6431    pub fn initial_yaw_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
6432        // SAFETY: as above; `&mut self` guarantees exclusivity.
6433        unsafe {
6434            crate::support::RefMut::new(AnimRefF32 {
6435                raw: core::ptr::NonNull::new_unchecked(
6436                    ffi::whiteout_m3_M3RibbonEmitter_get_initialYaw(self.raw.as_ptr()),
6437                ),
6438            })
6439        }
6440    }
6441
6442    /// Initial pitch angle
6443    /// Borrows the field in place — no copy, no allocation.
6444    pub fn initial_pitch(&self) -> crate::support::Ref<'_, AnimRefF32> {
6445        // SAFETY: an interior pointer into `self`, valid for this
6446        // borrow and never freed by the `Ref`.
6447        unsafe {
6448            crate::support::Ref::new(AnimRefF32 {
6449                raw: core::ptr::NonNull::new_unchecked(
6450                    ffi::whiteout_m3_M3RibbonEmitter_get_initialPitch(self.raw.as_ptr()),
6451                ),
6452            })
6453        }
6454    }
6455
6456    pub fn initial_pitch_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
6457        // SAFETY: as above; `&mut self` guarantees exclusivity.
6458        unsafe {
6459            crate::support::RefMut::new(AnimRefF32 {
6460                raw: core::ptr::NonNull::new_unchecked(
6461                    ffi::whiteout_m3_M3RibbonEmitter_get_initialPitch(self.raw.as_ptr()),
6462                ),
6463            })
6464        }
6465    }
6466
6467    /// Initial horizontal spread
6468    /// Borrows the field in place — no copy, no allocation.
6469    pub fn initial_horizontal(&self) -> crate::support::Ref<'_, AnimRefF32> {
6470        // SAFETY: an interior pointer into `self`, valid for this
6471        // borrow and never freed by the `Ref`.
6472        unsafe {
6473            crate::support::Ref::new(AnimRefF32 {
6474                raw: core::ptr::NonNull::new_unchecked(
6475                    ffi::whiteout_m3_M3RibbonEmitter_get_initialHorizontal(self.raw.as_ptr()),
6476                ),
6477            })
6478        }
6479    }
6480
6481    pub fn initial_horizontal_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
6482        // SAFETY: as above; `&mut self` guarantees exclusivity.
6483        unsafe {
6484            crate::support::RefMut::new(AnimRefF32 {
6485                raw: core::ptr::NonNull::new_unchecked(
6486                    ffi::whiteout_m3_M3RibbonEmitter_get_initialHorizontal(self.raw.as_ptr()),
6487                ),
6488            })
6489        }
6490    }
6491
6492    /// Initial vertical spread
6493    /// Borrows the field in place — no copy, no allocation.
6494    pub fn initial_vertical(&self) -> crate::support::Ref<'_, AnimRefF32> {
6495        // SAFETY: an interior pointer into `self`, valid for this
6496        // borrow and never freed by the `Ref`.
6497        unsafe {
6498            crate::support::Ref::new(AnimRefF32 {
6499                raw: core::ptr::NonNull::new_unchecked(
6500                    ffi::whiteout_m3_M3RibbonEmitter_get_initialVertical(self.raw.as_ptr()),
6501                ),
6502            })
6503        }
6504    }
6505
6506    pub fn initial_vertical_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
6507        // SAFETY: as above; `&mut self` guarantees exclusivity.
6508        unsafe {
6509            crate::support::RefMut::new(AnimRefF32 {
6510                raw: core::ptr::NonNull::new_unchecked(
6511                    ffi::whiteout_m3_M3RibbonEmitter_get_initialVertical(self.raw.as_ptr()),
6512                ),
6513            })
6514        }
6515    }
6516
6517    /// Base segment lifetime
6518    /// Borrows the field in place — no copy, no allocation.
6519    pub fn lifetime(&self) -> crate::support::Ref<'_, AnimRefF32> {
6520        // SAFETY: an interior pointer into `self`, valid for this
6521        // borrow and never freed by the `Ref`.
6522        unsafe {
6523            crate::support::Ref::new(AnimRefF32 {
6524                raw: core::ptr::NonNull::new_unchecked(
6525                    ffi::whiteout_m3_M3RibbonEmitter_get_lifetime(self.raw.as_ptr()),
6526                ),
6527            })
6528        }
6529    }
6530
6531    pub fn lifetime_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
6532        // SAFETY: as above; `&mut self` guarantees exclusivity.
6533        unsafe {
6534            crate::support::RefMut::new(AnimRefF32 {
6535                raw: core::ptr::NonNull::new_unchecked(
6536                    ffi::whiteout_m3_M3RibbonEmitter_get_lifetime(self.raw.as_ptr()),
6537                ),
6538            })
6539        }
6540    }
6541
6542    /// Random lifetime variation
6543    /// Borrows the field in place — no copy, no allocation.
6544    pub fn lifetime_random(&self) -> crate::support::Ref<'_, AnimRefF32> {
6545        // SAFETY: an interior pointer into `self`, valid for this
6546        // borrow and never freed by the `Ref`.
6547        unsafe {
6548            crate::support::Ref::new(AnimRefF32 {
6549                raw: core::ptr::NonNull::new_unchecked(
6550                    ffi::whiteout_m3_M3RibbonEmitter_get_lifetimeRandom(self.raw.as_ptr()),
6551                ),
6552            })
6553        }
6554    }
6555
6556    pub fn lifetime_random_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
6557        // SAFETY: as above; `&mut self` guarantees exclusivity.
6558        unsafe {
6559            crate::support::RefMut::new(AnimRefF32 {
6560                raw: core::ptr::NonNull::new_unchecked(
6561                    ffi::whiteout_m3_M3RibbonEmitter_get_lifetimeRandom(self.raw.as_ptr()),
6562                ),
6563            })
6564        }
6565    }
6566
6567    /// Kill radius
6568    pub fn kill_radius(&self) -> u32 {
6569        // SAFETY: plain scalar read through a live handle.
6570        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_killRadius(self.raw.as_ptr()) }
6571    }
6572
6573    pub fn set_kill_radius(&mut self, value: u32) {
6574        // SAFETY: plain scalar write through a live handle.
6575        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_killRadius(self.raw.as_ptr(), value) }
6576    }
6577
6578    /// Gravity X component
6579    pub fn gravity_x(&self) -> f32 {
6580        // SAFETY: plain scalar read through a live handle.
6581        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_gravityX(self.raw.as_ptr()) }
6582    }
6583
6584    pub fn set_gravity_x(&mut self, value: f32) {
6585        // SAFETY: plain scalar write through a live handle.
6586        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_gravityX(self.raw.as_ptr(), value) }
6587    }
6588
6589    /// Gravity Y component
6590    pub fn gravity_y(&self) -> f32 {
6591        // SAFETY: plain scalar read through a live handle.
6592        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_gravityY(self.raw.as_ptr()) }
6593    }
6594
6595    pub fn set_gravity_y(&mut self, value: f32) {
6596        // SAFETY: plain scalar write through a live handle.
6597        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_gravityY(self.raw.as_ptr(), value) }
6598    }
6599
6600    /// Gravity Z component
6601    pub fn gravity(&self) -> f32 {
6602        // SAFETY: plain scalar read through a live handle.
6603        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_gravity(self.raw.as_ptr()) }
6604    }
6605
6606    pub fn set_gravity(&mut self, value: f32) {
6607        // SAFETY: plain scalar write through a live handle.
6608        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_gravity(self.raw.as_ptr(), value) }
6609    }
6610
6611    /// Size midpoint time (0–1)
6612    pub fn size_mid_time(&self) -> f32 {
6613        // SAFETY: plain scalar read through a live handle.
6614        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_sizeMidTime(self.raw.as_ptr()) }
6615    }
6616
6617    pub fn set_size_mid_time(&mut self, value: f32) {
6618        // SAFETY: plain scalar write through a live handle.
6619        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_sizeMidTime(self.raw.as_ptr(), value) }
6620    }
6621
6622    /// Color midpoint time (0–1)
6623    pub fn color_mid_time(&self) -> f32 {
6624        // SAFETY: plain scalar read through a live handle.
6625        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_colorMidTime(self.raw.as_ptr()) }
6626    }
6627
6628    pub fn set_color_mid_time(&mut self, value: f32) {
6629        // SAFETY: plain scalar write through a live handle.
6630        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_colorMidTime(self.raw.as_ptr(), value) }
6631    }
6632
6633    /// Alpha midpoint time (0–1)
6634    pub fn alpha_mid_time(&self) -> f32 {
6635        // SAFETY: plain scalar read through a live handle.
6636        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_alphaMidTime(self.raw.as_ptr()) }
6637    }
6638
6639    pub fn set_alpha_mid_time(&mut self, value: f32) {
6640        // SAFETY: plain scalar write through a live handle.
6641        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_alphaMidTime(self.raw.as_ptr(), value) }
6642    }
6643
6644    /// Rotation midpoint time (0–1)
6645    pub fn rotation_mid_time(&self) -> f32 {
6646        // SAFETY: plain scalar read through a live handle.
6647        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_rotationMidTime(self.raw.as_ptr()) }
6648    }
6649
6650    pub fn set_rotation_mid_time(&mut self, value: f32) {
6651        // SAFETY: plain scalar write through a live handle.
6652        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_rotationMidTime(self.raw.as_ptr(), value) }
6653    }
6654
6655    /// Size hold time at midpoint
6656    pub fn size_mid_hold_time(&self) -> f32 {
6657        // SAFETY: plain scalar read through a live handle.
6658        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_sizeMidHoldTime(self.raw.as_ptr()) }
6659    }
6660
6661    pub fn set_size_mid_hold_time(&mut self, value: f32) {
6662        // SAFETY: plain scalar write through a live handle.
6663        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_sizeMidHoldTime(self.raw.as_ptr(), value) }
6664    }
6665
6666    /// Color hold time at midpoint
6667    pub fn color_mid_hold_time(&self) -> f32 {
6668        // SAFETY: plain scalar read through a live handle.
6669        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_colorMidHoldTime(self.raw.as_ptr()) }
6670    }
6671
6672    pub fn set_color_mid_hold_time(&mut self, value: f32) {
6673        // SAFETY: plain scalar write through a live handle.
6674        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_colorMidHoldTime(self.raw.as_ptr(), value) }
6675    }
6676
6677    /// Alpha hold time at midpoint
6678    pub fn alpha_mid_hold_time(&self) -> f32 {
6679        // SAFETY: plain scalar read through a live handle.
6680        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_alphaMidHoldTime(self.raw.as_ptr()) }
6681    }
6682
6683    pub fn set_alpha_mid_hold_time(&mut self, value: f32) {
6684        // SAFETY: plain scalar write through a live handle.
6685        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_alphaMidHoldTime(self.raw.as_ptr(), value) }
6686    }
6687
6688    /// Rotation hold time at midpoint
6689    pub fn rotation_mid_hold_time(&self) -> f32 {
6690        // SAFETY: plain scalar read through a live handle.
6691        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_rotationMidHoldTime(self.raw.as_ptr()) }
6692    }
6693
6694    pub fn set_rotation_mid_hold_time(&mut self, value: f32) {
6695        // SAFETY: plain scalar write through a live handle.
6696        unsafe {
6697            ffi::whiteout_m3_M3RibbonEmitter_set_rotationMidHoldTime(self.raw.as_ptr(), value)
6698        }
6699    }
6700
6701    /// Size curve (start, mid, end)
6702    /// Borrows the field in place — no copy, no allocation.
6703    pub fn size_animation(&self) -> crate::support::Ref<'_, AnimRefVector3f> {
6704        // SAFETY: an interior pointer into `self`, valid for this
6705        // borrow and never freed by the `Ref`.
6706        unsafe {
6707            crate::support::Ref::new(AnimRefVector3f {
6708                raw: core::ptr::NonNull::new_unchecked(
6709                    ffi::whiteout_m3_M3RibbonEmitter_get_sizeAnimation(self.raw.as_ptr()),
6710                ),
6711            })
6712        }
6713    }
6714
6715    pub fn size_animation_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector3f> {
6716        // SAFETY: as above; `&mut self` guarantees exclusivity.
6717        unsafe {
6718            crate::support::RefMut::new(AnimRefVector3f {
6719                raw: core::ptr::NonNull::new_unchecked(
6720                    ffi::whiteout_m3_M3RibbonEmitter_get_sizeAnimation(self.raw.as_ptr()),
6721                ),
6722            })
6723        }
6724    }
6725
6726    /// Rotation curve (start, mid, end)
6727    /// Borrows the field in place — no copy, no allocation.
6728    pub fn rotation_animation(&self) -> crate::support::Ref<'_, AnimRefVector3f> {
6729        // SAFETY: an interior pointer into `self`, valid for this
6730        // borrow and never freed by the `Ref`.
6731        unsafe {
6732            crate::support::Ref::new(AnimRefVector3f {
6733                raw: core::ptr::NonNull::new_unchecked(
6734                    ffi::whiteout_m3_M3RibbonEmitter_get_rotationAnimation(self.raw.as_ptr()),
6735                ),
6736            })
6737        }
6738    }
6739
6740    pub fn rotation_animation_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector3f> {
6741        // SAFETY: as above; `&mut self` guarantees exclusivity.
6742        unsafe {
6743            crate::support::RefMut::new(AnimRefVector3f {
6744                raw: core::ptr::NonNull::new_unchecked(
6745                    ffi::whiteout_m3_M3RibbonEmitter_get_rotationAnimation(self.raw.as_ptr()),
6746                ),
6747            })
6748        }
6749    }
6750
6751    /// Color at birth
6752    /// Borrows the field in place — no copy, no allocation.
6753    pub fn color_start(&self) -> crate::support::Ref<'_, AnimRefM3ColorBGRA> {
6754        // SAFETY: an interior pointer into `self`, valid for this
6755        // borrow and never freed by the `Ref`.
6756        unsafe {
6757            crate::support::Ref::new(AnimRefM3ColorBGRA {
6758                raw: core::ptr::NonNull::new_unchecked(
6759                    ffi::whiteout_m3_M3RibbonEmitter_get_colorStart(self.raw.as_ptr()),
6760                ),
6761            })
6762        }
6763    }
6764
6765    pub fn color_start_mut(&mut self) -> crate::support::RefMut<'_, AnimRefM3ColorBGRA> {
6766        // SAFETY: as above; `&mut self` guarantees exclusivity.
6767        unsafe {
6768            crate::support::RefMut::new(AnimRefM3ColorBGRA {
6769                raw: core::ptr::NonNull::new_unchecked(
6770                    ffi::whiteout_m3_M3RibbonEmitter_get_colorStart(self.raw.as_ptr()),
6771                ),
6772            })
6773        }
6774    }
6775
6776    /// Color at midpoint
6777    /// Borrows the field in place — no copy, no allocation.
6778    pub fn color_mid(&self) -> crate::support::Ref<'_, AnimRefM3ColorBGRA> {
6779        // SAFETY: an interior pointer into `self`, valid for this
6780        // borrow and never freed by the `Ref`.
6781        unsafe {
6782            crate::support::Ref::new(AnimRefM3ColorBGRA {
6783                raw: core::ptr::NonNull::new_unchecked(
6784                    ffi::whiteout_m3_M3RibbonEmitter_get_colorMid(self.raw.as_ptr()),
6785                ),
6786            })
6787        }
6788    }
6789
6790    pub fn color_mid_mut(&mut self) -> crate::support::RefMut<'_, AnimRefM3ColorBGRA> {
6791        // SAFETY: as above; `&mut self` guarantees exclusivity.
6792        unsafe {
6793            crate::support::RefMut::new(AnimRefM3ColorBGRA {
6794                raw: core::ptr::NonNull::new_unchecked(
6795                    ffi::whiteout_m3_M3RibbonEmitter_get_colorMid(self.raw.as_ptr()),
6796                ),
6797            })
6798        }
6799    }
6800
6801    /// Color at death
6802    /// Borrows the field in place — no copy, no allocation.
6803    pub fn color_end(&self) -> crate::support::Ref<'_, AnimRefM3ColorBGRA> {
6804        // SAFETY: an interior pointer into `self`, valid for this
6805        // borrow and never freed by the `Ref`.
6806        unsafe {
6807            crate::support::Ref::new(AnimRefM3ColorBGRA {
6808                raw: core::ptr::NonNull::new_unchecked(
6809                    ffi::whiteout_m3_M3RibbonEmitter_get_colorEnd(self.raw.as_ptr()),
6810                ),
6811            })
6812        }
6813    }
6814
6815    pub fn color_end_mut(&mut self) -> crate::support::RefMut<'_, AnimRefM3ColorBGRA> {
6816        // SAFETY: as above; `&mut self` guarantees exclusivity.
6817        unsafe {
6818            crate::support::RefMut::new(AnimRefM3ColorBGRA {
6819                raw: core::ptr::NonNull::new_unchecked(
6820                    ffi::whiteout_m3_M3RibbonEmitter_get_colorEnd(self.raw.as_ptr()),
6821                ),
6822            })
6823        }
6824    }
6825
6826    /// Air drag coefficient
6827    pub fn drag(&self) -> f32 {
6828        // SAFETY: plain scalar read through a live handle.
6829        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_drag(self.raw.as_ptr()) }
6830    }
6831
6832    pub fn set_drag(&mut self, value: f32) {
6833        // SAFETY: plain scalar write through a live handle.
6834        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_drag(self.raw.as_ptr(), value) }
6835    }
6836
6837    /// Segment mass
6838    pub fn mass(&self) -> f32 {
6839        // SAFETY: plain scalar read through a live handle.
6840        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_mass(self.raw.as_ptr()) }
6841    }
6842
6843    pub fn set_mass(&mut self, value: f32) {
6844        // SAFETY: plain scalar write through a live handle.
6845        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_mass(self.raw.as_ptr(), value) }
6846    }
6847
6848    /// Random mass variation
6849    pub fn mass_random(&self) -> f32 {
6850        // SAFETY: plain scalar read through a live handle.
6851        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_massRandom(self.raw.as_ptr()) }
6852    }
6853
6854    pub fn set_mass_random(&mut self, value: f32) {
6855        // SAFETY: plain scalar write through a live handle.
6856        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_massRandom(self.raw.as_ptr(), value) }
6857    }
6858
6859    /// Mass–size coupling
6860    pub fn mass_size_multiplier(&self) -> f32 {
6861        // SAFETY: plain scalar read through a live handle.
6862        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_massSizeMultiplier(self.raw.as_ptr()) }
6863    }
6864
6865    pub fn set_mass_size_multiplier(&mut self, value: f32) {
6866        // SAFETY: plain scalar write through a live handle.
6867        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_massSizeMultiplier(self.raw.as_ptr(), value) }
6868    }
6869
6870    /// Local force channel bitmask
6871    pub fn local_forces(&self) -> u16 {
6872        // SAFETY: plain scalar read through a live handle.
6873        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_localForces(self.raw.as_ptr()) }
6874    }
6875
6876    pub fn set_local_forces(&mut self, value: u16) {
6877        // SAFETY: plain scalar write through a live handle.
6878        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_localForces(self.raw.as_ptr(), value) }
6879    }
6880
6881    /// World force channel bitmask
6882    pub fn world_forces(&self) -> u16 {
6883        // SAFETY: plain scalar read through a live handle.
6884        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_worldForces(self.raw.as_ptr()) }
6885    }
6886
6887    pub fn set_world_forces(&mut self, value: u16) {
6888        // SAFETY: plain scalar write through a live handle.
6889        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_worldForces(self.raw.as_ptr(), value) }
6890    }
6891
6892    /// Fallback local force channels
6893    pub fn local_forces_fallback(&self) -> u16 {
6894        // SAFETY: plain scalar read through a live handle.
6895        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_localForcesFallback(self.raw.as_ptr()) }
6896    }
6897
6898    pub fn set_local_forces_fallback(&mut self, value: u16) {
6899        // SAFETY: plain scalar write through a live handle.
6900        unsafe {
6901            ffi::whiteout_m3_M3RibbonEmitter_set_localForcesFallback(self.raw.as_ptr(), value)
6902        }
6903    }
6904
6905    /// Fallback world force channels
6906    pub fn world_forces_fallback(&self) -> u16 {
6907        // SAFETY: plain scalar read through a live handle.
6908        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_worldForcesFallback(self.raw.as_ptr()) }
6909    }
6910
6911    pub fn set_world_forces_fallback(&mut self, value: u16) {
6912        // SAFETY: plain scalar write through a live handle.
6913        unsafe {
6914            ffi::whiteout_m3_M3RibbonEmitter_set_worldForcesFallback(self.raw.as_ptr(), value)
6915        }
6916    }
6917
6918    /// World force mass multiplier
6919    pub fn world_forces_mass_multiplier(&self) -> f32 {
6920        // SAFETY: plain scalar read through a live handle.
6921        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_worldForcesMassMultiplier(self.raw.as_ptr()) }
6922    }
6923
6924    pub fn set_world_forces_mass_multiplier(&mut self, value: f32) {
6925        // SAFETY: plain scalar write through a live handle.
6926        unsafe {
6927            ffi::whiteout_m3_M3RibbonEmitter_set_worldForcesMassMultiplier(self.raw.as_ptr(), value)
6928        }
6929    }
6930
6931    /// Noise displacement amplitude
6932    pub fn noise_amplitude(&self) -> f32 {
6933        // SAFETY: plain scalar read through a live handle.
6934        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_noiseAmplitude(self.raw.as_ptr()) }
6935    }
6936
6937    pub fn set_noise_amplitude(&mut self, value: f32) {
6938        // SAFETY: plain scalar write through a live handle.
6939        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_noiseAmplitude(self.raw.as_ptr(), value) }
6940    }
6941
6942    /// Noise spatial frequency
6943    pub fn noise_frequency(&self) -> f32 {
6944        // SAFETY: plain scalar read through a live handle.
6945        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_noiseFrequency(self.raw.as_ptr()) }
6946    }
6947
6948    pub fn set_noise_frequency(&mut self, value: f32) {
6949        // SAFETY: plain scalar write through a live handle.
6950        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_noiseFrequency(self.raw.as_ptr(), value) }
6951    }
6952
6953    /// Noise temporal coherence
6954    pub fn noise_coherence(&self) -> f32 {
6955        // SAFETY: plain scalar read through a live handle.
6956        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_noiseCoherence(self.raw.as_ptr()) }
6957    }
6958
6959    pub fn set_noise_coherence(&mut self, value: f32) {
6960        // SAFETY: plain scalar write through a live handle.
6961        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_noiseCoherence(self.raw.as_ptr(), value) }
6962    }
6963
6964    /// Noise edge sharpness
6965    pub fn noise_edge(&self) -> f32 {
6966        // SAFETY: plain scalar read through a live handle.
6967        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_noiseEdge(self.raw.as_ptr()) }
6968    }
6969
6970    pub fn set_noise_edge(&mut self, value: f32) {
6971        // SAFETY: plain scalar write through a live handle.
6972        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_noiseEdge(self.raw.as_ptr(), value) }
6973    }
6974
6975    /// Index + length
6976    pub fn index_plus_length(&self) -> u32 {
6977        // SAFETY: plain scalar read through a live handle.
6978        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_indexPlusLength(self.raw.as_ptr()) }
6979    }
6980
6981    pub fn set_index_plus_length(&mut self, value: u32) {
6982        // SAFETY: plain scalar write through a live handle.
6983        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_indexPlusLength(self.raw.as_ptr(), value) }
6984    }
6985
6986    /// Emitter shape type
6987    pub fn emitter_shape(&self) -> u32 {
6988        // SAFETY: plain scalar read through a live handle.
6989        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_emitterShape(self.raw.as_ptr()) }
6990    }
6991
6992    pub fn set_emitter_shape(&mut self, value: u32) {
6993        // SAFETY: plain scalar write through a live handle.
6994        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_emitterShape(self.raw.as_ptr(), value) }
6995    }
6996
6997    /// Ribbon cross-section type
6998    pub fn ribbon_type(&self) -> RibbonType {
6999        // SAFETY: scalar read; the discriminant is validated below.
7000        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_ribbonType(self.raw.as_ptr()) }
7001            .try_into()
7002            .expect("unknown enum discriminant from the native library")
7003    }
7004
7005    pub fn set_ribbon_type(&mut self, value: RibbonType) {
7006        // SAFETY: scalar write through a live handle.
7007        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_ribbonType(self.raw.as_ptr(), value as i32) }
7008    }
7009
7010    /// Number of ribbon divisions
7011    pub fn divisions(&self) -> f32 {
7012        // SAFETY: plain scalar read through a live handle.
7013        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_divisions(self.raw.as_ptr()) }
7014    }
7015
7016    pub fn set_divisions(&mut self, value: f32) {
7017        // SAFETY: plain scalar write through a live handle.
7018        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_divisions(self.raw.as_ptr(), value) }
7019    }
7020
7021    /// Number of cross-section edges
7022    pub fn edges(&self) -> u32 {
7023        // SAFETY: plain scalar read through a live handle.
7024        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_edges(self.raw.as_ptr()) }
7025    }
7026
7027    pub fn set_edges(&mut self, value: u32) {
7028        // SAFETY: plain scalar write through a live handle.
7029        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_edges(self.raw.as_ptr(), value) }
7030    }
7031
7032    /// Inner radius
7033    pub fn inner_radius(&self) -> f32 {
7034        // SAFETY: plain scalar read through a live handle.
7035        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_innerRadius(self.raw.as_ptr()) }
7036    }
7037
7038    pub fn set_inner_radius(&mut self, value: f32) {
7039        // SAFETY: plain scalar write through a live handle.
7040        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_innerRadius(self.raw.as_ptr(), value) }
7041    }
7042
7043    /// Animated maximum ribbon length
7044    /// Borrows the field in place — no copy, no allocation.
7045    pub fn max_length(&self) -> crate::support::Ref<'_, AnimRefF32> {
7046        // SAFETY: an interior pointer into `self`, valid for this
7047        // borrow and never freed by the `Ref`.
7048        unsafe {
7049            crate::support::Ref::new(AnimRefF32 {
7050                raw: core::ptr::NonNull::new_unchecked(
7051                    ffi::whiteout_m3_M3RibbonEmitter_get_maxLength(self.raw.as_ptr()),
7052                ),
7053            })
7054        }
7055    }
7056
7057    pub fn max_length_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7058        // SAFETY: as above; `&mut self` guarantees exclusivity.
7059        unsafe {
7060            crate::support::RefMut::new(AnimRefF32 {
7061                raw: core::ptr::NonNull::new_unchecked(
7062                    ffi::whiteout_m3_M3RibbonEmitter_get_maxLength(self.raw.as_ptr()),
7063                ),
7064            })
7065        }
7066    }
7067
7068    /// Spline ribbon segments (SRIB)
7069    pub fn spline_ribbons_len(&self) -> usize {
7070        // SAFETY: scalar read through a live handle.
7071        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_splineRibbons_count(self.raw.as_ptr()) }
7072    }
7073
7074    /// Borrows element `index` in place. `None` when out of range.
7075    pub fn spline_ribbons(&self, index: usize) -> Option<crate::support::Ref<'_, SplineRibbon>> {
7076        if index >= self.spline_ribbons_len() {
7077            return None;
7078        }
7079        // SAFETY: index checked above; the pointer is interior to `self`.
7080        unsafe {
7081            Some(crate::support::Ref::new(SplineRibbon {
7082                raw: core::ptr::NonNull::new_unchecked(
7083                    ffi::whiteout_m3_M3RibbonEmitter_get_splineRibbons_at(self.raw.as_ptr(), index),
7084                ),
7085            }))
7086        }
7087    }
7088
7089    pub fn spline_ribbons_mut(
7090        &mut self,
7091        index: usize,
7092    ) -> Option<crate::support::RefMut<'_, SplineRibbon>> {
7093        if index >= self.spline_ribbons_len() {
7094            return None;
7095        }
7096        // SAFETY: as above; `&mut self` guarantees exclusivity.
7097        unsafe {
7098            Some(crate::support::RefMut::new(SplineRibbon {
7099                raw: core::ptr::NonNull::new_unchecked(
7100                    ffi::whiteout_m3_M3RibbonEmitter_get_splineRibbons_at(self.raw.as_ptr(), index),
7101                ),
7102            }))
7103        }
7104    }
7105
7106    /// Iterate the elements, borrowing each in turn.
7107    pub fn spline_ribbons_iter(
7108        &self,
7109    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, SplineRibbon>> {
7110        (0..self.spline_ribbons_len())
7111            .map(move |i| self.spline_ribbons(i).expect("index below len"))
7112    }
7113
7114    pub fn resize_spline_ribbons(&mut self, count: usize) {
7115        // SAFETY: exclusive access, so no borrow is outstanding.
7116        unsafe { ffi::whiteout_m3_M3RibbonEmitter_resize_splineRibbons(self.raw.as_ptr(), count) }
7117    }
7118
7119    /// Animated active state
7120    /// Borrows the field in place — no copy, no allocation.
7121    pub fn active(&self) -> crate::support::Ref<'_, AnimRefU32> {
7122        // SAFETY: an interior pointer into `self`, valid for this
7123        // borrow and never freed by the `Ref`.
7124        unsafe {
7125            crate::support::Ref::new(AnimRefU32 {
7126                raw: core::ptr::NonNull::new_unchecked(
7127                    ffi::whiteout_m3_M3RibbonEmitter_get_active(self.raw.as_ptr()),
7128                ),
7129            })
7130        }
7131    }
7132
7133    pub fn active_mut(&mut self) -> crate::support::RefMut<'_, AnimRefU32> {
7134        // SAFETY: as above; `&mut self` guarantees exclusivity.
7135        unsafe {
7136            crate::support::RefMut::new(AnimRefU32 {
7137                raw: core::ptr::NonNull::new_unchecked(
7138                    ffi::whiteout_m3_M3RibbonEmitter_get_active(self.raw.as_ptr()),
7139                ),
7140            })
7141        }
7142    }
7143
7144    /// Ribbon emitter flags
7145    pub fn flags(&self) -> RibbonFlag {
7146        // SAFETY: scalar read; a flag set accepts any bits.
7147        RibbonFlag(unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_flags(self.raw.as_ptr()) })
7148    }
7149
7150    pub fn set_flags(&mut self, value: RibbonFlag) {
7151        // SAFETY: scalar write through a live handle.
7152        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_flags(self.raw.as_ptr(), value.0) }
7153    }
7154
7155    /// Size interpolation mode
7156    pub fn size_smoothing(&self) -> InterpolationMode {
7157        // SAFETY: scalar read; the discriminant is validated below.
7158        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_sizeSmoothing(self.raw.as_ptr()) }
7159            .try_into()
7160            .expect("unknown enum discriminant from the native library")
7161    }
7162
7163    pub fn set_size_smoothing(&mut self, value: InterpolationMode) {
7164        // SAFETY: scalar write through a live handle.
7165        unsafe {
7166            ffi::whiteout_m3_M3RibbonEmitter_set_sizeSmoothing(self.raw.as_ptr(), value as i32)
7167        }
7168    }
7169
7170    /// Color interpolation mode
7171    pub fn color_smoothing(&self) -> InterpolationMode {
7172        // SAFETY: scalar read; the discriminant is validated below.
7173        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_colorSmoothing(self.raw.as_ptr()) }
7174            .try_into()
7175            .expect("unknown enum discriminant from the native library")
7176    }
7177
7178    pub fn set_color_smoothing(&mut self, value: InterpolationMode) {
7179        // SAFETY: scalar write through a live handle.
7180        unsafe {
7181            ffi::whiteout_m3_M3RibbonEmitter_set_colorSmoothing(self.raw.as_ptr(), value as i32)
7182        }
7183    }
7184
7185    /// Friction coefficient
7186    pub fn friction(&self) -> f32 {
7187        // SAFETY: plain scalar read through a live handle.
7188        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_friction(self.raw.as_ptr()) }
7189    }
7190
7191    pub fn set_friction(&mut self, value: f32) {
7192        // SAFETY: plain scalar write through a live handle.
7193        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_friction(self.raw.as_ptr(), value) }
7194    }
7195
7196    /// Bounce coefficient
7197    pub fn bounce(&self) -> f32 {
7198        // SAFETY: plain scalar read through a live handle.
7199        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_bounce(self.raw.as_ptr()) }
7200    }
7201
7202    pub fn set_bounce(&mut self, value: f32) {
7203        // SAFETY: plain scalar write through a live handle.
7204        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_bounce(self.raw.as_ptr(), value) }
7205    }
7206
7207    /// LOD reduction level
7208    pub fn lod_reduce(&self) -> u32 {
7209        // SAFETY: plain scalar read through a live handle.
7210        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_lodReduce(self.raw.as_ptr()) }
7211    }
7212
7213    pub fn set_lod_reduce(&mut self, value: u32) {
7214        // SAFETY: plain scalar write through a live handle.
7215        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_lodReduce(self.raw.as_ptr(), value) }
7216    }
7217
7218    /// LOD cut-off level
7219    pub fn lod_cut(&self) -> u32 {
7220        // SAFETY: plain scalar read through a live handle.
7221        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_lodCut(self.raw.as_ptr()) }
7222    }
7223
7224    pub fn set_lod_cut(&mut self, value: u32) {
7225        // SAFETY: plain scalar write through a live handle.
7226        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_lodCut(self.raw.as_ptr(), value) }
7227    }
7228
7229    /// Yaw variation type
7230    pub fn yaw_type(&self) -> u32 {
7231        // SAFETY: plain scalar read through a live handle.
7232        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_yawType(self.raw.as_ptr()) }
7233    }
7234
7235    pub fn set_yaw_type(&mut self, value: u32) {
7236        // SAFETY: plain scalar write through a live handle.
7237        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_yawType(self.raw.as_ptr(), value) }
7238    }
7239
7240    /// Yaw variation amplitude
7241    /// Borrows the field in place — no copy, no allocation.
7242    pub fn yaw_amplitude(&self) -> crate::support::Ref<'_, AnimRefF32> {
7243        // SAFETY: an interior pointer into `self`, valid for this
7244        // borrow and never freed by the `Ref`.
7245        unsafe {
7246            crate::support::Ref::new(AnimRefF32 {
7247                raw: core::ptr::NonNull::new_unchecked(
7248                    ffi::whiteout_m3_M3RibbonEmitter_get_yawAmplitude(self.raw.as_ptr()),
7249                ),
7250            })
7251        }
7252    }
7253
7254    pub fn yaw_amplitude_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7255        // SAFETY: as above; `&mut self` guarantees exclusivity.
7256        unsafe {
7257            crate::support::RefMut::new(AnimRefF32 {
7258                raw: core::ptr::NonNull::new_unchecked(
7259                    ffi::whiteout_m3_M3RibbonEmitter_get_yawAmplitude(self.raw.as_ptr()),
7260                ),
7261            })
7262        }
7263    }
7264
7265    /// Yaw variation frequency
7266    /// Borrows the field in place — no copy, no allocation.
7267    pub fn yaw_frequency(&self) -> crate::support::Ref<'_, AnimRefF32> {
7268        // SAFETY: an interior pointer into `self`, valid for this
7269        // borrow and never freed by the `Ref`.
7270        unsafe {
7271            crate::support::Ref::new(AnimRefF32 {
7272                raw: core::ptr::NonNull::new_unchecked(
7273                    ffi::whiteout_m3_M3RibbonEmitter_get_yawFrequency(self.raw.as_ptr()),
7274                ),
7275            })
7276        }
7277    }
7278
7279    pub fn yaw_frequency_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7280        // SAFETY: as above; `&mut self` guarantees exclusivity.
7281        unsafe {
7282            crate::support::RefMut::new(AnimRefF32 {
7283                raw: core::ptr::NonNull::new_unchecked(
7284                    ffi::whiteout_m3_M3RibbonEmitter_get_yawFrequency(self.raw.as_ptr()),
7285                ),
7286            })
7287        }
7288    }
7289
7290    /// Pitch variation type
7291    pub fn pitch_type(&self) -> u32 {
7292        // SAFETY: plain scalar read through a live handle.
7293        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_pitchType(self.raw.as_ptr()) }
7294    }
7295
7296    pub fn set_pitch_type(&mut self, value: u32) {
7297        // SAFETY: plain scalar write through a live handle.
7298        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_pitchType(self.raw.as_ptr(), value) }
7299    }
7300
7301    /// Pitch variation amplitude
7302    /// Borrows the field in place — no copy, no allocation.
7303    pub fn pitch_amplitude(&self) -> crate::support::Ref<'_, AnimRefF32> {
7304        // SAFETY: an interior pointer into `self`, valid for this
7305        // borrow and never freed by the `Ref`.
7306        unsafe {
7307            crate::support::Ref::new(AnimRefF32 {
7308                raw: core::ptr::NonNull::new_unchecked(
7309                    ffi::whiteout_m3_M3RibbonEmitter_get_pitchAmplitude(self.raw.as_ptr()),
7310                ),
7311            })
7312        }
7313    }
7314
7315    pub fn pitch_amplitude_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7316        // SAFETY: as above; `&mut self` guarantees exclusivity.
7317        unsafe {
7318            crate::support::RefMut::new(AnimRefF32 {
7319                raw: core::ptr::NonNull::new_unchecked(
7320                    ffi::whiteout_m3_M3RibbonEmitter_get_pitchAmplitude(self.raw.as_ptr()),
7321                ),
7322            })
7323        }
7324    }
7325
7326    /// Pitch variation frequency
7327    /// Borrows the field in place — no copy, no allocation.
7328    pub fn pitch_frequency(&self) -> crate::support::Ref<'_, AnimRefF32> {
7329        // SAFETY: an interior pointer into `self`, valid for this
7330        // borrow and never freed by the `Ref`.
7331        unsafe {
7332            crate::support::Ref::new(AnimRefF32 {
7333                raw: core::ptr::NonNull::new_unchecked(
7334                    ffi::whiteout_m3_M3RibbonEmitter_get_pitchFrequency(self.raw.as_ptr()),
7335                ),
7336            })
7337        }
7338    }
7339
7340    pub fn pitch_frequency_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7341        // SAFETY: as above; `&mut self` guarantees exclusivity.
7342        unsafe {
7343            crate::support::RefMut::new(AnimRefF32 {
7344                raw: core::ptr::NonNull::new_unchecked(
7345                    ffi::whiteout_m3_M3RibbonEmitter_get_pitchFrequency(self.raw.as_ptr()),
7346                ),
7347            })
7348        }
7349    }
7350
7351    /// Speed variation type
7352    pub fn speed_type(&self) -> u32 {
7353        // SAFETY: plain scalar read through a live handle.
7354        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_speedType(self.raw.as_ptr()) }
7355    }
7356
7357    pub fn set_speed_type(&mut self, value: u32) {
7358        // SAFETY: plain scalar write through a live handle.
7359        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_speedType(self.raw.as_ptr(), value) }
7360    }
7361
7362    /// Speed variation amplitude
7363    /// Borrows the field in place — no copy, no allocation.
7364    pub fn speed_amplitude(&self) -> crate::support::Ref<'_, AnimRefF32> {
7365        // SAFETY: an interior pointer into `self`, valid for this
7366        // borrow and never freed by the `Ref`.
7367        unsafe {
7368            crate::support::Ref::new(AnimRefF32 {
7369                raw: core::ptr::NonNull::new_unchecked(
7370                    ffi::whiteout_m3_M3RibbonEmitter_get_speedAmplitude(self.raw.as_ptr()),
7371                ),
7372            })
7373        }
7374    }
7375
7376    pub fn speed_amplitude_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7377        // SAFETY: as above; `&mut self` guarantees exclusivity.
7378        unsafe {
7379            crate::support::RefMut::new(AnimRefF32 {
7380                raw: core::ptr::NonNull::new_unchecked(
7381                    ffi::whiteout_m3_M3RibbonEmitter_get_speedAmplitude(self.raw.as_ptr()),
7382                ),
7383            })
7384        }
7385    }
7386
7387    /// Speed variation frequency
7388    /// Borrows the field in place — no copy, no allocation.
7389    pub fn speed_frequency(&self) -> crate::support::Ref<'_, AnimRefF32> {
7390        // SAFETY: an interior pointer into `self`, valid for this
7391        // borrow and never freed by the `Ref`.
7392        unsafe {
7393            crate::support::Ref::new(AnimRefF32 {
7394                raw: core::ptr::NonNull::new_unchecked(
7395                    ffi::whiteout_m3_M3RibbonEmitter_get_speedFrequency(self.raw.as_ptr()),
7396                ),
7397            })
7398        }
7399    }
7400
7401    pub fn speed_frequency_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7402        // SAFETY: as above; `&mut self` guarantees exclusivity.
7403        unsafe {
7404            crate::support::RefMut::new(AnimRefF32 {
7405                raw: core::ptr::NonNull::new_unchecked(
7406                    ffi::whiteout_m3_M3RibbonEmitter_get_speedFrequency(self.raw.as_ptr()),
7407                ),
7408            })
7409        }
7410    }
7411
7412    /// Size variation type
7413    pub fn size_type(&self) -> u32 {
7414        // SAFETY: plain scalar read through a live handle.
7415        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_sizeType(self.raw.as_ptr()) }
7416    }
7417
7418    pub fn set_size_type(&mut self, value: u32) {
7419        // SAFETY: plain scalar write through a live handle.
7420        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_sizeType(self.raw.as_ptr(), value) }
7421    }
7422
7423    /// Size variation amplitude
7424    /// Borrows the field in place — no copy, no allocation.
7425    pub fn size_amplitude(&self) -> crate::support::Ref<'_, AnimRefF32> {
7426        // SAFETY: an interior pointer into `self`, valid for this
7427        // borrow and never freed by the `Ref`.
7428        unsafe {
7429            crate::support::Ref::new(AnimRefF32 {
7430                raw: core::ptr::NonNull::new_unchecked(
7431                    ffi::whiteout_m3_M3RibbonEmitter_get_sizeAmplitude(self.raw.as_ptr()),
7432                ),
7433            })
7434        }
7435    }
7436
7437    pub fn size_amplitude_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7438        // SAFETY: as above; `&mut self` guarantees exclusivity.
7439        unsafe {
7440            crate::support::RefMut::new(AnimRefF32 {
7441                raw: core::ptr::NonNull::new_unchecked(
7442                    ffi::whiteout_m3_M3RibbonEmitter_get_sizeAmplitude(self.raw.as_ptr()),
7443                ),
7444            })
7445        }
7446    }
7447
7448    /// Size variation frequency
7449    /// Borrows the field in place — no copy, no allocation.
7450    pub fn size_frequency(&self) -> crate::support::Ref<'_, AnimRefF32> {
7451        // SAFETY: an interior pointer into `self`, valid for this
7452        // borrow and never freed by the `Ref`.
7453        unsafe {
7454            crate::support::Ref::new(AnimRefF32 {
7455                raw: core::ptr::NonNull::new_unchecked(
7456                    ffi::whiteout_m3_M3RibbonEmitter_get_sizeFrequency(self.raw.as_ptr()),
7457                ),
7458            })
7459        }
7460    }
7461
7462    pub fn size_frequency_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7463        // SAFETY: as above; `&mut self` guarantees exclusivity.
7464        unsafe {
7465            crate::support::RefMut::new(AnimRefF32 {
7466                raw: core::ptr::NonNull::new_unchecked(
7467                    ffi::whiteout_m3_M3RibbonEmitter_get_sizeFrequency(self.raw.as_ptr()),
7468                ),
7469            })
7470        }
7471    }
7472
7473    /// Alpha variation type
7474    pub fn alpha_type(&self) -> u32 {
7475        // SAFETY: plain scalar read through a live handle.
7476        unsafe { ffi::whiteout_m3_M3RibbonEmitter_get_alphaType(self.raw.as_ptr()) }
7477    }
7478
7479    pub fn set_alpha_type(&mut self, value: u32) {
7480        // SAFETY: plain scalar write through a live handle.
7481        unsafe { ffi::whiteout_m3_M3RibbonEmitter_set_alphaType(self.raw.as_ptr(), value) }
7482    }
7483
7484    /// Alpha variation amplitude
7485    /// Borrows the field in place — no copy, no allocation.
7486    pub fn alpha_amplitude(&self) -> crate::support::Ref<'_, AnimRefF32> {
7487        // SAFETY: an interior pointer into `self`, valid for this
7488        // borrow and never freed by the `Ref`.
7489        unsafe {
7490            crate::support::Ref::new(AnimRefF32 {
7491                raw: core::ptr::NonNull::new_unchecked(
7492                    ffi::whiteout_m3_M3RibbonEmitter_get_alphaAmplitude(self.raw.as_ptr()),
7493                ),
7494            })
7495        }
7496    }
7497
7498    pub fn alpha_amplitude_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7499        // SAFETY: as above; `&mut self` guarantees exclusivity.
7500        unsafe {
7501            crate::support::RefMut::new(AnimRefF32 {
7502                raw: core::ptr::NonNull::new_unchecked(
7503                    ffi::whiteout_m3_M3RibbonEmitter_get_alphaAmplitude(self.raw.as_ptr()),
7504                ),
7505            })
7506        }
7507    }
7508
7509    /// Alpha variation frequency
7510    /// Borrows the field in place — no copy, no allocation.
7511    pub fn alpha_frequency(&self) -> crate::support::Ref<'_, AnimRefF32> {
7512        // SAFETY: an interior pointer into `self`, valid for this
7513        // borrow and never freed by the `Ref`.
7514        unsafe {
7515            crate::support::Ref::new(AnimRefF32 {
7516                raw: core::ptr::NonNull::new_unchecked(
7517                    ffi::whiteout_m3_M3RibbonEmitter_get_alphaFrequency(self.raw.as_ptr()),
7518                ),
7519            })
7520        }
7521    }
7522
7523    pub fn alpha_frequency_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7524        // SAFETY: as above; `&mut self` guarantees exclusivity.
7525        unsafe {
7526            crate::support::RefMut::new(AnimRefF32 {
7527                raw: core::ptr::NonNull::new_unchecked(
7528                    ffi::whiteout_m3_M3RibbonEmitter_get_alphaFrequency(self.raw.as_ptr()),
7529                ),
7530            })
7531        }
7532    }
7533
7534    /// Animated parent velocity influence
7535    /// Borrows the field in place — no copy, no allocation.
7536    pub fn particle_velocity(&self) -> crate::support::Ref<'_, AnimRefF32> {
7537        // SAFETY: an interior pointer into `self`, valid for this
7538        // borrow and never freed by the `Ref`.
7539        unsafe {
7540            crate::support::Ref::new(AnimRefF32 {
7541                raw: core::ptr::NonNull::new_unchecked(
7542                    ffi::whiteout_m3_M3RibbonEmitter_get_particleVelocity(self.raw.as_ptr()),
7543                ),
7544            })
7545        }
7546    }
7547
7548    pub fn particle_velocity_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7549        // SAFETY: as above; `&mut self` guarantees exclusivity.
7550        unsafe {
7551            crate::support::RefMut::new(AnimRefF32 {
7552                raw: core::ptr::NonNull::new_unchecked(
7553                    ffi::whiteout_m3_M3RibbonEmitter_get_particleVelocity(self.raw.as_ptr()),
7554                ),
7555            })
7556        }
7557    }
7558
7559    /// Animated overlay effect
7560    /// Borrows the field in place — no copy, no allocation.
7561    pub fn overlay(&self) -> crate::support::Ref<'_, AnimRefF32> {
7562        // SAFETY: an interior pointer into `self`, valid for this
7563        // borrow and never freed by the `Ref`.
7564        unsafe {
7565            crate::support::Ref::new(AnimRefF32 {
7566                raw: core::ptr::NonNull::new_unchecked(
7567                    ffi::whiteout_m3_M3RibbonEmitter_get_overlay(self.raw.as_ptr()),
7568                ),
7569            })
7570        }
7571    }
7572
7573    pub fn overlay_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7574        // SAFETY: as above; `&mut self` guarantees exclusivity.
7575        unsafe {
7576            crate::support::RefMut::new(AnimRefF32 {
7577                raw: core::ptr::NonNull::new_unchecked(
7578                    ffi::whiteout_m3_M3RibbonEmitter_get_overlay(self.raw.as_ptr()),
7579                ),
7580            })
7581        }
7582    }
7583}
7584
7585impl Default for RibbonEmitter {
7586    fn default() -> Self {
7587        Self::new()
7588    }
7589}
7590
7591/// PROJ — Projector / decal (v0–v5, 388 bytes)
7592///
7593/// Projects a material onto scene geometry with animated offset, orientation, field of view, aspect ratio, clipping planes, alpha lifecycle, and attenuation distance.
7594pub struct Projector {
7595    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3Projector>,
7596}
7597
7598impl Drop for Projector {
7599    fn drop(&mut self) {
7600        // SAFETY: `raw` came from a native constructor and Drop runs once.
7601        unsafe { ffi::whiteout_m3_M3Projector_delete(self.raw.as_ptr()) }
7602    }
7603}
7604
7605impl Projector {
7606    /// # Safety
7607    /// `raw` must be a live handle this value takes ownership of.
7608    #[allow(dead_code)] // used by whichever methods return this type
7609    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3Projector) -> Option<Self> {
7610        core::ptr::NonNull::new(raw).map(|raw| Projector { raw })
7611    }
7612}
7613
7614// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
7615// is deliberately NOT implemented — the C++ types make no documented
7616// guarantee about concurrent use, and claiming one we haven't verified
7617// would be unsound. See `@bind thread_safe` in the plan.
7618unsafe impl Send for Projector {}
7619
7620impl core::fmt::Debug for Projector {
7621    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
7622        f.debug_struct("Projector").finish_non_exhaustive()
7623    }
7624}
7625
7626impl Projector {
7627    /// # Panics
7628    /// Panics if the native allocation fails.
7629    pub fn new() -> Self {
7630        // SAFETY: the native constructor returns a live handle; a null here
7631        // means the library is unusable.
7632        unsafe {
7633            let raw = ffi::whiteout_m3_M3Projector_new();
7634            Self::from_raw(raw).expect("native Projector allocation failed")
7635        }
7636    }
7637
7638    /// Projection type (ortho/perspective)
7639    pub fn projection_type(&self) -> ProjectionType {
7640        // SAFETY: scalar read; the discriminant is validated below.
7641        unsafe { ffi::whiteout_m3_M3Projector_get_projectionType(self.raw.as_ptr()) }
7642            .try_into()
7643            .expect("unknown enum discriminant from the native library")
7644    }
7645
7646    pub fn set_projection_type(&mut self, value: ProjectionType) {
7647        // SAFETY: scalar write through a live handle.
7648        unsafe { ffi::whiteout_m3_M3Projector_set_projectionType(self.raw.as_ptr(), value as i32) }
7649    }
7650
7651    /// Index into BONE array
7652    pub fn bone(&self) -> u32 {
7653        // SAFETY: plain scalar read through a live handle.
7654        unsafe { ffi::whiteout_m3_M3Projector_get_bone(self.raw.as_ptr()) }
7655    }
7656
7657    pub fn set_bone(&mut self, value: u32) {
7658        // SAFETY: plain scalar write through a live handle.
7659        unsafe { ffi::whiteout_m3_M3Projector_set_bone(self.raw.as_ptr(), value) }
7660    }
7661
7662    /// Index into MATM material map
7663    pub fn material_reference_index(&self) -> u32 {
7664        // SAFETY: plain scalar read through a live handle.
7665        unsafe { ffi::whiteout_m3_M3Projector_get_materialReferenceIndex(self.raw.as_ptr()) }
7666    }
7667
7668    pub fn set_material_reference_index(&mut self, value: u32) {
7669        // SAFETY: plain scalar write through a live handle.
7670        unsafe { ffi::whiteout_m3_M3Projector_set_materialReferenceIndex(self.raw.as_ptr(), value) }
7671    }
7672
7673    /// Animated position offset
7674    /// Borrows the field in place — no copy, no allocation.
7675    pub fn offset(&self) -> crate::support::Ref<'_, AnimRefVector3f> {
7676        // SAFETY: an interior pointer into `self`, valid for this
7677        // borrow and never freed by the `Ref`.
7678        unsafe {
7679            crate::support::Ref::new(AnimRefVector3f {
7680                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Projector_get_offset(
7681                    self.raw.as_ptr(),
7682                )),
7683            })
7684        }
7685    }
7686
7687    pub fn offset_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector3f> {
7688        // SAFETY: as above; `&mut self` guarantees exclusivity.
7689        unsafe {
7690            crate::support::RefMut::new(AnimRefVector3f {
7691                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Projector_get_offset(
7692                    self.raw.as_ptr(),
7693                )),
7694            })
7695        }
7696    }
7697
7698    /// Animated pitch angle
7699    /// Borrows the field in place — no copy, no allocation.
7700    pub fn pitch(&self) -> crate::support::Ref<'_, AnimRefF32> {
7701        // SAFETY: an interior pointer into `self`, valid for this
7702        // borrow and never freed by the `Ref`.
7703        unsafe {
7704            crate::support::Ref::new(AnimRefF32 {
7705                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Projector_get_pitch(
7706                    self.raw.as_ptr(),
7707                )),
7708            })
7709        }
7710    }
7711
7712    pub fn pitch_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7713        // SAFETY: as above; `&mut self` guarantees exclusivity.
7714        unsafe {
7715            crate::support::RefMut::new(AnimRefF32 {
7716                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Projector_get_pitch(
7717                    self.raw.as_ptr(),
7718                )),
7719            })
7720        }
7721    }
7722
7723    /// Animated yaw angle
7724    /// Borrows the field in place — no copy, no allocation.
7725    pub fn yaw(&self) -> crate::support::Ref<'_, AnimRefF32> {
7726        // SAFETY: an interior pointer into `self`, valid for this
7727        // borrow and never freed by the `Ref`.
7728        unsafe {
7729            crate::support::Ref::new(AnimRefF32 {
7730                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Projector_get_yaw(
7731                    self.raw.as_ptr(),
7732                )),
7733            })
7734        }
7735    }
7736
7737    pub fn yaw_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7738        // SAFETY: as above; `&mut self` guarantees exclusivity.
7739        unsafe {
7740            crate::support::RefMut::new(AnimRefF32 {
7741                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Projector_get_yaw(
7742                    self.raw.as_ptr(),
7743                )),
7744            })
7745        }
7746    }
7747
7748    /// Animated roll angle
7749    /// Borrows the field in place — no copy, no allocation.
7750    pub fn roll(&self) -> crate::support::Ref<'_, AnimRefF32> {
7751        // SAFETY: an interior pointer into `self`, valid for this
7752        // borrow and never freed by the `Ref`.
7753        unsafe {
7754            crate::support::Ref::new(AnimRefF32 {
7755                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Projector_get_roll(
7756                    self.raw.as_ptr(),
7757                )),
7758            })
7759        }
7760    }
7761
7762    pub fn roll_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7763        // SAFETY: as above; `&mut self` guarantees exclusivity.
7764        unsafe {
7765            crate::support::RefMut::new(AnimRefF32 {
7766                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Projector_get_roll(
7767                    self.raw.as_ptr(),
7768                )),
7769            })
7770        }
7771    }
7772
7773    /// Animated field of view
7774    /// Borrows the field in place — no copy, no allocation.
7775    pub fn field_of_view(&self) -> crate::support::Ref<'_, AnimRefF32> {
7776        // SAFETY: an interior pointer into `self`, valid for this
7777        // borrow and never freed by the `Ref`.
7778        unsafe {
7779            crate::support::Ref::new(AnimRefF32 {
7780                raw: core::ptr::NonNull::new_unchecked(
7781                    ffi::whiteout_m3_M3Projector_get_fieldOfView(self.raw.as_ptr()),
7782                ),
7783            })
7784        }
7785    }
7786
7787    pub fn field_of_view_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7788        // SAFETY: as above; `&mut self` guarantees exclusivity.
7789        unsafe {
7790            crate::support::RefMut::new(AnimRefF32 {
7791                raw: core::ptr::NonNull::new_unchecked(
7792                    ffi::whiteout_m3_M3Projector_get_fieldOfView(self.raw.as_ptr()),
7793                ),
7794            })
7795        }
7796    }
7797
7798    /// Animated aspect ratio
7799    /// Borrows the field in place — no copy, no allocation.
7800    pub fn aspect_ratio(&self) -> crate::support::Ref<'_, AnimRefF32> {
7801        // SAFETY: an interior pointer into `self`, valid for this
7802        // borrow and never freed by the `Ref`.
7803        unsafe {
7804            crate::support::Ref::new(AnimRefF32 {
7805                raw: core::ptr::NonNull::new_unchecked(
7806                    ffi::whiteout_m3_M3Projector_get_aspectRatio(self.raw.as_ptr()),
7807                ),
7808            })
7809        }
7810    }
7811
7812    pub fn aspect_ratio_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7813        // SAFETY: as above; `&mut self` guarantees exclusivity.
7814        unsafe {
7815            crate::support::RefMut::new(AnimRefF32 {
7816                raw: core::ptr::NonNull::new_unchecked(
7817                    ffi::whiteout_m3_M3Projector_get_aspectRatio(self.raw.as_ptr()),
7818                ),
7819            })
7820        }
7821    }
7822
7823    /// Animated near clip plane
7824    /// Borrows the field in place — no copy, no allocation.
7825    pub fn near(&self) -> crate::support::Ref<'_, AnimRefF32> {
7826        // SAFETY: an interior pointer into `self`, valid for this
7827        // borrow and never freed by the `Ref`.
7828        unsafe {
7829            crate::support::Ref::new(AnimRefF32 {
7830                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Projector_get_near(
7831                    self.raw.as_ptr(),
7832                )),
7833            })
7834        }
7835    }
7836
7837    pub fn near_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7838        // SAFETY: as above; `&mut self` guarantees exclusivity.
7839        unsafe {
7840            crate::support::RefMut::new(AnimRefF32 {
7841                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Projector_get_near(
7842                    self.raw.as_ptr(),
7843                )),
7844            })
7845        }
7846    }
7847
7848    /// Animated far clip plane
7849    /// Borrows the field in place — no copy, no allocation.
7850    pub fn far(&self) -> crate::support::Ref<'_, AnimRefF32> {
7851        // SAFETY: an interior pointer into `self`, valid for this
7852        // borrow and never freed by the `Ref`.
7853        unsafe {
7854            crate::support::Ref::new(AnimRefF32 {
7855                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Projector_get_far(
7856                    self.raw.as_ptr(),
7857                )),
7858            })
7859        }
7860    }
7861
7862    pub fn far_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7863        // SAFETY: as above; `&mut self` guarantees exclusivity.
7864        unsafe {
7865            crate::support::RefMut::new(AnimRefF32 {
7866                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Projector_get_far(
7867                    self.raw.as_ptr(),
7868                )),
7869            })
7870        }
7871    }
7872
7873    /// Animated box Z bottom offset
7874    /// Borrows the field in place — no copy, no allocation.
7875    pub fn box_offset_z_bottom(&self) -> crate::support::Ref<'_, AnimRefF32> {
7876        // SAFETY: an interior pointer into `self`, valid for this
7877        // borrow and never freed by the `Ref`.
7878        unsafe {
7879            crate::support::Ref::new(AnimRefF32 {
7880                raw: core::ptr::NonNull::new_unchecked(
7881                    ffi::whiteout_m3_M3Projector_get_boxOffsetZBottom(self.raw.as_ptr()),
7882                ),
7883            })
7884        }
7885    }
7886
7887    pub fn box_offset_z_bottom_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7888        // SAFETY: as above; `&mut self` guarantees exclusivity.
7889        unsafe {
7890            crate::support::RefMut::new(AnimRefF32 {
7891                raw: core::ptr::NonNull::new_unchecked(
7892                    ffi::whiteout_m3_M3Projector_get_boxOffsetZBottom(self.raw.as_ptr()),
7893                ),
7894            })
7895        }
7896    }
7897
7898    /// Animated box Z top offset
7899    /// Borrows the field in place — no copy, no allocation.
7900    pub fn box_offset_z_top(&self) -> crate::support::Ref<'_, AnimRefF32> {
7901        // SAFETY: an interior pointer into `self`, valid for this
7902        // borrow and never freed by the `Ref`.
7903        unsafe {
7904            crate::support::Ref::new(AnimRefF32 {
7905                raw: core::ptr::NonNull::new_unchecked(
7906                    ffi::whiteout_m3_M3Projector_get_boxOffsetZTop(self.raw.as_ptr()),
7907                ),
7908            })
7909        }
7910    }
7911
7912    pub fn box_offset_z_top_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7913        // SAFETY: as above; `&mut self` guarantees exclusivity.
7914        unsafe {
7915            crate::support::RefMut::new(AnimRefF32 {
7916                raw: core::ptr::NonNull::new_unchecked(
7917                    ffi::whiteout_m3_M3Projector_get_boxOffsetZTop(self.raw.as_ptr()),
7918                ),
7919            })
7920        }
7921    }
7922
7923    /// Animated box X left offset
7924    /// Borrows the field in place — no copy, no allocation.
7925    pub fn box_offset_x_left(&self) -> crate::support::Ref<'_, AnimRefF32> {
7926        // SAFETY: an interior pointer into `self`, valid for this
7927        // borrow and never freed by the `Ref`.
7928        unsafe {
7929            crate::support::Ref::new(AnimRefF32 {
7930                raw: core::ptr::NonNull::new_unchecked(
7931                    ffi::whiteout_m3_M3Projector_get_boxOffsetXLeft(self.raw.as_ptr()),
7932                ),
7933            })
7934        }
7935    }
7936
7937    pub fn box_offset_x_left_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7938        // SAFETY: as above; `&mut self` guarantees exclusivity.
7939        unsafe {
7940            crate::support::RefMut::new(AnimRefF32 {
7941                raw: core::ptr::NonNull::new_unchecked(
7942                    ffi::whiteout_m3_M3Projector_get_boxOffsetXLeft(self.raw.as_ptr()),
7943                ),
7944            })
7945        }
7946    }
7947
7948    /// Animated box X right offset
7949    /// Borrows the field in place — no copy, no allocation.
7950    pub fn box_offset_x_right(&self) -> crate::support::Ref<'_, AnimRefF32> {
7951        // SAFETY: an interior pointer into `self`, valid for this
7952        // borrow and never freed by the `Ref`.
7953        unsafe {
7954            crate::support::Ref::new(AnimRefF32 {
7955                raw: core::ptr::NonNull::new_unchecked(
7956                    ffi::whiteout_m3_M3Projector_get_boxOffsetXRight(self.raw.as_ptr()),
7957                ),
7958            })
7959        }
7960    }
7961
7962    pub fn box_offset_x_right_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7963        // SAFETY: as above; `&mut self` guarantees exclusivity.
7964        unsafe {
7965            crate::support::RefMut::new(AnimRefF32 {
7966                raw: core::ptr::NonNull::new_unchecked(
7967                    ffi::whiteout_m3_M3Projector_get_boxOffsetXRight(self.raw.as_ptr()),
7968                ),
7969            })
7970        }
7971    }
7972
7973    /// Animated box Y front offset
7974    /// Borrows the field in place — no copy, no allocation.
7975    pub fn box_offset_y_front(&self) -> crate::support::Ref<'_, AnimRefF32> {
7976        // SAFETY: an interior pointer into `self`, valid for this
7977        // borrow and never freed by the `Ref`.
7978        unsafe {
7979            crate::support::Ref::new(AnimRefF32 {
7980                raw: core::ptr::NonNull::new_unchecked(
7981                    ffi::whiteout_m3_M3Projector_get_boxOffsetYFront(self.raw.as_ptr()),
7982                ),
7983            })
7984        }
7985    }
7986
7987    pub fn box_offset_y_front_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
7988        // SAFETY: as above; `&mut self` guarantees exclusivity.
7989        unsafe {
7990            crate::support::RefMut::new(AnimRefF32 {
7991                raw: core::ptr::NonNull::new_unchecked(
7992                    ffi::whiteout_m3_M3Projector_get_boxOffsetYFront(self.raw.as_ptr()),
7993                ),
7994            })
7995        }
7996    }
7997
7998    /// Animated box Y back offset
7999    /// Borrows the field in place — no copy, no allocation.
8000    pub fn box_offset_y_back(&self) -> crate::support::Ref<'_, AnimRefF32> {
8001        // SAFETY: an interior pointer into `self`, valid for this
8002        // borrow and never freed by the `Ref`.
8003        unsafe {
8004            crate::support::Ref::new(AnimRefF32 {
8005                raw: core::ptr::NonNull::new_unchecked(
8006                    ffi::whiteout_m3_M3Projector_get_boxOffsetYBack(self.raw.as_ptr()),
8007                ),
8008            })
8009        }
8010    }
8011
8012    pub fn box_offset_y_back_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
8013        // SAFETY: as above; `&mut self` guarantees exclusivity.
8014        unsafe {
8015            crate::support::RefMut::new(AnimRefF32 {
8016                raw: core::ptr::NonNull::new_unchecked(
8017                    ffi::whiteout_m3_M3Projector_get_boxOffsetYBack(self.raw.as_ptr()),
8018                ),
8019            })
8020        }
8021    }
8022
8023    /// Projection falloff distance
8024    pub fn falloff(&self) -> f32 {
8025        // SAFETY: plain scalar read through a live handle.
8026        unsafe { ffi::whiteout_m3_M3Projector_get_falloff(self.raw.as_ptr()) }
8027    }
8028
8029    pub fn set_falloff(&mut self, value: f32) {
8030        // SAFETY: plain scalar write through a live handle.
8031        unsafe { ffi::whiteout_m3_M3Projector_set_falloff(self.raw.as_ptr(), value) }
8032    }
8033
8034    /// Alpha at creation
8035    pub fn alpha_init(&self) -> f32 {
8036        // SAFETY: plain scalar read through a live handle.
8037        unsafe { ffi::whiteout_m3_M3Projector_get_alphaInit(self.raw.as_ptr()) }
8038    }
8039
8040    pub fn set_alpha_init(&mut self, value: f32) {
8041        // SAFETY: plain scalar write through a live handle.
8042        unsafe { ffi::whiteout_m3_M3Projector_set_alphaInit(self.raw.as_ptr(), value) }
8043    }
8044
8045    /// Alpha at midpoint
8046    pub fn alpha_mid(&self) -> f32 {
8047        // SAFETY: plain scalar read through a live handle.
8048        unsafe { ffi::whiteout_m3_M3Projector_get_alphaMid(self.raw.as_ptr()) }
8049    }
8050
8051    pub fn set_alpha_mid(&mut self, value: f32) {
8052        // SAFETY: plain scalar write through a live handle.
8053        unsafe { ffi::whiteout_m3_M3Projector_set_alphaMid(self.raw.as_ptr(), value) }
8054    }
8055
8056    /// Alpha at end
8057    pub fn alpha_end(&self) -> f32 {
8058        // SAFETY: plain scalar read through a live handle.
8059        unsafe { ffi::whiteout_m3_M3Projector_get_alphaEnd(self.raw.as_ptr()) }
8060    }
8061
8062    pub fn set_alpha_end(&mut self, value: f32) {
8063        // SAFETY: plain scalar write through a live handle.
8064        unsafe { ffi::whiteout_m3_M3Projector_set_alphaEnd(self.raw.as_ptr(), value) }
8065    }
8066
8067    /// Attack phase duration
8068    pub fn lifetime_attack(&self) -> f32 {
8069        // SAFETY: plain scalar read through a live handle.
8070        unsafe { ffi::whiteout_m3_M3Projector_get_lifetimeAttack(self.raw.as_ptr()) }
8071    }
8072
8073    pub fn set_lifetime_attack(&mut self, value: f32) {
8074        // SAFETY: plain scalar write through a live handle.
8075        unsafe { ffi::whiteout_m3_M3Projector_set_lifetimeAttack(self.raw.as_ptr(), value) }
8076    }
8077
8078    /// Attack target time
8079    pub fn lifetime_attack_to(&self) -> f32 {
8080        // SAFETY: plain scalar read through a live handle.
8081        unsafe { ffi::whiteout_m3_M3Projector_get_lifetimeAttackTo(self.raw.as_ptr()) }
8082    }
8083
8084    pub fn set_lifetime_attack_to(&mut self, value: f32) {
8085        // SAFETY: plain scalar write through a live handle.
8086        unsafe { ffi::whiteout_m3_M3Projector_set_lifetimeAttackTo(self.raw.as_ptr(), value) }
8087    }
8088
8089    /// Hold phase duration
8090    pub fn lifetime_hold(&self) -> f32 {
8091        // SAFETY: plain scalar read through a live handle.
8092        unsafe { ffi::whiteout_m3_M3Projector_get_lifetimeHold(self.raw.as_ptr()) }
8093    }
8094
8095    pub fn set_lifetime_hold(&mut self, value: f32) {
8096        // SAFETY: plain scalar write through a live handle.
8097        unsafe { ffi::whiteout_m3_M3Projector_set_lifetimeHold(self.raw.as_ptr(), value) }
8098    }
8099
8100    /// Hold target time
8101    pub fn lifetime_hold_to(&self) -> f32 {
8102        // SAFETY: plain scalar read through a live handle.
8103        unsafe { ffi::whiteout_m3_M3Projector_get_lifetimeHoldTo(self.raw.as_ptr()) }
8104    }
8105
8106    pub fn set_lifetime_hold_to(&mut self, value: f32) {
8107        // SAFETY: plain scalar write through a live handle.
8108        unsafe { ffi::whiteout_m3_M3Projector_set_lifetimeHoldTo(self.raw.as_ptr(), value) }
8109    }
8110
8111    /// Decay phase duration
8112    pub fn lifetime_decay(&self) -> f32 {
8113        // SAFETY: plain scalar read through a live handle.
8114        unsafe { ffi::whiteout_m3_M3Projector_get_lifetimeDecay(self.raw.as_ptr()) }
8115    }
8116
8117    pub fn set_lifetime_decay(&mut self, value: f32) {
8118        // SAFETY: plain scalar write through a live handle.
8119        unsafe { ffi::whiteout_m3_M3Projector_set_lifetimeDecay(self.raw.as_ptr(), value) }
8120    }
8121
8122    /// Decay target time
8123    pub fn lifetime_decay_to(&self) -> f32 {
8124        // SAFETY: plain scalar read through a live handle.
8125        unsafe { ffi::whiteout_m3_M3Projector_get_lifetimeDecayTo(self.raw.as_ptr()) }
8126    }
8127
8128    pub fn set_lifetime_decay_to(&mut self, value: f32) {
8129        // SAFETY: plain scalar write through a live handle.
8130        unsafe { ffi::whiteout_m3_M3Projector_set_lifetimeDecayTo(self.raw.as_ptr(), value) }
8131    }
8132
8133    /// Distance-based attenuation
8134    pub fn attenuation_distance(&self) -> f32 {
8135        // SAFETY: plain scalar read through a live handle.
8136        unsafe { ffi::whiteout_m3_M3Projector_get_attenuationDistance(self.raw.as_ptr()) }
8137    }
8138
8139    pub fn set_attenuation_distance(&mut self, value: f32) {
8140        // SAFETY: plain scalar write through a live handle.
8141        unsafe { ffi::whiteout_m3_M3Projector_set_attenuationDistance(self.raw.as_ptr(), value) }
8142    }
8143
8144    /// Animated active state
8145    /// Borrows the field in place — no copy, no allocation.
8146    pub fn active(&self) -> crate::support::Ref<'_, AnimRefU32> {
8147        // SAFETY: an interior pointer into `self`, valid for this
8148        // borrow and never freed by the `Ref`.
8149        unsafe {
8150            crate::support::Ref::new(AnimRefU32 {
8151                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Projector_get_active(
8152                    self.raw.as_ptr(),
8153                )),
8154            })
8155        }
8156    }
8157
8158    pub fn active_mut(&mut self) -> crate::support::RefMut<'_, AnimRefU32> {
8159        // SAFETY: as above; `&mut self` guarantees exclusivity.
8160        unsafe {
8161            crate::support::RefMut::new(AnimRefU32 {
8162                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Projector_get_active(
8163                    self.raw.as_ptr(),
8164                )),
8165            })
8166        }
8167    }
8168
8169    /// Render layer
8170    pub fn layer(&self) -> u32 {
8171        // SAFETY: plain scalar read through a live handle.
8172        unsafe { ffi::whiteout_m3_M3Projector_get_layer(self.raw.as_ptr()) }
8173    }
8174
8175    pub fn set_layer(&mut self, value: u32) {
8176        // SAFETY: plain scalar write through a live handle.
8177        unsafe { ffi::whiteout_m3_M3Projector_set_layer(self.raw.as_ptr(), value) }
8178    }
8179
8180    /// LOD reduction level
8181    pub fn lod_reduce(&self) -> u32 {
8182        // SAFETY: plain scalar read through a live handle.
8183        unsafe { ffi::whiteout_m3_M3Projector_get_lodReduce(self.raw.as_ptr()) }
8184    }
8185
8186    pub fn set_lod_reduce(&mut self, value: u32) {
8187        // SAFETY: plain scalar write through a live handle.
8188        unsafe { ffi::whiteout_m3_M3Projector_set_lodReduce(self.raw.as_ptr(), value) }
8189    }
8190
8191    /// LOD cut-off level
8192    pub fn lod_cut(&self) -> u32 {
8193        // SAFETY: plain scalar read through a live handle.
8194        unsafe { ffi::whiteout_m3_M3Projector_get_lodCut(self.raw.as_ptr()) }
8195    }
8196
8197    pub fn set_lod_cut(&mut self, value: u32) {
8198        // SAFETY: plain scalar write through a live handle.
8199        unsafe { ffi::whiteout_m3_M3Projector_set_lodCut(self.raw.as_ptr(), value) }
8200    }
8201
8202    /// Projector flags
8203    pub fn flags(&self) -> ProjectorFlag {
8204        // SAFETY: scalar read; a flag set accepts any bits.
8205        ProjectorFlag(unsafe { ffi::whiteout_m3_M3Projector_get_flags(self.raw.as_ptr()) })
8206    }
8207
8208    pub fn set_flags(&mut self, value: ProjectorFlag) {
8209        // SAFETY: scalar write through a live handle.
8210        unsafe { ffi::whiteout_m3_M3Projector_set_flags(self.raw.as_ptr(), value.0) }
8211    }
8212}
8213
8214impl Default for Projector {
8215    fn default() -> Self {
8216        Self::new()
8217    }
8218}
8219
8220/// MATM — Material map entry (v0, 8 bytes)
8221///
8222/// 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.
8223pub struct MaterialMap {
8224    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3MaterialMap>,
8225}
8226
8227impl Drop for MaterialMap {
8228    fn drop(&mut self) {
8229        // SAFETY: `raw` came from a native constructor and Drop runs once.
8230        unsafe { ffi::whiteout_m3_M3MaterialMap_delete(self.raw.as_ptr()) }
8231    }
8232}
8233
8234impl MaterialMap {
8235    /// # Safety
8236    /// `raw` must be a live handle this value takes ownership of.
8237    #[allow(dead_code)] // used by whichever methods return this type
8238    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3MaterialMap) -> Option<Self> {
8239        core::ptr::NonNull::new(raw).map(|raw| MaterialMap { raw })
8240    }
8241}
8242
8243// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
8244// is deliberately NOT implemented — the C++ types make no documented
8245// guarantee about concurrent use, and claiming one we haven't verified
8246// would be unsound. See `@bind thread_safe` in the plan.
8247unsafe impl Send for MaterialMap {}
8248
8249impl core::fmt::Debug for MaterialMap {
8250    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
8251        f.debug_struct("MaterialMap").finish_non_exhaustive()
8252    }
8253}
8254
8255impl MaterialMap {
8256    /// # Panics
8257    /// Panics if the native allocation fails.
8258    pub fn new() -> Self {
8259        // SAFETY: the native constructor returns a live handle; a null here
8260        // means the library is unusable.
8261        unsafe {
8262            let raw = ffi::whiteout_m3_M3MaterialMap_new();
8263            Self::from_raw(raw).expect("native MaterialMap allocation failed")
8264        }
8265    }
8266
8267    /// Material type (1=standard, 2=displacement, etc.)
8268    pub fn material_type(&self) -> MaterialType {
8269        // SAFETY: scalar read; the discriminant is validated below.
8270        unsafe { ffi::whiteout_m3_M3MaterialMap_get_materialType(self.raw.as_ptr()) }
8271            .try_into()
8272            .expect("unknown enum discriminant from the native library")
8273    }
8274
8275    pub fn set_material_type(&mut self, value: MaterialType) {
8276        // SAFETY: scalar write through a live handle.
8277        unsafe { ffi::whiteout_m3_M3MaterialMap_set_materialType(self.raw.as_ptr(), value as i32) }
8278    }
8279
8280    /// Index into the typed material array
8281    pub fn material_index(&self) -> u32 {
8282        // SAFETY: plain scalar read through a live handle.
8283        unsafe { ffi::whiteout_m3_M3MaterialMap_get_materialIndex(self.raw.as_ptr()) }
8284    }
8285
8286    pub fn set_material_index(&mut self, value: u32) {
8287        // SAFETY: plain scalar write through a live handle.
8288        unsafe { ffi::whiteout_m3_M3MaterialMap_set_materialIndex(self.raw.as_ptr(), value) }
8289    }
8290}
8291
8292impl Default for MaterialMap {
8293    fn default() -> Self {
8294        Self::new()
8295    }
8296}
8297
8298/// LAYR — Texture layer (v0–v26, 352–464 bytes)
8299///
8300/// 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.
8301pub struct TextureLayer {
8302    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3TextureLayer>,
8303}
8304
8305impl Drop for TextureLayer {
8306    fn drop(&mut self) {
8307        // SAFETY: `raw` came from a native constructor and Drop runs once.
8308        unsafe { ffi::whiteout_m3_M3TextureLayer_delete(self.raw.as_ptr()) }
8309    }
8310}
8311
8312impl TextureLayer {
8313    /// # Safety
8314    /// `raw` must be a live handle this value takes ownership of.
8315    #[allow(dead_code)] // used by whichever methods return this type
8316    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3TextureLayer) -> Option<Self> {
8317        core::ptr::NonNull::new(raw).map(|raw| TextureLayer { raw })
8318    }
8319}
8320
8321// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
8322// is deliberately NOT implemented — the C++ types make no documented
8323// guarantee about concurrent use, and claiming one we haven't verified
8324// would be unsound. See `@bind thread_safe` in the plan.
8325unsafe impl Send for TextureLayer {}
8326
8327impl core::fmt::Debug for TextureLayer {
8328    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
8329        f.debug_struct("TextureLayer").finish_non_exhaustive()
8330    }
8331}
8332
8333impl TextureLayer {
8334    /// # Panics
8335    /// Panics if the native allocation fails.
8336    pub fn new() -> Self {
8337        // SAFETY: the native constructor returns a live handle; a null here
8338        // means the library is unusable.
8339        unsafe {
8340            let raw = ffi::whiteout_m3_M3TextureLayer_new();
8341            Self::from_raw(raw).expect("native TextureLayer allocation failed")
8342        }
8343    }
8344
8345    /// Layer identifier
8346    pub fn id(&self) -> u32 {
8347        // SAFETY: plain scalar read through a live handle.
8348        unsafe { ffi::whiteout_m3_M3TextureLayer_get_id(self.raw.as_ptr()) }
8349    }
8350
8351    pub fn set_id(&mut self, value: u32) {
8352        // SAFETY: plain scalar write through a live handle.
8353        unsafe { ffi::whiteout_m3_M3TextureLayer_set_id(self.raw.as_ptr(), value) }
8354    }
8355
8356    /// Texture file path (`Ref<CHAR>`)
8357    pub fn texture_path(&self) -> String {
8358        // SAFETY: the native side hands over an owned CString.
8359        unsafe {
8360            crate::support::take_string(ffi::whiteout_m3_M3TextureLayer_get_texturePath(
8361                self.raw.as_ptr(),
8362            ))
8363        }
8364    }
8365
8366    pub fn set_texture_path(&mut self, value: &str) {
8367        let value = std::ffi::CString::new(value).unwrap_or_default();
8368        // SAFETY: the pointer outlives the call.
8369        unsafe {
8370            ffi::whiteout_m3_M3TextureLayer_set_texturePath(self.raw.as_ptr(), value.as_ptr())
8371        }
8372    }
8373
8374    /// Animated color tint
8375    /// Borrows the field in place — no copy, no allocation.
8376    pub fn color(&self) -> crate::support::Ref<'_, AnimRefM3ColorBGRA> {
8377        // SAFETY: an interior pointer into `self`, valid for this
8378        // borrow and never freed by the `Ref`.
8379        unsafe {
8380            crate::support::Ref::new(AnimRefM3ColorBGRA {
8381                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3TextureLayer_get_color(
8382                    self.raw.as_ptr(),
8383                )),
8384            })
8385        }
8386    }
8387
8388    pub fn color_mut(&mut self) -> crate::support::RefMut<'_, AnimRefM3ColorBGRA> {
8389        // SAFETY: as above; `&mut self` guarantees exclusivity.
8390        unsafe {
8391            crate::support::RefMut::new(AnimRefM3ColorBGRA {
8392                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3TextureLayer_get_color(
8393                    self.raw.as_ptr(),
8394                )),
8395            })
8396        }
8397    }
8398
8399    /// Layer flags (wrap, flipbook, video, etc.)
8400    pub fn flags(&self) -> TextureLayerFlag {
8401        // SAFETY: scalar read; a flag set accepts any bits.
8402        TextureLayerFlag(unsafe { ffi::whiteout_m3_M3TextureLayer_get_flags(self.raw.as_ptr()) })
8403    }
8404
8405    pub fn set_flags(&mut self, value: TextureLayerFlag) {
8406        // SAFETY: scalar write through a live handle.
8407        unsafe { ffi::whiteout_m3_M3TextureLayer_set_flags(self.raw.as_ptr(), value.0) }
8408    }
8409
8410    /// UV mapping source
8411    pub fn uv_mapping(&self) -> UVMappingMode {
8412        // SAFETY: scalar read; the discriminant is validated below.
8413        unsafe { ffi::whiteout_m3_M3TextureLayer_get_uvMapping(self.raw.as_ptr()) }
8414            .try_into()
8415            .expect("unknown enum discriminant from the native library")
8416    }
8417
8418    pub fn set_uv_mapping(&mut self, value: UVMappingMode) {
8419        // SAFETY: scalar write through a live handle.
8420        unsafe { ffi::whiteout_m3_M3TextureLayer_set_uvMapping(self.raw.as_ptr(), value as i32) }
8421    }
8422
8423    /// Channel selection
8424    pub fn color_type(&self) -> ColorChannelSelect {
8425        // SAFETY: scalar read; the discriminant is validated below.
8426        unsafe { ffi::whiteout_m3_M3TextureLayer_get_colorType(self.raw.as_ptr()) }
8427            .try_into()
8428            .expect("unknown enum discriminant from the native library")
8429    }
8430
8431    pub fn set_color_type(&mut self, value: ColorChannelSelect) {
8432        // SAFETY: scalar write through a live handle.
8433        unsafe { ffi::whiteout_m3_M3TextureLayer_set_colorType(self.raw.as_ptr(), value as i32) }
8434    }
8435
8436    /// RGB multiply factor
8437    /// Borrows the field in place — no copy, no allocation.
8438    pub fn rgb_multiply(&self) -> crate::support::Ref<'_, AnimRefF32> {
8439        // SAFETY: an interior pointer into `self`, valid for this
8440        // borrow and never freed by the `Ref`.
8441        unsafe {
8442            crate::support::Ref::new(AnimRefF32 {
8443                raw: core::ptr::NonNull::new_unchecked(
8444                    ffi::whiteout_m3_M3TextureLayer_get_rgbMultiply(self.raw.as_ptr()),
8445                ),
8446            })
8447        }
8448    }
8449
8450    pub fn rgb_multiply_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
8451        // SAFETY: as above; `&mut self` guarantees exclusivity.
8452        unsafe {
8453            crate::support::RefMut::new(AnimRefF32 {
8454                raw: core::ptr::NonNull::new_unchecked(
8455                    ffi::whiteout_m3_M3TextureLayer_get_rgbMultiply(self.raw.as_ptr()),
8456                ),
8457            })
8458        }
8459    }
8460
8461    /// RGB additive factor
8462    /// Borrows the field in place — no copy, no allocation.
8463    pub fn rgb_add(&self) -> crate::support::Ref<'_, AnimRefF32> {
8464        // SAFETY: an interior pointer into `self`, valid for this
8465        // borrow and never freed by the `Ref`.
8466        unsafe {
8467            crate::support::Ref::new(AnimRefF32 {
8468                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3TextureLayer_get_rgbAdd(
8469                    self.raw.as_ptr(),
8470                )),
8471            })
8472        }
8473    }
8474
8475    pub fn rgb_add_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
8476        // SAFETY: as above; `&mut self` guarantees exclusivity.
8477        unsafe {
8478            crate::support::RefMut::new(AnimRefF32 {
8479                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3TextureLayer_get_rgbAdd(
8480                    self.raw.as_ptr(),
8481                )),
8482            })
8483        }
8484    }
8485
8486    /// POC texture reference
8487    pub fn poc_texture(&self) -> u32 {
8488        // SAFETY: plain scalar read through a live handle.
8489        unsafe { ffi::whiteout_m3_M3TextureLayer_get_pocTexture(self.raw.as_ptr()) }
8490    }
8491
8492    pub fn set_poc_texture(&mut self, value: u32) {
8493        // SAFETY: plain scalar write through a live handle.
8494        unsafe { ffi::whiteout_m3_M3TextureLayer_set_pocTexture(self.raw.as_ptr(), value) }
8495    }
8496
8497    /// Noise amplitude (v24+)
8498    pub fn noise_amplitude(&self) -> f32 {
8499        // SAFETY: plain scalar read through a live handle.
8500        unsafe { ffi::whiteout_m3_M3TextureLayer_get_noiseAmplitude(self.raw.as_ptr()) }
8501    }
8502
8503    pub fn set_noise_amplitude(&mut self, value: f32) {
8504        // SAFETY: plain scalar write through a live handle.
8505        unsafe { ffi::whiteout_m3_M3TextureLayer_set_noiseAmplitude(self.raw.as_ptr(), value) }
8506    }
8507
8508    /// Noise frequency (v24+)
8509    pub fn noise_frequency(&self) -> f32 {
8510        // SAFETY: plain scalar read through a live handle.
8511        unsafe { ffi::whiteout_m3_M3TextureLayer_get_noiseFrequency(self.raw.as_ptr()) }
8512    }
8513
8514    pub fn set_noise_frequency(&mut self, value: f32) {
8515        // SAFETY: plain scalar write through a live handle.
8516        unsafe { ffi::whiteout_m3_M3TextureLayer_set_noiseFrequency(self.raw.as_ptr(), value) }
8517    }
8518
8519    /// Texture source override
8520    pub fn texture_source(&self) -> u32 {
8521        // SAFETY: plain scalar read through a live handle.
8522        unsafe { ffi::whiteout_m3_M3TextureLayer_get_textureSource(self.raw.as_ptr()) }
8523    }
8524
8525    pub fn set_texture_source(&mut self, value: u32) {
8526        // SAFETY: plain scalar write through a live handle.
8527        unsafe { ffi::whiteout_m3_M3TextureLayer_set_textureSource(self.raw.as_ptr(), value) }
8528    }
8529
8530    /// AVI playback frame rate
8531    pub fn avi_frame_rate(&self) -> u32 {
8532        // SAFETY: plain scalar read through a live handle.
8533        unsafe { ffi::whiteout_m3_M3TextureLayer_get_aviFrameRate(self.raw.as_ptr()) }
8534    }
8535
8536    pub fn set_avi_frame_rate(&mut self, value: u32) {
8537        // SAFETY: plain scalar write through a live handle.
8538        unsafe { ffi::whiteout_m3_M3TextureLayer_set_aviFrameRate(self.raw.as_ptr(), value) }
8539    }
8540
8541    /// AVI start frame
8542    pub fn avi_start(&self) -> u32 {
8543        // SAFETY: plain scalar read through a live handle.
8544        unsafe { ffi::whiteout_m3_M3TextureLayer_get_aviStart(self.raw.as_ptr()) }
8545    }
8546
8547    pub fn set_avi_start(&mut self, value: u32) {
8548        // SAFETY: plain scalar write through a live handle.
8549        unsafe { ffi::whiteout_m3_M3TextureLayer_set_aviStart(self.raw.as_ptr(), value) }
8550    }
8551
8552    /// AVI stop frame
8553    pub fn avi_stop(&self) -> u32 {
8554        // SAFETY: plain scalar read through a live handle.
8555        unsafe { ffi::whiteout_m3_M3TextureLayer_get_aviStop(self.raw.as_ptr()) }
8556    }
8557
8558    pub fn set_avi_stop(&mut self, value: u32) {
8559        // SAFETY: plain scalar write through a live handle.
8560        unsafe { ffi::whiteout_m3_M3TextureLayer_set_aviStop(self.raw.as_ptr(), value) }
8561    }
8562
8563    /// AVI loop mode
8564    pub fn avi_loop(&self) -> u32 {
8565        // SAFETY: plain scalar read through a live handle.
8566        unsafe { ffi::whiteout_m3_M3TextureLayer_get_aviLoop(self.raw.as_ptr()) }
8567    }
8568
8569    pub fn set_avi_loop(&mut self, value: u32) {
8570        // SAFETY: plain scalar write through a live handle.
8571        unsafe { ffi::whiteout_m3_M3TextureLayer_set_aviLoop(self.raw.as_ptr(), value) }
8572    }
8573
8574    /// AVI sync mode
8575    pub fn avi_sync(&self) -> u32 {
8576        // SAFETY: plain scalar read through a live handle.
8577        unsafe { ffi::whiteout_m3_M3TextureLayer_get_aviSync(self.raw.as_ptr()) }
8578    }
8579
8580    pub fn set_avi_sync(&mut self, value: u32) {
8581        // SAFETY: plain scalar write through a live handle.
8582        unsafe { ffi::whiteout_m3_M3TextureLayer_set_aviSync(self.raw.as_ptr(), value) }
8583    }
8584
8585    /// AVI play control
8586    /// Borrows the field in place — no copy, no allocation.
8587    pub fn avi_play(&self) -> crate::support::Ref<'_, AnimRefU32> {
8588        // SAFETY: an interior pointer into `self`, valid for this
8589        // borrow and never freed by the `Ref`.
8590        unsafe {
8591            crate::support::Ref::new(AnimRefU32 {
8592                raw: core::ptr::NonNull::new_unchecked(
8593                    ffi::whiteout_m3_M3TextureLayer_get_aviPlay(self.raw.as_ptr()),
8594                ),
8595            })
8596        }
8597    }
8598
8599    pub fn avi_play_mut(&mut self) -> crate::support::RefMut<'_, AnimRefU32> {
8600        // SAFETY: as above; `&mut self` guarantees exclusivity.
8601        unsafe {
8602            crate::support::RefMut::new(AnimRefU32 {
8603                raw: core::ptr::NonNull::new_unchecked(
8604                    ffi::whiteout_m3_M3TextureLayer_get_aviPlay(self.raw.as_ptr()),
8605                ),
8606            })
8607        }
8608    }
8609
8610    /// AVI restart control
8611    /// Borrows the field in place — no copy, no allocation.
8612    pub fn avi_restart(&self) -> crate::support::Ref<'_, AnimRefU32> {
8613        // SAFETY: an interior pointer into `self`, valid for this
8614        // borrow and never freed by the `Ref`.
8615        unsafe {
8616            crate::support::Ref::new(AnimRefU32 {
8617                raw: core::ptr::NonNull::new_unchecked(
8618                    ffi::whiteout_m3_M3TextureLayer_get_aviRestart(self.raw.as_ptr()),
8619                ),
8620            })
8621        }
8622    }
8623
8624    pub fn avi_restart_mut(&mut self) -> crate::support::RefMut<'_, AnimRefU32> {
8625        // SAFETY: as above; `&mut self` guarantees exclusivity.
8626        unsafe {
8627            crate::support::RefMut::new(AnimRefU32 {
8628                raw: core::ptr::NonNull::new_unchecked(
8629                    ffi::whiteout_m3_M3TextureLayer_get_aviRestart(self.raw.as_ptr()),
8630                ),
8631            })
8632        }
8633    }
8634
8635    /// Flipbook grid rows
8636    pub fn flipbook_rows(&self) -> u32 {
8637        // SAFETY: plain scalar read through a live handle.
8638        unsafe { ffi::whiteout_m3_M3TextureLayer_get_flipbookRows(self.raw.as_ptr()) }
8639    }
8640
8641    pub fn set_flipbook_rows(&mut self, value: u32) {
8642        // SAFETY: plain scalar write through a live handle.
8643        unsafe { ffi::whiteout_m3_M3TextureLayer_set_flipbookRows(self.raw.as_ptr(), value) }
8644    }
8645
8646    /// Flipbook grid columns
8647    pub fn flipbook_columns(&self) -> u32 {
8648        // SAFETY: plain scalar read through a live handle.
8649        unsafe { ffi::whiteout_m3_M3TextureLayer_get_flipbookColumns(self.raw.as_ptr()) }
8650    }
8651
8652    pub fn set_flipbook_columns(&mut self, value: u32) {
8653        // SAFETY: plain scalar write through a live handle.
8654        unsafe { ffi::whiteout_m3_M3TextureLayer_set_flipbookColumns(self.raw.as_ptr(), value) }
8655    }
8656
8657    /// Animated flipbook frame index
8658    /// Borrows the field in place — no copy, no allocation.
8659    pub fn current_frame(&self) -> crate::support::Ref<'_, AnimRefU16> {
8660        // SAFETY: an interior pointer into `self`, valid for this
8661        // borrow and never freed by the `Ref`.
8662        unsafe {
8663            crate::support::Ref::new(AnimRefU16 {
8664                raw: core::ptr::NonNull::new_unchecked(
8665                    ffi::whiteout_m3_M3TextureLayer_get_currentFrame(self.raw.as_ptr()),
8666                ),
8667            })
8668        }
8669    }
8670
8671    pub fn current_frame_mut(&mut self) -> crate::support::RefMut<'_, AnimRefU16> {
8672        // SAFETY: as above; `&mut self` guarantees exclusivity.
8673        unsafe {
8674            crate::support::RefMut::new(AnimRefU16 {
8675                raw: core::ptr::NonNull::new_unchecked(
8676                    ffi::whiteout_m3_M3TextureLayer_get_currentFrame(self.raw.as_ptr()),
8677                ),
8678            })
8679        }
8680    }
8681
8682    /// Animated UV offset
8683    /// Borrows the field in place — no copy, no allocation.
8684    pub fn uv_offset(&self) -> crate::support::Ref<'_, AnimRefVector2f> {
8685        // SAFETY: an interior pointer into `self`, valid for this
8686        // borrow and never freed by the `Ref`.
8687        unsafe {
8688            crate::support::Ref::new(AnimRefVector2f {
8689                raw: core::ptr::NonNull::new_unchecked(
8690                    ffi::whiteout_m3_M3TextureLayer_get_uvOffset(self.raw.as_ptr()),
8691                ),
8692            })
8693        }
8694    }
8695
8696    pub fn uv_offset_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector2f> {
8697        // SAFETY: as above; `&mut self` guarantees exclusivity.
8698        unsafe {
8699            crate::support::RefMut::new(AnimRefVector2f {
8700                raw: core::ptr::NonNull::new_unchecked(
8701                    ffi::whiteout_m3_M3TextureLayer_get_uvOffset(self.raw.as_ptr()),
8702                ),
8703            })
8704        }
8705    }
8706
8707    /// Animated UV rotation angles
8708    /// Borrows the field in place — no copy, no allocation.
8709    pub fn uv_angle(&self) -> crate::support::Ref<'_, AnimRefVector3f> {
8710        // SAFETY: an interior pointer into `self`, valid for this
8711        // borrow and never freed by the `Ref`.
8712        unsafe {
8713            crate::support::Ref::new(AnimRefVector3f {
8714                raw: core::ptr::NonNull::new_unchecked(
8715                    ffi::whiteout_m3_M3TextureLayer_get_uvAngle(self.raw.as_ptr()),
8716                ),
8717            })
8718        }
8719    }
8720
8721    pub fn uv_angle_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector3f> {
8722        // SAFETY: as above; `&mut self` guarantees exclusivity.
8723        unsafe {
8724            crate::support::RefMut::new(AnimRefVector3f {
8725                raw: core::ptr::NonNull::new_unchecked(
8726                    ffi::whiteout_m3_M3TextureLayer_get_uvAngle(self.raw.as_ptr()),
8727                ),
8728            })
8729        }
8730    }
8731
8732    /// Animated UV tiling
8733    /// Borrows the field in place — no copy, no allocation.
8734    pub fn uv_tiling(&self) -> crate::support::Ref<'_, AnimRefVector2f> {
8735        // SAFETY: an interior pointer into `self`, valid for this
8736        // borrow and never freed by the `Ref`.
8737        unsafe {
8738            crate::support::Ref::new(AnimRefVector2f {
8739                raw: core::ptr::NonNull::new_unchecked(
8740                    ffi::whiteout_m3_M3TextureLayer_get_uvTiling(self.raw.as_ptr()),
8741                ),
8742            })
8743        }
8744    }
8745
8746    pub fn uv_tiling_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector2f> {
8747        // SAFETY: as above; `&mut self` guarantees exclusivity.
8748        unsafe {
8749            crate::support::RefMut::new(AnimRefVector2f {
8750                raw: core::ptr::NonNull::new_unchecked(
8751                    ffi::whiteout_m3_M3TextureLayer_get_uvTiling(self.raw.as_ptr()),
8752                ),
8753            })
8754        }
8755    }
8756
8757    /// Animated W offset (3D textures)
8758    /// Borrows the field in place — no copy, no allocation.
8759    pub fn w_offset(&self) -> crate::support::Ref<'_, AnimRefF32> {
8760        // SAFETY: an interior pointer into `self`, valid for this
8761        // borrow and never freed by the `Ref`.
8762        unsafe {
8763            crate::support::Ref::new(AnimRefF32 {
8764                raw: core::ptr::NonNull::new_unchecked(
8765                    ffi::whiteout_m3_M3TextureLayer_get_wOffset(self.raw.as_ptr()),
8766                ),
8767            })
8768        }
8769    }
8770
8771    pub fn w_offset_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
8772        // SAFETY: as above; `&mut self` guarantees exclusivity.
8773        unsafe {
8774            crate::support::RefMut::new(AnimRefF32 {
8775                raw: core::ptr::NonNull::new_unchecked(
8776                    ffi::whiteout_m3_M3TextureLayer_get_wOffset(self.raw.as_ptr()),
8777                ),
8778            })
8779        }
8780    }
8781
8782    /// Animated W tiling (3D textures)
8783    /// Borrows the field in place — no copy, no allocation.
8784    pub fn w_tiling(&self) -> crate::support::Ref<'_, AnimRefF32> {
8785        // SAFETY: an interior pointer into `self`, valid for this
8786        // borrow and never freed by the `Ref`.
8787        unsafe {
8788            crate::support::Ref::new(AnimRefF32 {
8789                raw: core::ptr::NonNull::new_unchecked(
8790                    ffi::whiteout_m3_M3TextureLayer_get_wTiling(self.raw.as_ptr()),
8791                ),
8792            })
8793        }
8794    }
8795
8796    pub fn w_tiling_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
8797        // SAFETY: as above; `&mut self` guarantees exclusivity.
8798        unsafe {
8799            crate::support::RefMut::new(AnimRefF32 {
8800                raw: core::ptr::NonNull::new_unchecked(
8801                    ffi::whiteout_m3_M3TextureLayer_get_wTiling(self.raw.as_ptr()),
8802                ),
8803            })
8804        }
8805    }
8806
8807    /// Animated map alpha
8808    /// Borrows the field in place — no copy, no allocation.
8809    pub fn map_alpha(&self) -> crate::support::Ref<'_, AnimRefF32> {
8810        // SAFETY: an interior pointer into `self`, valid for this
8811        // borrow and never freed by the `Ref`.
8812        unsafe {
8813            crate::support::Ref::new(AnimRefF32 {
8814                raw: core::ptr::NonNull::new_unchecked(
8815                    ffi::whiteout_m3_M3TextureLayer_get_mapAlpha(self.raw.as_ptr()),
8816                ),
8817            })
8818        }
8819    }
8820
8821    pub fn map_alpha_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
8822        // SAFETY: as above; `&mut self` guarantees exclusivity.
8823        unsafe {
8824            crate::support::RefMut::new(AnimRefF32 {
8825                raw: core::ptr::NonNull::new_unchecked(
8826                    ffi::whiteout_m3_M3TextureLayer_get_mapAlpha(self.raw.as_ptr()),
8827                ),
8828            })
8829        }
8830    }
8831
8832    /// Tri-planar UV offset (v23+)
8833    /// Borrows the field in place — no copy, no allocation.
8834    pub fn triplanar_offset(&self) -> crate::support::Ref<'_, AnimRefVector3f> {
8835        // SAFETY: an interior pointer into `self`, valid for this
8836        // borrow and never freed by the `Ref`.
8837        unsafe {
8838            crate::support::Ref::new(AnimRefVector3f {
8839                raw: core::ptr::NonNull::new_unchecked(
8840                    ffi::whiteout_m3_M3TextureLayer_get_triplanarOffset(self.raw.as_ptr()),
8841                ),
8842            })
8843        }
8844    }
8845
8846    pub fn triplanar_offset_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector3f> {
8847        // SAFETY: as above; `&mut self` guarantees exclusivity.
8848        unsafe {
8849            crate::support::RefMut::new(AnimRefVector3f {
8850                raw: core::ptr::NonNull::new_unchecked(
8851                    ffi::whiteout_m3_M3TextureLayer_get_triplanarOffset(self.raw.as_ptr()),
8852                ),
8853            })
8854        }
8855    }
8856
8857    /// Tri-planar UV scale (v23+)
8858    /// Borrows the field in place — no copy, no allocation.
8859    pub fn triplanar_scale(&self) -> crate::support::Ref<'_, AnimRefVector3f> {
8860        // SAFETY: an interior pointer into `self`, valid for this
8861        // borrow and never freed by the `Ref`.
8862        unsafe {
8863            crate::support::Ref::new(AnimRefVector3f {
8864                raw: core::ptr::NonNull::new_unchecked(
8865                    ffi::whiteout_m3_M3TextureLayer_get_triplanarScale(self.raw.as_ptr()),
8866                ),
8867            })
8868        }
8869    }
8870
8871    pub fn triplanar_scale_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector3f> {
8872        // SAFETY: as above; `&mut self` guarantees exclusivity.
8873        unsafe {
8874            crate::support::RefMut::new(AnimRefVector3f {
8875                raw: core::ptr::NonNull::new_unchecked(
8876                    ffi::whiteout_m3_M3TextureLayer_get_triplanarScale(self.raw.as_ptr()),
8877                ),
8878            })
8879        }
8880    }
8881
8882    /// UV source related field
8883    pub fn uv_source_related(&self) -> u32 {
8884        // SAFETY: plain scalar read through a live handle.
8885        unsafe { ffi::whiteout_m3_M3TextureLayer_get_uvSourceRelated(self.raw.as_ptr()) }
8886    }
8887
8888    pub fn set_uv_source_related(&mut self, value: u32) {
8889        // SAFETY: plain scalar write through a live handle.
8890        unsafe { ffi::whiteout_m3_M3TextureLayer_set_uvSourceRelated(self.raw.as_ptr(), value) }
8891    }
8892
8893    /// Fresnel effect mode
8894    pub fn fresnel_mode(&self) -> FresnelMode {
8895        // SAFETY: scalar read; the discriminant is validated below.
8896        unsafe { ffi::whiteout_m3_M3TextureLayer_get_fresnelMode(self.raw.as_ptr()) }
8897            .try_into()
8898            .expect("unknown enum discriminant from the native library")
8899    }
8900
8901    pub fn set_fresnel_mode(&mut self, value: FresnelMode) {
8902        // SAFETY: scalar write through a live handle.
8903        unsafe { ffi::whiteout_m3_M3TextureLayer_set_fresnelMode(self.raw.as_ptr(), value as i32) }
8904    }
8905
8906    /// Fresnel exponent (edge sharpness)
8907    pub fn fresnel_exponent(&self) -> f32 {
8908        // SAFETY: plain scalar read through a live handle.
8909        unsafe { ffi::whiteout_m3_M3TextureLayer_get_fresnelExponent(self.raw.as_ptr()) }
8910    }
8911
8912    pub fn set_fresnel_exponent(&mut self, value: f32) {
8913        // SAFETY: plain scalar write through a live handle.
8914        unsafe { ffi::whiteout_m3_M3TextureLayer_set_fresnelExponent(self.raw.as_ptr(), value) }
8915    }
8916
8917    /// Fresnel minimum intensity
8918    pub fn fresnel_min(&self) -> f32 {
8919        // SAFETY: plain scalar read through a live handle.
8920        unsafe { ffi::whiteout_m3_M3TextureLayer_get_fresnelMin(self.raw.as_ptr()) }
8921    }
8922
8923    pub fn set_fresnel_min(&mut self, value: f32) {
8924        // SAFETY: plain scalar write through a live handle.
8925        unsafe { ffi::whiteout_m3_M3TextureLayer_set_fresnelMin(self.raw.as_ptr(), value) }
8926    }
8927
8928    /// Fresnel maximum intensity
8929    pub fn fresnel_max(&self) -> f32 {
8930        // SAFETY: plain scalar read through a live handle.
8931        unsafe { ffi::whiteout_m3_M3TextureLayer_get_fresnelMax(self.raw.as_ptr()) }
8932    }
8933
8934    pub fn set_fresnel_max(&mut self, value: f32) {
8935        // SAFETY: plain scalar write through a live handle.
8936        unsafe { ffi::whiteout_m3_M3TextureLayer_set_fresnelMax(self.raw.as_ptr(), value) }
8937    }
8938
8939    /// Fresnel UV translation (v25+)
8940    pub fn fresnel_translation(&self) -> crate::math::Vector3f {
8941        // SAFETY: the getter returns an interior pointer to a
8942        // layout-identical POD; we copy it out immediately.
8943        unsafe {
8944            *(ffi::whiteout_m3_M3TextureLayer_get_fresnelTranslation(self.raw.as_ptr())
8945                as *const crate::math::Vector3f)
8946        }
8947    }
8948
8949    pub fn set_fresnel_translation(&mut self, value: crate::math::Vector3f) {
8950        // SAFETY: as above, in the other direction.
8951        unsafe {
8952            ffi::whiteout_m3_M3TextureLayer_set_fresnelTranslation(
8953                self.raw.as_ptr(),
8954                &value as *const crate::math::Vector3f as *const _,
8955            )
8956        }
8957    }
8958
8959    /// Fresnel mask vector (v25+)
8960    pub fn fresnel_mask(&self) -> crate::math::Vector3f {
8961        // SAFETY: the getter returns an interior pointer to a
8962        // layout-identical POD; we copy it out immediately.
8963        unsafe {
8964            *(ffi::whiteout_m3_M3TextureLayer_get_fresnelMask(self.raw.as_ptr())
8965                as *const crate::math::Vector3f)
8966        }
8967    }
8968
8969    pub fn set_fresnel_mask(&mut self, value: crate::math::Vector3f) {
8970        // SAFETY: as above, in the other direction.
8971        unsafe {
8972            ffi::whiteout_m3_M3TextureLayer_set_fresnelMask(
8973                self.raw.as_ptr(),
8974                &value as *const crate::math::Vector3f as *const _,
8975            )
8976        }
8977    }
8978
8979    /// Fresnel UV rotation (v25+)
8980    pub fn fresnel_rotation(&self) -> crate::math::Vector2f {
8981        // SAFETY: the getter returns an interior pointer to a
8982        // layout-identical POD; we copy it out immediately.
8983        unsafe {
8984            *(ffi::whiteout_m3_M3TextureLayer_get_fresnelRotation(self.raw.as_ptr())
8985                as *const crate::math::Vector2f)
8986        }
8987    }
8988
8989    pub fn set_fresnel_rotation(&mut self, value: crate::math::Vector2f) {
8990        // SAFETY: as above, in the other direction.
8991        unsafe {
8992            ffi::whiteout_m3_M3TextureLayer_set_fresnelRotation(
8993                self.raw.as_ptr(),
8994                &value as *const crate::math::Vector2f as *const _,
8995            )
8996        }
8997    }
8998
8999    /// UV density hint (v0–v25, absent in v26)
9000    pub fn uv_density(&self) -> u32 {
9001        // SAFETY: plain scalar read through a live handle.
9002        unsafe { ffi::whiteout_m3_M3TextureLayer_get_uvDensity(self.raw.as_ptr()) }
9003    }
9004
9005    pub fn set_uv_density(&mut self, value: u32) {
9006        // SAFETY: plain scalar write through a live handle.
9007        unsafe { ffi::whiteout_m3_M3TextureLayer_set_uvDensity(self.raw.as_ptr(), value) }
9008    }
9009}
9010
9011impl Default for TextureLayer {
9012    fn default() -> Self {
9013        Self::new()
9014    }
9015}
9016
9017/// MAT_ — Standard material (v0–v20, 268–352 bytes)
9018///
9019/// 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.
9020pub struct StandardMaterial {
9021    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3StandardMaterial>,
9022}
9023
9024impl Drop for StandardMaterial {
9025    fn drop(&mut self) {
9026        // SAFETY: `raw` came from a native constructor and Drop runs once.
9027        unsafe { ffi::whiteout_m3_M3StandardMaterial_delete(self.raw.as_ptr()) }
9028    }
9029}
9030
9031impl StandardMaterial {
9032    /// # Safety
9033    /// `raw` must be a live handle this value takes ownership of.
9034    #[allow(dead_code)] // used by whichever methods return this type
9035    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3StandardMaterial) -> Option<Self> {
9036        core::ptr::NonNull::new(raw).map(|raw| StandardMaterial { raw })
9037    }
9038}
9039
9040// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
9041// is deliberately NOT implemented — the C++ types make no documented
9042// guarantee about concurrent use, and claiming one we haven't verified
9043// would be unsound. See `@bind thread_safe` in the plan.
9044unsafe impl Send for StandardMaterial {}
9045
9046impl core::fmt::Debug for StandardMaterial {
9047    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
9048        f.debug_struct("StandardMaterial").finish_non_exhaustive()
9049    }
9050}
9051
9052impl StandardMaterial {
9053    /// # Panics
9054    /// Panics if the native allocation fails.
9055    pub fn new() -> Self {
9056        // SAFETY: the native constructor returns a live handle; a null here
9057        // means the library is unusable.
9058        unsafe {
9059            let raw = ffi::whiteout_m3_M3StandardMaterial_new();
9060            Self::from_raw(raw).expect("native StandardMaterial allocation failed")
9061        }
9062    }
9063
9064    /// Material name (`Ref<CHAR>`)
9065    pub fn name(&self) -> String {
9066        // SAFETY: the native side hands over an owned CString.
9067        unsafe {
9068            crate::support::take_string(ffi::whiteout_m3_M3StandardMaterial_get_name(
9069                self.raw.as_ptr(),
9070            ))
9071        }
9072    }
9073
9074    pub fn set_name(&mut self, value: &str) {
9075        let value = std::ffi::CString::new(value).unwrap_or_default();
9076        // SAFETY: the pointer outlives the call.
9077        unsafe { ffi::whiteout_m3_M3StandardMaterial_set_name(self.raw.as_ptr(), value.as_ptr()) }
9078    }
9079
9080    /// Additional flags
9081    pub fn additional_flags(&self) -> MaterialAdditionalFlag {
9082        // SAFETY: scalar read; a flag set accepts any bits.
9083        MaterialAdditionalFlag(unsafe {
9084            ffi::whiteout_m3_M3StandardMaterial_get_additionalFlags(self.raw.as_ptr())
9085        })
9086    }
9087
9088    pub fn set_additional_flags(&mut self, value: MaterialAdditionalFlag) {
9089        // SAFETY: scalar write through a live handle.
9090        unsafe {
9091            ffi::whiteout_m3_M3StandardMaterial_set_additionalFlags(self.raw.as_ptr(), value.0)
9092        }
9093    }
9094
9095    /// Material rendering flags
9096    pub fn flags(&self) -> MaterialFlag {
9097        // SAFETY: scalar read; a flag set accepts any bits.
9098        MaterialFlag(unsafe { ffi::whiteout_m3_M3StandardMaterial_get_flags(self.raw.as_ptr()) })
9099    }
9100
9101    pub fn set_flags(&mut self, value: MaterialFlag) {
9102        // SAFETY: scalar write through a live handle.
9103        unsafe { ffi::whiteout_m3_M3StandardMaterial_set_flags(self.raw.as_ptr(), value.0) }
9104    }
9105
9106    /// Alpha blend mode
9107    pub fn blend_mode(&self) -> BlendMode {
9108        // SAFETY: scalar read; the discriminant is validated below.
9109        unsafe { ffi::whiteout_m3_M3StandardMaterial_get_blendMode(self.raw.as_ptr()) }
9110            .try_into()
9111            .expect("unknown enum discriminant from the native library")
9112    }
9113
9114    pub fn set_blend_mode(&mut self, value: BlendMode) {
9115        // SAFETY: scalar write through a live handle.
9116        unsafe {
9117            ffi::whiteout_m3_M3StandardMaterial_set_blendMode(self.raw.as_ptr(), value as i32)
9118        }
9119    }
9120
9121    /// Render priority (lower = earlier)
9122    pub fn priority(&self) -> i32 {
9123        // SAFETY: plain scalar read through a live handle.
9124        unsafe { ffi::whiteout_m3_M3StandardMaterial_get_priority(self.raw.as_ptr()) }
9125    }
9126
9127    pub fn set_priority(&mut self, value: i32) {
9128        // SAFETY: plain scalar write through a live handle.
9129        unsafe { ffi::whiteout_m3_M3StandardMaterial_set_priority(self.raw.as_ptr(), value) }
9130    }
9131
9132    /// RTT channel mask
9133    pub fn rtt_channels(&self) -> u32 {
9134        // SAFETY: plain scalar read through a live handle.
9135        unsafe { ffi::whiteout_m3_M3StandardMaterial_get_rttChannels(self.raw.as_ptr()) }
9136    }
9137
9138    pub fn set_rtt_channels(&mut self, value: u32) {
9139        // SAFETY: plain scalar write through a live handle.
9140        unsafe { ffi::whiteout_m3_M3StandardMaterial_set_rttChannels(self.raw.as_ptr(), value) }
9141    }
9142
9143    /// Specular highlight exponent
9144    pub fn specular_exponent(&self) -> f32 {
9145        // SAFETY: plain scalar read through a live handle.
9146        unsafe { ffi::whiteout_m3_M3StandardMaterial_get_specularExponent(self.raw.as_ptr()) }
9147    }
9148
9149    pub fn set_specular_exponent(&mut self, value: f32) {
9150        // SAFETY: plain scalar write through a live handle.
9151        unsafe {
9152            ffi::whiteout_m3_M3StandardMaterial_set_specularExponent(self.raw.as_ptr(), value)
9153        }
9154    }
9155
9156    /// Depth blend falloff distance
9157    pub fn depth_blend_falloff(&self) -> f32 {
9158        // SAFETY: plain scalar read through a live handle.
9159        unsafe { ffi::whiteout_m3_M3StandardMaterial_get_depthBlendFalloff(self.raw.as_ptr()) }
9160    }
9161
9162    pub fn set_depth_blend_falloff(&mut self, value: f32) {
9163        // SAFETY: plain scalar write through a live handle.
9164        unsafe {
9165            ffi::whiteout_m3_M3StandardMaterial_set_depthBlendFalloff(self.raw.as_ptr(), value)
9166        }
9167    }
9168
9169    /// Alpha test cut-off value
9170    pub fn alpha_test_threshold(&self) -> u32 {
9171        // SAFETY: plain scalar read through a live handle.
9172        unsafe { ffi::whiteout_m3_M3StandardMaterial_get_alphaTestThreshold(self.raw.as_ptr()) }
9173    }
9174
9175    pub fn set_alpha_test_threshold(&mut self, value: u32) {
9176        // SAFETY: plain scalar write through a live handle.
9177        unsafe {
9178            ffi::whiteout_m3_M3StandardMaterial_set_alphaTestThreshold(self.raw.as_ptr(), value)
9179        }
9180    }
9181
9182    /// HDR specular multiplier
9183    pub fn hdr_specular_multiplier(&self) -> f32 {
9184        // SAFETY: plain scalar read through a live handle.
9185        unsafe { ffi::whiteout_m3_M3StandardMaterial_get_hdrSpecularMultiplier(self.raw.as_ptr()) }
9186    }
9187
9188    pub fn set_hdr_specular_multiplier(&mut self, value: f32) {
9189        // SAFETY: plain scalar write through a live handle.
9190        unsafe {
9191            ffi::whiteout_m3_M3StandardMaterial_set_hdrSpecularMultiplier(self.raw.as_ptr(), value)
9192        }
9193    }
9194
9195    /// HDR emissive multiplier
9196    pub fn hdr_emissive_multiplier(&self) -> f32 {
9197        // SAFETY: plain scalar read through a live handle.
9198        unsafe { ffi::whiteout_m3_M3StandardMaterial_get_hdrEmissiveMultiplier(self.raw.as_ptr()) }
9199    }
9200
9201    pub fn set_hdr_emissive_multiplier(&mut self, value: f32) {
9202        // SAFETY: plain scalar write through a live handle.
9203        unsafe {
9204            ffi::whiteout_m3_M3StandardMaterial_set_hdrEmissiveMultiplier(self.raw.as_ptr(), value)
9205        }
9206    }
9207
9208    /// HDR environment constant (v20)
9209    pub fn hdr_environment_constant(&self) -> f32 {
9210        // SAFETY: plain scalar read through a live handle.
9211        unsafe { ffi::whiteout_m3_M3StandardMaterial_get_hdrEnvironmentConstant(self.raw.as_ptr()) }
9212    }
9213
9214    pub fn set_hdr_environment_constant(&mut self, value: f32) {
9215        // SAFETY: plain scalar write through a live handle.
9216        unsafe {
9217            ffi::whiteout_m3_M3StandardMaterial_set_hdrEnvironmentConstant(self.raw.as_ptr(), value)
9218        }
9219    }
9220
9221    /// HDR environment diffuse (v20)
9222    pub fn hdr_environment_diffuse(&self) -> f32 {
9223        // SAFETY: plain scalar read through a live handle.
9224        unsafe { ffi::whiteout_m3_M3StandardMaterial_get_hdrEnvironmentDiffuse(self.raw.as_ptr()) }
9225    }
9226
9227    pub fn set_hdr_environment_diffuse(&mut self, value: f32) {
9228        // SAFETY: plain scalar write through a live handle.
9229        unsafe {
9230            ffi::whiteout_m3_M3StandardMaterial_set_hdrEnvironmentDiffuse(self.raw.as_ptr(), value)
9231        }
9232    }
9233
9234    /// HDR environment specular (v20)
9235    pub fn hdr_environment_specular(&self) -> f32 {
9236        // SAFETY: plain scalar read through a live handle.
9237        unsafe { ffi::whiteout_m3_M3StandardMaterial_get_hdrEnvironmentSpecular(self.raw.as_ptr()) }
9238    }
9239
9240    pub fn set_hdr_environment_specular(&mut self, value: f32) {
9241        // SAFETY: plain scalar write through a live handle.
9242        unsafe {
9243            ffi::whiteout_m3_M3StandardMaterial_set_hdrEnvironmentSpecular(self.raw.as_ptr(), value)
9244        }
9245    }
9246
9247    /// Material class (unit, building, etc.)
9248    pub fn material_class(&self) -> MaterialClass {
9249        // SAFETY: scalar read; the discriminant is validated below.
9250        unsafe { ffi::whiteout_m3_M3StandardMaterial_get_materialClass(self.raw.as_ptr()) }
9251            .try_into()
9252            .expect("unknown enum discriminant from the native library")
9253    }
9254
9255    pub fn set_material_class(&mut self, value: MaterialClass) {
9256        // SAFETY: scalar write through a live handle.
9257        unsafe {
9258            ffi::whiteout_m3_M3StandardMaterial_set_materialClass(self.raw.as_ptr(), value as i32)
9259        }
9260    }
9261
9262    /// Layer blend operation
9263    pub fn layer_blend_mode(&self) -> LayerBlendOp {
9264        // SAFETY: scalar read; the discriminant is validated below.
9265        unsafe { ffi::whiteout_m3_M3StandardMaterial_get_layerBlendMode(self.raw.as_ptr()) }
9266            .try_into()
9267            .expect("unknown enum discriminant from the native library")
9268    }
9269
9270    pub fn set_layer_blend_mode(&mut self, value: LayerBlendOp) {
9271        // SAFETY: scalar write through a live handle.
9272        unsafe {
9273            ffi::whiteout_m3_M3StandardMaterial_set_layerBlendMode(self.raw.as_ptr(), value as i32)
9274        }
9275    }
9276
9277    /// Emissive layer 1 blend mode
9278    pub fn emissive_blend_mode_1(&self) -> LayerBlendOp {
9279        // SAFETY: scalar read; the discriminant is validated below.
9280        unsafe { ffi::whiteout_m3_M3StandardMaterial_get_emissiveBlendMode1(self.raw.as_ptr()) }
9281            .try_into()
9282            .expect("unknown enum discriminant from the native library")
9283    }
9284
9285    pub fn set_emissive_blend_mode_1(&mut self, value: LayerBlendOp) {
9286        // SAFETY: scalar write through a live handle.
9287        unsafe {
9288            ffi::whiteout_m3_M3StandardMaterial_set_emissiveBlendMode1(
9289                self.raw.as_ptr(),
9290                value as i32,
9291            )
9292        }
9293    }
9294
9295    /// Emissive layer 2 blend mode
9296    pub fn emissive_blend_mode_2(&self) -> LayerBlendOp {
9297        // SAFETY: scalar read; the discriminant is validated below.
9298        unsafe { ffi::whiteout_m3_M3StandardMaterial_get_emissiveBlendMode2(self.raw.as_ptr()) }
9299            .try_into()
9300            .expect("unknown enum discriminant from the native library")
9301    }
9302
9303    pub fn set_emissive_blend_mode_2(&mut self, value: LayerBlendOp) {
9304        // SAFETY: scalar write through a live handle.
9305        unsafe {
9306            ffi::whiteout_m3_M3StandardMaterial_set_emissiveBlendMode2(
9307                self.raw.as_ptr(),
9308                value as i32,
9309            )
9310        }
9311    }
9312
9313    /// Specular computation mode
9314    pub fn specular_mode(&self) -> SpecularMode {
9315        // SAFETY: scalar read; the discriminant is validated below.
9316        unsafe { ffi::whiteout_m3_M3StandardMaterial_get_specularMode(self.raw.as_ptr()) }
9317            .try_into()
9318            .expect("unknown enum discriminant from the native library")
9319    }
9320
9321    pub fn set_specular_mode(&mut self, value: SpecularMode) {
9322        // SAFETY: scalar write through a live handle.
9323        unsafe {
9324            ffi::whiteout_m3_M3StandardMaterial_set_specularMode(self.raw.as_ptr(), value as i32)
9325        }
9326    }
9327
9328    /// Animated parallax height
9329    /// Borrows the field in place — no copy, no allocation.
9330    pub fn parallax_height(&self) -> crate::support::Ref<'_, AnimRefF32> {
9331        // SAFETY: an interior pointer into `self`, valid for this
9332        // borrow and never freed by the `Ref`.
9333        unsafe {
9334            crate::support::Ref::new(AnimRefF32 {
9335                raw: core::ptr::NonNull::new_unchecked(
9336                    ffi::whiteout_m3_M3StandardMaterial_get_parallaxHeight(self.raw.as_ptr()),
9337                ),
9338            })
9339        }
9340    }
9341
9342    pub fn parallax_height_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
9343        // SAFETY: as above; `&mut self` guarantees exclusivity.
9344        unsafe {
9345            crate::support::RefMut::new(AnimRefF32 {
9346                raw: core::ptr::NonNull::new_unchecked(
9347                    ffi::whiteout_m3_M3StandardMaterial_get_parallaxHeight(self.raw.as_ptr()),
9348                ),
9349            })
9350        }
9351    }
9352
9353    /// Animated motion blur amount
9354    /// Borrows the field in place — no copy, no allocation.
9355    pub fn motion_blur_amount(&self) -> crate::support::Ref<'_, AnimRefF32> {
9356        // SAFETY: an interior pointer into `self`, valid for this
9357        // borrow and never freed by the `Ref`.
9358        unsafe {
9359            crate::support::Ref::new(AnimRefF32 {
9360                raw: core::ptr::NonNull::new_unchecked(
9361                    ffi::whiteout_m3_M3StandardMaterial_get_motionBlurAmount(self.raw.as_ptr()),
9362                ),
9363            })
9364        }
9365    }
9366
9367    pub fn motion_blur_amount_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
9368        // SAFETY: as above; `&mut self` guarantees exclusivity.
9369        unsafe {
9370            crate::support::RefMut::new(AnimRefF32 {
9371                raw: core::ptr::NonNull::new_unchecked(
9372                    ffi::whiteout_m3_M3StandardMaterial_get_motionBlurAmount(self.raw.as_ptr()),
9373                ),
9374            })
9375        }
9376    }
9377
9378    /// Normal blend factors (v19+)
9379    pub fn normal_blend_factors_len(&self) -> usize {
9380        // SAFETY: scalar read through a live handle.
9381        unsafe {
9382            ffi::whiteout_m3_M3StandardMaterial_get_normalBlendFactors_count(self.raw.as_ptr())
9383        }
9384    }
9385
9386    /// Borrows element `index` in place. `None` when out of range.
9387    pub fn normal_blend_factors(
9388        &self,
9389        index: usize,
9390    ) -> Option<crate::support::Ref<'_, AnimRefF32>> {
9391        if index >= self.normal_blend_factors_len() {
9392            return None;
9393        }
9394        // SAFETY: index checked above; the pointer is interior to `self`.
9395        unsafe {
9396            Some(crate::support::Ref::new(AnimRefF32 {
9397                raw: core::ptr::NonNull::new_unchecked(
9398                    ffi::whiteout_m3_M3StandardMaterial_get_normalBlendFactors_at(
9399                        self.raw.as_ptr(),
9400                        index,
9401                    ),
9402                ),
9403            }))
9404        }
9405    }
9406
9407    pub fn normal_blend_factors_mut(
9408        &mut self,
9409        index: usize,
9410    ) -> Option<crate::support::RefMut<'_, AnimRefF32>> {
9411        if index >= self.normal_blend_factors_len() {
9412            return None;
9413        }
9414        // SAFETY: as above; `&mut self` guarantees exclusivity.
9415        unsafe {
9416            Some(crate::support::RefMut::new(AnimRefF32 {
9417                raw: core::ptr::NonNull::new_unchecked(
9418                    ffi::whiteout_m3_M3StandardMaterial_get_normalBlendFactors_at(
9419                        self.raw.as_ptr(),
9420                        index,
9421                    ),
9422                ),
9423            }))
9424        }
9425    }
9426
9427    /// Iterate the elements, borrowing each in turn.
9428    pub fn normal_blend_factors_iter(
9429        &self,
9430    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, AnimRefF32>> {
9431        (0..self.normal_blend_factors_len())
9432            .map(move |i| self.normal_blend_factors(i).expect("index below len"))
9433    }
9434
9435    pub fn resize_normal_blend_factors(&mut self, count: usize) {
9436        // SAFETY: exclusive access, so no borrow is outstanding.
9437        unsafe {
9438            ffi::whiteout_m3_M3StandardMaterial_resize_normalBlendFactors(self.raw.as_ptr(), count)
9439        }
9440    }
9441}
9442
9443impl Default for StandardMaterial {
9444    fn default() -> Self {
9445        Self::new()
9446    }
9447}
9448
9449/// DIS_ — Displacement material (v0–v4, 68 bytes)
9450///
9451/// Applies vertex displacement via a normal map and animated strength.
9452pub struct DisplacementMaterial {
9453    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3DisplacementMaterial>,
9454}
9455
9456impl Drop for DisplacementMaterial {
9457    fn drop(&mut self) {
9458        // SAFETY: `raw` came from a native constructor and Drop runs once.
9459        unsafe { ffi::whiteout_m3_M3DisplacementMaterial_delete(self.raw.as_ptr()) }
9460    }
9461}
9462
9463impl DisplacementMaterial {
9464    /// # Safety
9465    /// `raw` must be a live handle this value takes ownership of.
9466    #[allow(dead_code)] // used by whichever methods return this type
9467    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3DisplacementMaterial) -> Option<Self> {
9468        core::ptr::NonNull::new(raw).map(|raw| DisplacementMaterial { raw })
9469    }
9470}
9471
9472// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
9473// is deliberately NOT implemented — the C++ types make no documented
9474// guarantee about concurrent use, and claiming one we haven't verified
9475// would be unsound. See `@bind thread_safe` in the plan.
9476unsafe impl Send for DisplacementMaterial {}
9477
9478impl core::fmt::Debug for DisplacementMaterial {
9479    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
9480        f.debug_struct("DisplacementMaterial")
9481            .finish_non_exhaustive()
9482    }
9483}
9484
9485impl DisplacementMaterial {
9486    /// # Panics
9487    /// Panics if the native allocation fails.
9488    pub fn new() -> Self {
9489        // SAFETY: the native constructor returns a live handle; a null here
9490        // means the library is unusable.
9491        unsafe {
9492            let raw = ffi::whiteout_m3_M3DisplacementMaterial_new();
9493            Self::from_raw(raw).expect("native DisplacementMaterial allocation failed")
9494        }
9495    }
9496
9497    /// Material name (`Ref<CHAR>`)
9498    pub fn name(&self) -> String {
9499        // SAFETY: the native side hands over an owned CString.
9500        unsafe {
9501            crate::support::take_string(ffi::whiteout_m3_M3DisplacementMaterial_get_name(
9502                self.raw.as_ptr(),
9503            ))
9504        }
9505    }
9506
9507    pub fn set_name(&mut self, value: &str) {
9508        let value = std::ffi::CString::new(value).unwrap_or_default();
9509        // SAFETY: the pointer outlives the call.
9510        unsafe {
9511            ffi::whiteout_m3_M3DisplacementMaterial_set_name(self.raw.as_ptr(), value.as_ptr())
9512        }
9513    }
9514
9515    /// Unknown field
9516    pub fn unknown(&self) -> u32 {
9517        // SAFETY: plain scalar read through a live handle.
9518        unsafe { ffi::whiteout_m3_M3DisplacementMaterial_get_unknown(self.raw.as_ptr()) }
9519    }
9520
9521    pub fn set_unknown(&mut self, value: u32) {
9522        // SAFETY: plain scalar write through a live handle.
9523        unsafe { ffi::whiteout_m3_M3DisplacementMaterial_set_unknown(self.raw.as_ptr(), value) }
9524    }
9525
9526    /// Animated displacement strength
9527    /// Borrows the field in place — no copy, no allocation.
9528    pub fn strength(&self) -> crate::support::Ref<'_, AnimRefF32> {
9529        // SAFETY: an interior pointer into `self`, valid for this
9530        // borrow and never freed by the `Ref`.
9531        unsafe {
9532            crate::support::Ref::new(AnimRefF32 {
9533                raw: core::ptr::NonNull::new_unchecked(
9534                    ffi::whiteout_m3_M3DisplacementMaterial_get_strength(self.raw.as_ptr()),
9535                ),
9536            })
9537        }
9538    }
9539
9540    pub fn strength_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
9541        // SAFETY: as above; `&mut self` guarantees exclusivity.
9542        unsafe {
9543            crate::support::RefMut::new(AnimRefF32 {
9544                raw: core::ptr::NonNull::new_unchecked(
9545                    ffi::whiteout_m3_M3DisplacementMaterial_get_strength(self.raw.as_ptr()),
9546                ),
9547            })
9548        }
9549    }
9550
9551    /// Render priority
9552    pub fn priority(&self) -> u32 {
9553        // SAFETY: plain scalar read through a live handle.
9554        unsafe { ffi::whiteout_m3_M3DisplacementMaterial_get_priority(self.raw.as_ptr()) }
9555    }
9556
9557    pub fn set_priority(&mut self, value: u32) {
9558        // SAFETY: plain scalar write through a live handle.
9559        unsafe { ffi::whiteout_m3_M3DisplacementMaterial_set_priority(self.raw.as_ptr(), value) }
9560    }
9561}
9562
9563impl Default for DisplacementMaterial {
9564    fn default() -> Self {
9565        Self::new()
9566    }
9567}
9568
9569/// CMS_ — Composite material section (v0, 24 bytes)
9570///
9571/// A single section within a composite material, referencing another material index with an animated blend multiplier.
9572pub struct CompositeSection {
9573    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3CompositeSection>,
9574}
9575
9576impl Drop for CompositeSection {
9577    fn drop(&mut self) {
9578        // SAFETY: `raw` came from a native constructor and Drop runs once.
9579        unsafe { ffi::whiteout_m3_M3CompositeSection_delete(self.raw.as_ptr()) }
9580    }
9581}
9582
9583impl CompositeSection {
9584    /// # Safety
9585    /// `raw` must be a live handle this value takes ownership of.
9586    #[allow(dead_code)] // used by whichever methods return this type
9587    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3CompositeSection) -> Option<Self> {
9588        core::ptr::NonNull::new(raw).map(|raw| CompositeSection { raw })
9589    }
9590}
9591
9592// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
9593// is deliberately NOT implemented — the C++ types make no documented
9594// guarantee about concurrent use, and claiming one we haven't verified
9595// would be unsound. See `@bind thread_safe` in the plan.
9596unsafe impl Send for CompositeSection {}
9597
9598impl core::fmt::Debug for CompositeSection {
9599    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
9600        f.debug_struct("CompositeSection").finish_non_exhaustive()
9601    }
9602}
9603
9604impl CompositeSection {
9605    /// # Panics
9606    /// Panics if the native allocation fails.
9607    pub fn new() -> Self {
9608        // SAFETY: the native constructor returns a live handle; a null here
9609        // means the library is unusable.
9610        unsafe {
9611            let raw = ffi::whiteout_m3_M3CompositeSection_new();
9612            Self::from_raw(raw).expect("native CompositeSection allocation failed")
9613        }
9614    }
9615
9616    /// Index into MATM array
9617    pub fn material_index(&self) -> u32 {
9618        // SAFETY: plain scalar read through a live handle.
9619        unsafe { ffi::whiteout_m3_M3CompositeSection_get_materialIndex(self.raw.as_ptr()) }
9620    }
9621
9622    pub fn set_material_index(&mut self, value: u32) {
9623        // SAFETY: plain scalar write through a live handle.
9624        unsafe { ffi::whiteout_m3_M3CompositeSection_set_materialIndex(self.raw.as_ptr(), value) }
9625    }
9626
9627    /// Animated blend weight
9628    /// Borrows the field in place — no copy, no allocation.
9629    pub fn map_multiplier(&self) -> crate::support::Ref<'_, AnimRefF32> {
9630        // SAFETY: an interior pointer into `self`, valid for this
9631        // borrow and never freed by the `Ref`.
9632        unsafe {
9633            crate::support::Ref::new(AnimRefF32 {
9634                raw: core::ptr::NonNull::new_unchecked(
9635                    ffi::whiteout_m3_M3CompositeSection_get_mapMultiplier(self.raw.as_ptr()),
9636                ),
9637            })
9638        }
9639    }
9640
9641    pub fn map_multiplier_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
9642        // SAFETY: as above; `&mut self` guarantees exclusivity.
9643        unsafe {
9644            crate::support::RefMut::new(AnimRefF32 {
9645                raw: core::ptr::NonNull::new_unchecked(
9646                    ffi::whiteout_m3_M3CompositeSection_get_mapMultiplier(self.raw.as_ptr()),
9647                ),
9648            })
9649        }
9650    }
9651}
9652
9653impl Default for CompositeSection {
9654    fn default() -> Self {
9655        Self::new()
9656    }
9657}
9658
9659/// CMP_ — Composite material (v0–v2, 28 bytes)
9660///
9661/// Blends multiple sub-materials via CompositeSection entries.
9662pub struct CompositeMaterial {
9663    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3CompositeMaterial>,
9664}
9665
9666impl Drop for CompositeMaterial {
9667    fn drop(&mut self) {
9668        // SAFETY: `raw` came from a native constructor and Drop runs once.
9669        unsafe { ffi::whiteout_m3_M3CompositeMaterial_delete(self.raw.as_ptr()) }
9670    }
9671}
9672
9673impl CompositeMaterial {
9674    /// # Safety
9675    /// `raw` must be a live handle this value takes ownership of.
9676    #[allow(dead_code)] // used by whichever methods return this type
9677    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3CompositeMaterial) -> Option<Self> {
9678        core::ptr::NonNull::new(raw).map(|raw| CompositeMaterial { raw })
9679    }
9680}
9681
9682// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
9683// is deliberately NOT implemented — the C++ types make no documented
9684// guarantee about concurrent use, and claiming one we haven't verified
9685// would be unsound. See `@bind thread_safe` in the plan.
9686unsafe impl Send for CompositeMaterial {}
9687
9688impl core::fmt::Debug for CompositeMaterial {
9689    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
9690        f.debug_struct("CompositeMaterial").finish_non_exhaustive()
9691    }
9692}
9693
9694impl CompositeMaterial {
9695    /// # Panics
9696    /// Panics if the native allocation fails.
9697    pub fn new() -> Self {
9698        // SAFETY: the native constructor returns a live handle; a null here
9699        // means the library is unusable.
9700        unsafe {
9701            let raw = ffi::whiteout_m3_M3CompositeMaterial_new();
9702            Self::from_raw(raw).expect("native CompositeMaterial allocation failed")
9703        }
9704    }
9705
9706    /// Material name (`Ref<CHAR>`)
9707    pub fn name(&self) -> String {
9708        // SAFETY: the native side hands over an owned CString.
9709        unsafe {
9710            crate::support::take_string(ffi::whiteout_m3_M3CompositeMaterial_get_name(
9711                self.raw.as_ptr(),
9712            ))
9713        }
9714    }
9715
9716    pub fn set_name(&mut self, value: &str) {
9717        let value = std::ffi::CString::new(value).unwrap_or_default();
9718        // SAFETY: the pointer outlives the call.
9719        unsafe { ffi::whiteout_m3_M3CompositeMaterial_set_name(self.raw.as_ptr(), value.as_ptr()) }
9720    }
9721
9722    /// Render priority
9723    pub fn priority(&self) -> u32 {
9724        // SAFETY: plain scalar read through a live handle.
9725        unsafe { ffi::whiteout_m3_M3CompositeMaterial_get_priority(self.raw.as_ptr()) }
9726    }
9727
9728    pub fn set_priority(&mut self, value: u32) {
9729        // SAFETY: plain scalar write through a live handle.
9730        unsafe { ffi::whiteout_m3_M3CompositeMaterial_set_priority(self.raw.as_ptr(), value) }
9731    }
9732
9733    /// Sub-material sections (CMS_)
9734    pub fn sections_len(&self) -> usize {
9735        // SAFETY: scalar read through a live handle.
9736        unsafe { ffi::whiteout_m3_M3CompositeMaterial_get_sections_count(self.raw.as_ptr()) }
9737    }
9738
9739    /// Borrows element `index` in place. `None` when out of range.
9740    pub fn sections(&self, index: usize) -> Option<crate::support::Ref<'_, CompositeSection>> {
9741        if index >= self.sections_len() {
9742            return None;
9743        }
9744        // SAFETY: index checked above; the pointer is interior to `self`.
9745        unsafe {
9746            Some(crate::support::Ref::new(CompositeSection {
9747                raw: core::ptr::NonNull::new_unchecked(
9748                    ffi::whiteout_m3_M3CompositeMaterial_get_sections_at(self.raw.as_ptr(), index),
9749                ),
9750            }))
9751        }
9752    }
9753
9754    pub fn sections_mut(
9755        &mut self,
9756        index: usize,
9757    ) -> Option<crate::support::RefMut<'_, CompositeSection>> {
9758        if index >= self.sections_len() {
9759            return None;
9760        }
9761        // SAFETY: as above; `&mut self` guarantees exclusivity.
9762        unsafe {
9763            Some(crate::support::RefMut::new(CompositeSection {
9764                raw: core::ptr::NonNull::new_unchecked(
9765                    ffi::whiteout_m3_M3CompositeMaterial_get_sections_at(self.raw.as_ptr(), index),
9766                ),
9767            }))
9768        }
9769    }
9770
9771    /// Iterate the elements, borrowing each in turn.
9772    pub fn sections_iter(
9773        &self,
9774    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, CompositeSection>> {
9775        (0..self.sections_len()).map(move |i| self.sections(i).expect("index below len"))
9776    }
9777
9778    pub fn resize_sections(&mut self, count: usize) {
9779        // SAFETY: exclusive access, so no borrow is outstanding.
9780        unsafe { ffi::whiteout_m3_M3CompositeMaterial_resize_sections(self.raw.as_ptr(), count) }
9781    }
9782}
9783
9784impl Default for CompositeMaterial {
9785    fn default() -> Self {
9786        Self::new()
9787    }
9788}
9789
9790/// TER_ — Terrain material (v0–v1, 28 bytes)
9791///
9792/// Simple terrain-specific material with a single texture layer.
9793pub struct TerrainMaterial {
9794    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3TerrainMaterial>,
9795}
9796
9797impl Drop for TerrainMaterial {
9798    fn drop(&mut self) {
9799        // SAFETY: `raw` came from a native constructor and Drop runs once.
9800        unsafe { ffi::whiteout_m3_M3TerrainMaterial_delete(self.raw.as_ptr()) }
9801    }
9802}
9803
9804impl TerrainMaterial {
9805    /// # Safety
9806    /// `raw` must be a live handle this value takes ownership of.
9807    #[allow(dead_code)] // used by whichever methods return this type
9808    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3TerrainMaterial) -> Option<Self> {
9809        core::ptr::NonNull::new(raw).map(|raw| TerrainMaterial { raw })
9810    }
9811}
9812
9813// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
9814// is deliberately NOT implemented — the C++ types make no documented
9815// guarantee about concurrent use, and claiming one we haven't verified
9816// would be unsound. See `@bind thread_safe` in the plan.
9817unsafe impl Send for TerrainMaterial {}
9818
9819impl core::fmt::Debug for TerrainMaterial {
9820    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
9821        f.debug_struct("TerrainMaterial").finish_non_exhaustive()
9822    }
9823}
9824
9825impl TerrainMaterial {
9826    /// # Panics
9827    /// Panics if the native allocation fails.
9828    pub fn new() -> Self {
9829        // SAFETY: the native constructor returns a live handle; a null here
9830        // means the library is unusable.
9831        unsafe {
9832            let raw = ffi::whiteout_m3_M3TerrainMaterial_new();
9833            Self::from_raw(raw).expect("native TerrainMaterial allocation failed")
9834        }
9835    }
9836
9837    /// Material name (`Ref<CHAR>`)
9838    pub fn name(&self) -> String {
9839        // SAFETY: the native side hands over an owned CString.
9840        unsafe {
9841            crate::support::take_string(ffi::whiteout_m3_M3TerrainMaterial_get_name(
9842                self.raw.as_ptr(),
9843            ))
9844        }
9845    }
9846
9847    pub fn set_name(&mut self, value: &str) {
9848        let value = std::ffi::CString::new(value).unwrap_or_default();
9849        // SAFETY: the pointer outlives the call.
9850        unsafe { ffi::whiteout_m3_M3TerrainMaterial_set_name(self.raw.as_ptr(), value.as_ptr()) }
9851    }
9852
9853    /// Unknown field
9854    pub fn unknown(&self) -> u32 {
9855        // SAFETY: plain scalar read through a live handle.
9856        unsafe { ffi::whiteout_m3_M3TerrainMaterial_get_unknown(self.raw.as_ptr()) }
9857    }
9858
9859    pub fn set_unknown(&mut self, value: u32) {
9860        // SAFETY: plain scalar write through a live handle.
9861        unsafe { ffi::whiteout_m3_M3TerrainMaterial_set_unknown(self.raw.as_ptr(), value) }
9862    }
9863}
9864
9865impl Default for TerrainMaterial {
9866    fn default() -> Self {
9867        Self::new()
9868    }
9869}
9870
9871/// VOL_ — Volume material (v0, 84 bytes)
9872///
9873/// Volumetric rendering material with density falloff, color map, and two noise maps for procedural volumetric effects.
9874pub struct VolumeMaterial {
9875    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3VolumeMaterial>,
9876}
9877
9878impl Drop for VolumeMaterial {
9879    fn drop(&mut self) {
9880        // SAFETY: `raw` came from a native constructor and Drop runs once.
9881        unsafe { ffi::whiteout_m3_M3VolumeMaterial_delete(self.raw.as_ptr()) }
9882    }
9883}
9884
9885impl VolumeMaterial {
9886    /// # Safety
9887    /// `raw` must be a live handle this value takes ownership of.
9888    #[allow(dead_code)] // used by whichever methods return this type
9889    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3VolumeMaterial) -> Option<Self> {
9890        core::ptr::NonNull::new(raw).map(|raw| VolumeMaterial { raw })
9891    }
9892}
9893
9894// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
9895// is deliberately NOT implemented — the C++ types make no documented
9896// guarantee about concurrent use, and claiming one we haven't verified
9897// would be unsound. See `@bind thread_safe` in the plan.
9898unsafe impl Send for VolumeMaterial {}
9899
9900impl core::fmt::Debug for VolumeMaterial {
9901    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
9902        f.debug_struct("VolumeMaterial").finish_non_exhaustive()
9903    }
9904}
9905
9906impl VolumeMaterial {
9907    /// # Panics
9908    /// Panics if the native allocation fails.
9909    pub fn new() -> Self {
9910        // SAFETY: the native constructor returns a live handle; a null here
9911        // means the library is unusable.
9912        unsafe {
9913            let raw = ffi::whiteout_m3_M3VolumeMaterial_new();
9914            Self::from_raw(raw).expect("native VolumeMaterial allocation failed")
9915        }
9916    }
9917
9918    /// Material name (`Ref<CHAR>`)
9919    pub fn name(&self) -> String {
9920        // SAFETY: the native side hands over an owned CString.
9921        unsafe {
9922            crate::support::take_string(ffi::whiteout_m3_M3VolumeMaterial_get_name(
9923                self.raw.as_ptr(),
9924            ))
9925        }
9926    }
9927
9928    pub fn set_name(&mut self, value: &str) {
9929        let value = std::ffi::CString::new(value).unwrap_or_default();
9930        // SAFETY: the pointer outlives the call.
9931        unsafe { ffi::whiteout_m3_M3VolumeMaterial_set_name(self.raw.as_ptr(), value.as_ptr()) }
9932    }
9933
9934    /// Blend mode
9935    pub fn blend_mode(&self) -> u32 {
9936        // SAFETY: plain scalar read through a live handle.
9937        unsafe { ffi::whiteout_m3_M3VolumeMaterial_get_blendMode(self.raw.as_ptr()) }
9938    }
9939
9940    pub fn set_blend_mode(&mut self, value: u32) {
9941        // SAFETY: plain scalar write through a live handle.
9942        unsafe { ffi::whiteout_m3_M3VolumeMaterial_set_blendMode(self.raw.as_ptr(), value) }
9943    }
9944
9945    /// Density falloff type
9946    pub fn falloff_type(&self) -> VolumeFalloffType {
9947        // SAFETY: scalar read; the discriminant is validated below.
9948        unsafe { ffi::whiteout_m3_M3VolumeMaterial_get_falloffType(self.raw.as_ptr()) }
9949            .try_into()
9950            .expect("unknown enum discriminant from the native library")
9951    }
9952
9953    pub fn set_falloff_type(&mut self, value: VolumeFalloffType) {
9954        // SAFETY: scalar write through a live handle.
9955        unsafe {
9956            ffi::whiteout_m3_M3VolumeMaterial_set_falloffType(self.raw.as_ptr(), value as i32)
9957        }
9958    }
9959
9960    /// Animated density
9961    /// Borrows the field in place — no copy, no allocation.
9962    pub fn density(&self) -> crate::support::Ref<'_, AnimRefF32> {
9963        // SAFETY: an interior pointer into `self`, valid for this
9964        // borrow and never freed by the `Ref`.
9965        unsafe {
9966            crate::support::Ref::new(AnimRefF32 {
9967                raw: core::ptr::NonNull::new_unchecked(
9968                    ffi::whiteout_m3_M3VolumeMaterial_get_density(self.raw.as_ptr()),
9969                ),
9970            })
9971        }
9972    }
9973
9974    pub fn density_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
9975        // SAFETY: as above; `&mut self` guarantees exclusivity.
9976        unsafe {
9977            crate::support::RefMut::new(AnimRefF32 {
9978                raw: core::ptr::NonNull::new_unchecked(
9979                    ffi::whiteout_m3_M3VolumeMaterial_get_density(self.raw.as_ptr()),
9980                ),
9981            })
9982        }
9983    }
9984
9985    /// Alpha test threshold
9986    pub fn alpha_threshold(&self) -> u32 {
9987        // SAFETY: plain scalar read through a live handle.
9988        unsafe { ffi::whiteout_m3_M3VolumeMaterial_get_alphaThreshold(self.raw.as_ptr()) }
9989    }
9990
9991    pub fn set_alpha_threshold(&mut self, value: u32) {
9992        // SAFETY: plain scalar write through a live handle.
9993        unsafe { ffi::whiteout_m3_M3VolumeMaterial_set_alphaThreshold(self.raw.as_ptr(), value) }
9994    }
9995}
9996
9997impl Default for VolumeMaterial {
9998    fn default() -> Self {
9999        Self::new()
10000    }
10001}
10002
10003/// HAI_ — Hair material (defunct, v0, 116 bytes)
10004///
10005/// Anisotropic hair rendering material with specular shift and AO. Always null in observed corpus data.
10006pub struct HairMaterial {
10007    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3HairMaterial>,
10008}
10009
10010impl Drop for HairMaterial {
10011    fn drop(&mut self) {
10012        // SAFETY: `raw` came from a native constructor and Drop runs once.
10013        unsafe { ffi::whiteout_m3_M3HairMaterial_delete(self.raw.as_ptr()) }
10014    }
10015}
10016
10017impl HairMaterial {
10018    /// # Safety
10019    /// `raw` must be a live handle this value takes ownership of.
10020    #[allow(dead_code)] // used by whichever methods return this type
10021    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3HairMaterial) -> Option<Self> {
10022        core::ptr::NonNull::new(raw).map(|raw| HairMaterial { raw })
10023    }
10024}
10025
10026// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
10027// is deliberately NOT implemented — the C++ types make no documented
10028// guarantee about concurrent use, and claiming one we haven't verified
10029// would be unsound. See `@bind thread_safe` in the plan.
10030unsafe impl Send for HairMaterial {}
10031
10032impl core::fmt::Debug for HairMaterial {
10033    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
10034        f.debug_struct("HairMaterial").finish_non_exhaustive()
10035    }
10036}
10037
10038impl HairMaterial {
10039    /// # Panics
10040    /// Panics if the native allocation fails.
10041    pub fn new() -> Self {
10042        // SAFETY: the native constructor returns a live handle; a null here
10043        // means the library is unusable.
10044        unsafe {
10045            let raw = ffi::whiteout_m3_M3HairMaterial_new();
10046            Self::from_raw(raw).expect("native HairMaterial allocation failed")
10047        }
10048    }
10049
10050    /// Material name (`Ref<CHAR>`)
10051    pub fn name(&self) -> String {
10052        // SAFETY: the native side hands over an owned CString.
10053        unsafe {
10054            crate::support::take_string(ffi::whiteout_m3_M3HairMaterial_get_name(self.raw.as_ptr()))
10055        }
10056    }
10057
10058    pub fn set_name(&mut self, value: &str) {
10059        let value = std::ffi::CString::new(value).unwrap_or_default();
10060        // SAFETY: the pointer outlives the call.
10061        unsafe { ffi::whiteout_m3_M3HairMaterial_set_name(self.raw.as_ptr(), value.as_ptr()) }
10062    }
10063
10064    /// Primary specular shift
10065    pub fn shift_primary(&self) -> f32 {
10066        // SAFETY: plain scalar read through a live handle.
10067        unsafe { ffi::whiteout_m3_M3HairMaterial_get_shiftPrimary(self.raw.as_ptr()) }
10068    }
10069
10070    pub fn set_shift_primary(&mut self, value: f32) {
10071        // SAFETY: plain scalar write through a live handle.
10072        unsafe { ffi::whiteout_m3_M3HairMaterial_set_shiftPrimary(self.raw.as_ptr(), value) }
10073    }
10074
10075    /// Secondary specular shift
10076    pub fn shift_secondary(&self) -> f32 {
10077        // SAFETY: plain scalar read through a live handle.
10078        unsafe { ffi::whiteout_m3_M3HairMaterial_get_shiftSecondary(self.raw.as_ptr()) }
10079    }
10080
10081    pub fn set_shift_secondary(&mut self, value: f32) {
10082        // SAFETY: plain scalar write through a live handle.
10083        unsafe { ffi::whiteout_m3_M3HairMaterial_set_shiftSecondary(self.raw.as_ptr(), value) }
10084    }
10085
10086    /// Animated diffuse tint
10087    /// Borrows the field in place — no copy, no allocation.
10088    pub fn color_diffuse(&self) -> crate::support::Ref<'_, AnimRefM3ColorBGRA> {
10089        // SAFETY: an interior pointer into `self`, valid for this
10090        // borrow and never freed by the `Ref`.
10091        unsafe {
10092            crate::support::Ref::new(AnimRefM3ColorBGRA {
10093                raw: core::ptr::NonNull::new_unchecked(
10094                    ffi::whiteout_m3_M3HairMaterial_get_colorDiffuse(self.raw.as_ptr()),
10095                ),
10096            })
10097        }
10098    }
10099
10100    pub fn color_diffuse_mut(&mut self) -> crate::support::RefMut<'_, AnimRefM3ColorBGRA> {
10101        // SAFETY: as above; `&mut self` guarantees exclusivity.
10102        unsafe {
10103            crate::support::RefMut::new(AnimRefM3ColorBGRA {
10104                raw: core::ptr::NonNull::new_unchecked(
10105                    ffi::whiteout_m3_M3HairMaterial_get_colorDiffuse(self.raw.as_ptr()),
10106                ),
10107            })
10108        }
10109    }
10110
10111    /// Animated specular tint
10112    /// Borrows the field in place — no copy, no allocation.
10113    pub fn color_spec(&self) -> crate::support::Ref<'_, AnimRefM3ColorBGRA> {
10114        // SAFETY: an interior pointer into `self`, valid for this
10115        // borrow and never freed by the `Ref`.
10116        unsafe {
10117            crate::support::Ref::new(AnimRefM3ColorBGRA {
10118                raw: core::ptr::NonNull::new_unchecked(
10119                    ffi::whiteout_m3_M3HairMaterial_get_colorSpec(self.raw.as_ptr()),
10120                ),
10121            })
10122        }
10123    }
10124
10125    pub fn color_spec_mut(&mut self) -> crate::support::RefMut<'_, AnimRefM3ColorBGRA> {
10126        // SAFETY: as above; `&mut self` guarantees exclusivity.
10127        unsafe {
10128            crate::support::RefMut::new(AnimRefM3ColorBGRA {
10129                raw: core::ptr::NonNull::new_unchecked(
10130                    ffi::whiteout_m3_M3HairMaterial_get_colorSpec(self.raw.as_ptr()),
10131                ),
10132            })
10133        }
10134    }
10135
10136    /// Primary specular exponent
10137    pub fn spec_exponent_0(&self) -> f32 {
10138        // SAFETY: plain scalar read through a live handle.
10139        unsafe { ffi::whiteout_m3_M3HairMaterial_get_specExponent0(self.raw.as_ptr()) }
10140    }
10141
10142    pub fn set_spec_exponent_0(&mut self, value: f32) {
10143        // SAFETY: plain scalar write through a live handle.
10144        unsafe { ffi::whiteout_m3_M3HairMaterial_set_specExponent0(self.raw.as_ptr(), value) }
10145    }
10146
10147    /// Secondary specular exponent
10148    pub fn spec_exponent_1(&self) -> f32 {
10149        // SAFETY: plain scalar read through a live handle.
10150        unsafe { ffi::whiteout_m3_M3HairMaterial_get_specExponent1(self.raw.as_ptr()) }
10151    }
10152
10153    pub fn set_spec_exponent_1(&mut self, value: f32) {
10154        // SAFETY: plain scalar write through a live handle.
10155        unsafe { ffi::whiteout_m3_M3HairMaterial_set_specExponent1(self.raw.as_ptr(), value) }
10156    }
10157}
10158
10159impl Default for HairMaterial {
10160    fn default() -> Self {
10161        Self::new()
10162    }
10163}
10164
10165/// VON_ — Volume noise material (v0, 268 bytes)
10166///
10167/// Volumetric noise-based rendering material with animated density, falloff, scroll rate, position, scale, and rotation. Used for gas/smoke/cloud effects.
10168pub struct VolumeNoiseMaterial {
10169    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3VolumeNoiseMaterial>,
10170}
10171
10172impl Drop for VolumeNoiseMaterial {
10173    fn drop(&mut self) {
10174        // SAFETY: `raw` came from a native constructor and Drop runs once.
10175        unsafe { ffi::whiteout_m3_M3VolumeNoiseMaterial_delete(self.raw.as_ptr()) }
10176    }
10177}
10178
10179impl VolumeNoiseMaterial {
10180    /// # Safety
10181    /// `raw` must be a live handle this value takes ownership of.
10182    #[allow(dead_code)] // used by whichever methods return this type
10183    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3VolumeNoiseMaterial) -> Option<Self> {
10184        core::ptr::NonNull::new(raw).map(|raw| VolumeNoiseMaterial { raw })
10185    }
10186}
10187
10188// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
10189// is deliberately NOT implemented — the C++ types make no documented
10190// guarantee about concurrent use, and claiming one we haven't verified
10191// would be unsound. See `@bind thread_safe` in the plan.
10192unsafe impl Send for VolumeNoiseMaterial {}
10193
10194impl core::fmt::Debug for VolumeNoiseMaterial {
10195    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
10196        f.debug_struct("VolumeNoiseMaterial")
10197            .finish_non_exhaustive()
10198    }
10199}
10200
10201impl VolumeNoiseMaterial {
10202    /// # Panics
10203    /// Panics if the native allocation fails.
10204    pub fn new() -> Self {
10205        // SAFETY: the native constructor returns a live handle; a null here
10206        // means the library is unusable.
10207        unsafe {
10208            let raw = ffi::whiteout_m3_M3VolumeNoiseMaterial_new();
10209            Self::from_raw(raw).expect("native VolumeNoiseMaterial allocation failed")
10210        }
10211    }
10212
10213    /// Material name (`Ref<CHAR>`)
10214    pub fn name(&self) -> String {
10215        // SAFETY: the native side hands over an owned CString.
10216        unsafe {
10217            crate::support::take_string(ffi::whiteout_m3_M3VolumeNoiseMaterial_get_name(
10218                self.raw.as_ptr(),
10219            ))
10220        }
10221    }
10222
10223    pub fn set_name(&mut self, value: &str) {
10224        let value = std::ffi::CString::new(value).unwrap_or_default();
10225        // SAFETY: the pointer outlives the call.
10226        unsafe {
10227            ffi::whiteout_m3_M3VolumeNoiseMaterial_set_name(self.raw.as_ptr(), value.as_ptr())
10228        }
10229    }
10230
10231    /// Density falloff type
10232    pub fn falloff_type(&self) -> VolumeFalloffType {
10233        // SAFETY: scalar read; the discriminant is validated below.
10234        unsafe { ffi::whiteout_m3_M3VolumeNoiseMaterial_get_falloffType(self.raw.as_ptr()) }
10235            .try_into()
10236            .expect("unknown enum discriminant from the native library")
10237    }
10238
10239    pub fn set_falloff_type(&mut self, value: VolumeFalloffType) {
10240        // SAFETY: scalar write through a live handle.
10241        unsafe {
10242            ffi::whiteout_m3_M3VolumeNoiseMaterial_set_falloffType(self.raw.as_ptr(), value as i32)
10243        }
10244    }
10245
10246    /// Camera position mode (inside/outside)
10247    pub fn draw_transparency(&self) -> VolumeNoiseCameraMode {
10248        // SAFETY: scalar read; the discriminant is validated below.
10249        unsafe { ffi::whiteout_m3_M3VolumeNoiseMaterial_get_drawTransparency(self.raw.as_ptr()) }
10250            .try_into()
10251            .expect("unknown enum discriminant from the native library")
10252    }
10253
10254    pub fn set_draw_transparency(&mut self, value: VolumeNoiseCameraMode) {
10255        // SAFETY: scalar write through a live handle.
10256        unsafe {
10257            ffi::whiteout_m3_M3VolumeNoiseMaterial_set_drawTransparency(
10258                self.raw.as_ptr(),
10259                value as i32,
10260            )
10261        }
10262    }
10263
10264    /// Animated density
10265    /// Borrows the field in place — no copy, no allocation.
10266    pub fn density(&self) -> crate::support::Ref<'_, AnimRefF32> {
10267        // SAFETY: an interior pointer into `self`, valid for this
10268        // borrow and never freed by the `Ref`.
10269        unsafe {
10270            crate::support::Ref::new(AnimRefF32 {
10271                raw: core::ptr::NonNull::new_unchecked(
10272                    ffi::whiteout_m3_M3VolumeNoiseMaterial_get_density(self.raw.as_ptr()),
10273                ),
10274            })
10275        }
10276    }
10277
10278    pub fn density_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
10279        // SAFETY: as above; `&mut self` guarantees exclusivity.
10280        unsafe {
10281            crate::support::RefMut::new(AnimRefF32 {
10282                raw: core::ptr::NonNull::new_unchecked(
10283                    ffi::whiteout_m3_M3VolumeNoiseMaterial_get_density(self.raw.as_ptr()),
10284                ),
10285            })
10286        }
10287    }
10288
10289    /// Animated near-plane clip
10290    /// Borrows the field in place — no copy, no allocation.
10291    pub fn near_plane(&self) -> crate::support::Ref<'_, AnimRefF32> {
10292        // SAFETY: an interior pointer into `self`, valid for this
10293        // borrow and never freed by the `Ref`.
10294        unsafe {
10295            crate::support::Ref::new(AnimRefF32 {
10296                raw: core::ptr::NonNull::new_unchecked(
10297                    ffi::whiteout_m3_M3VolumeNoiseMaterial_get_nearPlane(self.raw.as_ptr()),
10298                ),
10299            })
10300        }
10301    }
10302
10303    pub fn near_plane_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
10304        // SAFETY: as above; `&mut self` guarantees exclusivity.
10305        unsafe {
10306            crate::support::RefMut::new(AnimRefF32 {
10307                raw: core::ptr::NonNull::new_unchecked(
10308                    ffi::whiteout_m3_M3VolumeNoiseMaterial_get_nearPlane(self.raw.as_ptr()),
10309                ),
10310            })
10311        }
10312    }
10313
10314    /// Animated falloff distance
10315    /// Borrows the field in place — no copy, no allocation.
10316    pub fn falloff(&self) -> crate::support::Ref<'_, AnimRefF32> {
10317        // SAFETY: an interior pointer into `self`, valid for this
10318        // borrow and never freed by the `Ref`.
10319        unsafe {
10320            crate::support::Ref::new(AnimRefF32 {
10321                raw: core::ptr::NonNull::new_unchecked(
10322                    ffi::whiteout_m3_M3VolumeNoiseMaterial_get_falloff(self.raw.as_ptr()),
10323                ),
10324            })
10325        }
10326    }
10327
10328    pub fn falloff_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
10329        // SAFETY: as above; `&mut self` guarantees exclusivity.
10330        unsafe {
10331            crate::support::RefMut::new(AnimRefF32 {
10332                raw: core::ptr::NonNull::new_unchecked(
10333                    ffi::whiteout_m3_M3VolumeNoiseMaterial_get_falloff(self.raw.as_ptr()),
10334                ),
10335            })
10336        }
10337    }
10338
10339    /// Animated noise scroll rate
10340    /// Borrows the field in place — no copy, no allocation.
10341    pub fn scroll_rate(&self) -> crate::support::Ref<'_, AnimRefVector3f> {
10342        // SAFETY: an interior pointer into `self`, valid for this
10343        // borrow and never freed by the `Ref`.
10344        unsafe {
10345            crate::support::Ref::new(AnimRefVector3f {
10346                raw: core::ptr::NonNull::new_unchecked(
10347                    ffi::whiteout_m3_M3VolumeNoiseMaterial_get_scrollRate(self.raw.as_ptr()),
10348                ),
10349            })
10350        }
10351    }
10352
10353    pub fn scroll_rate_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector3f> {
10354        // SAFETY: as above; `&mut self` guarantees exclusivity.
10355        unsafe {
10356            crate::support::RefMut::new(AnimRefVector3f {
10357                raw: core::ptr::NonNull::new_unchecked(
10358                    ffi::whiteout_m3_M3VolumeNoiseMaterial_get_scrollRate(self.raw.as_ptr()),
10359                ),
10360            })
10361        }
10362    }
10363
10364    /// Animated volume position
10365    /// Borrows the field in place — no copy, no allocation.
10366    pub fn position(&self) -> crate::support::Ref<'_, AnimRefVector3f> {
10367        // SAFETY: an interior pointer into `self`, valid for this
10368        // borrow and never freed by the `Ref`.
10369        unsafe {
10370            crate::support::Ref::new(AnimRefVector3f {
10371                raw: core::ptr::NonNull::new_unchecked(
10372                    ffi::whiteout_m3_M3VolumeNoiseMaterial_get_position(self.raw.as_ptr()),
10373                ),
10374            })
10375        }
10376    }
10377
10378    pub fn position_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector3f> {
10379        // SAFETY: as above; `&mut self` guarantees exclusivity.
10380        unsafe {
10381            crate::support::RefMut::new(AnimRefVector3f {
10382                raw: core::ptr::NonNull::new_unchecked(
10383                    ffi::whiteout_m3_M3VolumeNoiseMaterial_get_position(self.raw.as_ptr()),
10384                ),
10385            })
10386        }
10387    }
10388
10389    /// Animated volume scale
10390    /// Borrows the field in place — no copy, no allocation.
10391    pub fn scale(&self) -> crate::support::Ref<'_, AnimRefVector3f> {
10392        // SAFETY: an interior pointer into `self`, valid for this
10393        // borrow and never freed by the `Ref`.
10394        unsafe {
10395            crate::support::Ref::new(AnimRefVector3f {
10396                raw: core::ptr::NonNull::new_unchecked(
10397                    ffi::whiteout_m3_M3VolumeNoiseMaterial_get_scale(self.raw.as_ptr()),
10398                ),
10399            })
10400        }
10401    }
10402
10403    pub fn scale_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector3f> {
10404        // SAFETY: as above; `&mut self` guarantees exclusivity.
10405        unsafe {
10406            crate::support::RefMut::new(AnimRefVector3f {
10407                raw: core::ptr::NonNull::new_unchecked(
10408                    ffi::whiteout_m3_M3VolumeNoiseMaterial_get_scale(self.raw.as_ptr()),
10409                ),
10410            })
10411        }
10412    }
10413
10414    /// Animated volume rotation
10415    /// Borrows the field in place — no copy, no allocation.
10416    pub fn rotation(&self) -> crate::support::Ref<'_, AnimRefVector3f> {
10417        // SAFETY: an interior pointer into `self`, valid for this
10418        // borrow and never freed by the `Ref`.
10419        unsafe {
10420            crate::support::Ref::new(AnimRefVector3f {
10421                raw: core::ptr::NonNull::new_unchecked(
10422                    ffi::whiteout_m3_M3VolumeNoiseMaterial_get_rotation(self.raw.as_ptr()),
10423                ),
10424            })
10425        }
10426    }
10427
10428    pub fn rotation_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector3f> {
10429        // SAFETY: as above; `&mut self` guarantees exclusivity.
10430        unsafe {
10431            crate::support::RefMut::new(AnimRefVector3f {
10432                raw: core::ptr::NonNull::new_unchecked(
10433                    ffi::whiteout_m3_M3VolumeNoiseMaterial_get_rotation(self.raw.as_ptr()),
10434                ),
10435            })
10436        }
10437    }
10438
10439    /// Alpha test threshold
10440    pub fn alpha_threshold(&self) -> u32 {
10441        // SAFETY: plain scalar read through a live handle.
10442        unsafe { ffi::whiteout_m3_M3VolumeNoiseMaterial_get_alphaThreshold(self.raw.as_ptr()) }
10443    }
10444
10445    pub fn set_alpha_threshold(&mut self, value: u32) {
10446        // SAFETY: plain scalar write through a live handle.
10447        unsafe {
10448            ffi::whiteout_m3_M3VolumeNoiseMaterial_set_alphaThreshold(self.raw.as_ptr(), value)
10449        }
10450    }
10451
10452    /// Volume noise material flags
10453    pub fn flags(&self) -> VolumeNoiseMaterialFlag {
10454        // SAFETY: scalar read; the discriminant is validated below.
10455        unsafe { ffi::whiteout_m3_M3VolumeNoiseMaterial_get_flags(self.raw.as_ptr()) }
10456            .try_into()
10457            .expect("unknown enum discriminant from the native library")
10458    }
10459
10460    pub fn set_flags(&mut self, value: VolumeNoiseMaterialFlag) {
10461        // SAFETY: scalar write through a live handle.
10462        unsafe { ffi::whiteout_m3_M3VolumeNoiseMaterial_set_flags(self.raw.as_ptr(), value as i32) }
10463    }
10464}
10465
10466impl Default for VolumeNoiseMaterial {
10467    fn default() -> Self {
10468        Self::new()
10469    }
10470}
10471
10472/// CREP — Creep material (v0–v1, 28 bytes)
10473///
10474/// Material for Zerg creep rendering with a mask map and creep-low parameter.
10475pub struct CreepMaterial {
10476    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3CreepMaterial>,
10477}
10478
10479impl Drop for CreepMaterial {
10480    fn drop(&mut self) {
10481        // SAFETY: `raw` came from a native constructor and Drop runs once.
10482        unsafe { ffi::whiteout_m3_M3CreepMaterial_delete(self.raw.as_ptr()) }
10483    }
10484}
10485
10486impl CreepMaterial {
10487    /// # Safety
10488    /// `raw` must be a live handle this value takes ownership of.
10489    #[allow(dead_code)] // used by whichever methods return this type
10490    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3CreepMaterial) -> Option<Self> {
10491        core::ptr::NonNull::new(raw).map(|raw| CreepMaterial { raw })
10492    }
10493}
10494
10495// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
10496// is deliberately NOT implemented — the C++ types make no documented
10497// guarantee about concurrent use, and claiming one we haven't verified
10498// would be unsound. See `@bind thread_safe` in the plan.
10499unsafe impl Send for CreepMaterial {}
10500
10501impl core::fmt::Debug for CreepMaterial {
10502    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
10503        f.debug_struct("CreepMaterial").finish_non_exhaustive()
10504    }
10505}
10506
10507impl CreepMaterial {
10508    /// # Panics
10509    /// Panics if the native allocation fails.
10510    pub fn new() -> Self {
10511        // SAFETY: the native constructor returns a live handle; a null here
10512        // means the library is unusable.
10513        unsafe {
10514            let raw = ffi::whiteout_m3_M3CreepMaterial_new();
10515            Self::from_raw(raw).expect("native CreepMaterial allocation failed")
10516        }
10517    }
10518
10519    /// Material name (`Ref<CHAR>`)
10520    pub fn name(&self) -> String {
10521        // SAFETY: the native side hands over an owned CString.
10522        unsafe {
10523            crate::support::take_string(ffi::whiteout_m3_M3CreepMaterial_get_name(
10524                self.raw.as_ptr(),
10525            ))
10526        }
10527    }
10528
10529    pub fn set_name(&mut self, value: &str) {
10530        let value = std::ffi::CString::new(value).unwrap_or_default();
10531        // SAFETY: the pointer outlives the call.
10532        unsafe { ffi::whiteout_m3_M3CreepMaterial_set_name(self.raw.as_ptr(), value.as_ptr()) }
10533    }
10534
10535    /// Creep low parameter
10536    pub fn creep_low(&self) -> u32 {
10537        // SAFETY: plain scalar read through a live handle.
10538        unsafe { ffi::whiteout_m3_M3CreepMaterial_get_creepLow(self.raw.as_ptr()) }
10539    }
10540
10541    pub fn set_creep_low(&mut self, value: u32) {
10542        // SAFETY: plain scalar write through a live handle.
10543        unsafe { ffi::whiteout_m3_M3CreepMaterial_set_creepLow(self.raw.as_ptr(), value) }
10544    }
10545}
10546
10547impl Default for CreepMaterial {
10548    fn default() -> Self {
10549        Self::new()
10550    }
10551}
10552
10553/// STBM — Splat terrain bake material (v0, 48 bytes)
10554///
10555/// Material for baked terrain splat rendering with diffuse, normal, and specular texture layers.
10556pub struct STBMaterial {
10557    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3STBMaterial>,
10558}
10559
10560impl Drop for STBMaterial {
10561    fn drop(&mut self) {
10562        // SAFETY: `raw` came from a native constructor and Drop runs once.
10563        unsafe { ffi::whiteout_m3_M3STBMaterial_delete(self.raw.as_ptr()) }
10564    }
10565}
10566
10567impl STBMaterial {
10568    /// # Safety
10569    /// `raw` must be a live handle this value takes ownership of.
10570    #[allow(dead_code)] // used by whichever methods return this type
10571    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3STBMaterial) -> Option<Self> {
10572        core::ptr::NonNull::new(raw).map(|raw| STBMaterial { raw })
10573    }
10574}
10575
10576// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
10577// is deliberately NOT implemented — the C++ types make no documented
10578// guarantee about concurrent use, and claiming one we haven't verified
10579// would be unsound. See `@bind thread_safe` in the plan.
10580unsafe impl Send for STBMaterial {}
10581
10582impl core::fmt::Debug for STBMaterial {
10583    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
10584        f.debug_struct("STBMaterial").finish_non_exhaustive()
10585    }
10586}
10587
10588impl STBMaterial {
10589    /// # Panics
10590    /// Panics if the native allocation fails.
10591    pub fn new() -> Self {
10592        // SAFETY: the native constructor returns a live handle; a null here
10593        // means the library is unusable.
10594        unsafe {
10595            let raw = ffi::whiteout_m3_M3STBMaterial_new();
10596            Self::from_raw(raw).expect("native STBMaterial allocation failed")
10597        }
10598    }
10599
10600    /// Material name (`Ref<CHAR>`)
10601    pub fn name(&self) -> String {
10602        // SAFETY: the native side hands over an owned CString.
10603        unsafe {
10604            crate::support::take_string(ffi::whiteout_m3_M3STBMaterial_get_name(self.raw.as_ptr()))
10605        }
10606    }
10607
10608    pub fn set_name(&mut self, value: &str) {
10609        let value = std::ffi::CString::new(value).unwrap_or_default();
10610        // SAFETY: the pointer outlives the call.
10611        unsafe { ffi::whiteout_m3_M3STBMaterial_set_name(self.raw.as_ptr(), value.as_ptr()) }
10612    }
10613}
10614
10615impl Default for STBMaterial {
10616    fn default() -> Self {
10617        Self::new()
10618    }
10619}
10620
10621/// REF_ — Reflection material (v0–v3, 84–160 bytes)
10622///
10623/// Planar or cube-map reflection material with animated reflection/displacement strength, blur, and multiple texture layers.
10624pub struct ReflectionMaterial {
10625    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3ReflectionMaterial>,
10626}
10627
10628impl Drop for ReflectionMaterial {
10629    fn drop(&mut self) {
10630        // SAFETY: `raw` came from a native constructor and Drop runs once.
10631        unsafe { ffi::whiteout_m3_M3ReflectionMaterial_delete(self.raw.as_ptr()) }
10632    }
10633}
10634
10635impl ReflectionMaterial {
10636    /// # Safety
10637    /// `raw` must be a live handle this value takes ownership of.
10638    #[allow(dead_code)] // used by whichever methods return this type
10639    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3ReflectionMaterial) -> Option<Self> {
10640        core::ptr::NonNull::new(raw).map(|raw| ReflectionMaterial { raw })
10641    }
10642}
10643
10644// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
10645// is deliberately NOT implemented — the C++ types make no documented
10646// guarantee about concurrent use, and claiming one we haven't verified
10647// would be unsound. See `@bind thread_safe` in the plan.
10648unsafe impl Send for ReflectionMaterial {}
10649
10650impl core::fmt::Debug for ReflectionMaterial {
10651    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
10652        f.debug_struct("ReflectionMaterial").finish_non_exhaustive()
10653    }
10654}
10655
10656impl ReflectionMaterial {
10657    /// # Panics
10658    /// Panics if the native allocation fails.
10659    pub fn new() -> Self {
10660        // SAFETY: the native constructor returns a live handle; a null here
10661        // means the library is unusable.
10662        unsafe {
10663            let raw = ffi::whiteout_m3_M3ReflectionMaterial_new();
10664            Self::from_raw(raw).expect("native ReflectionMaterial allocation failed")
10665        }
10666    }
10667
10668    /// Material name (`Ref<CHAR>`)
10669    pub fn name(&self) -> String {
10670        // SAFETY: the native side hands over an owned CString.
10671        unsafe {
10672            crate::support::take_string(ffi::whiteout_m3_M3ReflectionMaterial_get_name(
10673                self.raw.as_ptr(),
10674            ))
10675        }
10676    }
10677
10678    pub fn set_name(&mut self, value: &str) {
10679        let value = std::ffi::CString::new(value).unwrap_or_default();
10680        // SAFETY: the pointer outlives the call.
10681        unsafe { ffi::whiteout_m3_M3ReflectionMaterial_set_name(self.raw.as_ptr(), value.as_ptr()) }
10682    }
10683
10684    /// Unknown field
10685    pub fn unknown(&self) -> u32 {
10686        // SAFETY: plain scalar read through a live handle.
10687        unsafe { ffi::whiteout_m3_M3ReflectionMaterial_get_unknown(self.raw.as_ptr()) }
10688    }
10689
10690    pub fn set_unknown(&mut self, value: u32) {
10691        // SAFETY: plain scalar write through a live handle.
10692        unsafe { ffi::whiteout_m3_M3ReflectionMaterial_set_unknown(self.raw.as_ptr(), value) }
10693    }
10694
10695    /// Animated reflection strength (v2+)
10696    /// Borrows the field in place — no copy, no allocation.
10697    pub fn reflection_strength(&self) -> crate::support::Ref<'_, AnimRefF32> {
10698        // SAFETY: an interior pointer into `self`, valid for this
10699        // borrow and never freed by the `Ref`.
10700        unsafe {
10701            crate::support::Ref::new(AnimRefF32 {
10702                raw: core::ptr::NonNull::new_unchecked(
10703                    ffi::whiteout_m3_M3ReflectionMaterial_get_reflectionStrength(self.raw.as_ptr()),
10704                ),
10705            })
10706        }
10707    }
10708
10709    pub fn reflection_strength_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
10710        // SAFETY: as above; `&mut self` guarantees exclusivity.
10711        unsafe {
10712            crate::support::RefMut::new(AnimRefF32 {
10713                raw: core::ptr::NonNull::new_unchecked(
10714                    ffi::whiteout_m3_M3ReflectionMaterial_get_reflectionStrength(self.raw.as_ptr()),
10715                ),
10716            })
10717        }
10718    }
10719
10720    /// Animated displacement strength (v2+)
10721    /// Borrows the field in place — no copy, no allocation.
10722    pub fn displacement_strength(&self) -> crate::support::Ref<'_, AnimRefF32> {
10723        // SAFETY: an interior pointer into `self`, valid for this
10724        // borrow and never freed by the `Ref`.
10725        unsafe {
10726            crate::support::Ref::new(AnimRefF32 {
10727                raw: core::ptr::NonNull::new_unchecked(
10728                    ffi::whiteout_m3_M3ReflectionMaterial_get_displacementStrength(
10729                        self.raw.as_ptr(),
10730                    ),
10731                ),
10732            })
10733        }
10734    }
10735
10736    pub fn displacement_strength_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
10737        // SAFETY: as above; `&mut self` guarantees exclusivity.
10738        unsafe {
10739            crate::support::RefMut::new(AnimRefF32 {
10740                raw: core::ptr::NonNull::new_unchecked(
10741                    ffi::whiteout_m3_M3ReflectionMaterial_get_displacementStrength(
10742                        self.raw.as_ptr(),
10743                    ),
10744                ),
10745            })
10746        }
10747    }
10748
10749    /// Animated reflection offset (v2+)
10750    /// Borrows the field in place — no copy, no allocation.
10751    pub fn reflection_offset(&self) -> crate::support::Ref<'_, AnimRefF32> {
10752        // SAFETY: an interior pointer into `self`, valid for this
10753        // borrow and never freed by the `Ref`.
10754        unsafe {
10755            crate::support::Ref::new(AnimRefF32 {
10756                raw: core::ptr::NonNull::new_unchecked(
10757                    ffi::whiteout_m3_M3ReflectionMaterial_get_reflectionOffset(self.raw.as_ptr()),
10758                ),
10759            })
10760        }
10761    }
10762
10763    pub fn reflection_offset_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
10764        // SAFETY: as above; `&mut self` guarantees exclusivity.
10765        unsafe {
10766            crate::support::RefMut::new(AnimRefF32 {
10767                raw: core::ptr::NonNull::new_unchecked(
10768                    ffi::whiteout_m3_M3ReflectionMaterial_get_reflectionOffset(self.raw.as_ptr()),
10769                ),
10770            })
10771        }
10772    }
10773
10774    /// Animated blur angle (v2+)
10775    /// Borrows the field in place — no copy, no allocation.
10776    pub fn blur_angle(&self) -> crate::support::Ref<'_, AnimRefF32> {
10777        // SAFETY: an interior pointer into `self`, valid for this
10778        // borrow and never freed by the `Ref`.
10779        unsafe {
10780            crate::support::Ref::new(AnimRefF32 {
10781                raw: core::ptr::NonNull::new_unchecked(
10782                    ffi::whiteout_m3_M3ReflectionMaterial_get_blurAngle(self.raw.as_ptr()),
10783                ),
10784            })
10785        }
10786    }
10787
10788    pub fn blur_angle_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
10789        // SAFETY: as above; `&mut self` guarantees exclusivity.
10790        unsafe {
10791            crate::support::RefMut::new(AnimRefF32 {
10792                raw: core::ptr::NonNull::new_unchecked(
10793                    ffi::whiteout_m3_M3ReflectionMaterial_get_blurAngle(self.raw.as_ptr()),
10794                ),
10795            })
10796        }
10797    }
10798
10799    /// Animated max blur distance (v2+)
10800    /// Borrows the field in place — no copy, no allocation.
10801    pub fn blur_distance_max(&self) -> crate::support::Ref<'_, AnimRefF32> {
10802        // SAFETY: an interior pointer into `self`, valid for this
10803        // borrow and never freed by the `Ref`.
10804        unsafe {
10805            crate::support::Ref::new(AnimRefF32 {
10806                raw: core::ptr::NonNull::new_unchecked(
10807                    ffi::whiteout_m3_M3ReflectionMaterial_get_blurDistanceMax(self.raw.as_ptr()),
10808                ),
10809            })
10810        }
10811    }
10812
10813    pub fn blur_distance_max_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
10814        // SAFETY: as above; `&mut self` guarantees exclusivity.
10815        unsafe {
10816            crate::support::RefMut::new(AnimRefF32 {
10817                raw: core::ptr::NonNull::new_unchecked(
10818                    ffi::whiteout_m3_M3ReflectionMaterial_get_blurDistanceMax(self.raw.as_ptr()),
10819                ),
10820            })
10821        }
10822    }
10823
10824    /// Reflection flags (v2+)
10825    pub fn flags(&self) -> ReflectionMaterialFlag {
10826        // SAFETY: scalar read; a flag set accepts any bits.
10827        ReflectionMaterialFlag(unsafe {
10828            ffi::whiteout_m3_M3ReflectionMaterial_get_flags(self.raw.as_ptr())
10829        })
10830    }
10831
10832    pub fn set_flags(&mut self, value: ReflectionMaterialFlag) {
10833        // SAFETY: scalar write through a live handle.
10834        unsafe { ffi::whiteout_m3_M3ReflectionMaterial_set_flags(self.raw.as_ptr(), value.0) }
10835    }
10836
10837    /// Unknown field
10838    pub fn unknown_2(&self) -> u32 {
10839        // SAFETY: plain scalar read through a live handle.
10840        unsafe { ffi::whiteout_m3_M3ReflectionMaterial_get_unknown2(self.raw.as_ptr()) }
10841    }
10842
10843    pub fn set_unknown_2(&mut self, value: u32) {
10844        // SAFETY: plain scalar write through a live handle.
10845        unsafe { ffi::whiteout_m3_M3ReflectionMaterial_set_unknown2(self.raw.as_ptr(), value) }
10846    }
10847}
10848
10849impl Default for ReflectionMaterial {
10850    fn default() -> Self {
10851        Self::new()
10852    }
10853}
10854
10855/// LFSB — Sub-flare element (v0–v2, 56 bytes)
10856///
10857/// A single flare element within a LensFlare material, with position, size, scale, fade, color, and offset parameters.
10858pub struct SubFlare {
10859    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3SubFlare>,
10860}
10861
10862impl Drop for SubFlare {
10863    fn drop(&mut self) {
10864        // SAFETY: `raw` came from a native constructor and Drop runs once.
10865        unsafe { ffi::whiteout_m3_M3SubFlare_delete(self.raw.as_ptr()) }
10866    }
10867}
10868
10869impl SubFlare {
10870    /// # Safety
10871    /// `raw` must be a live handle this value takes ownership of.
10872    #[allow(dead_code)] // used by whichever methods return this type
10873    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3SubFlare) -> Option<Self> {
10874        core::ptr::NonNull::new(raw).map(|raw| SubFlare { raw })
10875    }
10876}
10877
10878// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
10879// is deliberately NOT implemented — the C++ types make no documented
10880// guarantee about concurrent use, and claiming one we haven't verified
10881// would be unsound. See `@bind thread_safe` in the plan.
10882unsafe impl Send for SubFlare {}
10883
10884impl core::fmt::Debug for SubFlare {
10885    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
10886        f.debug_struct("SubFlare").finish_non_exhaustive()
10887    }
10888}
10889
10890impl SubFlare {
10891    /// # Panics
10892    /// Panics if the native allocation fails.
10893    pub fn new() -> Self {
10894        // SAFETY: the native constructor returns a live handle; a null here
10895        // means the library is unusable.
10896        unsafe {
10897            let raw = ffi::whiteout_m3_M3SubFlare_new();
10898            Self::from_raw(raw).expect("native SubFlare allocation failed")
10899        }
10900    }
10901
10902    /// Flare element index
10903    pub fn index(&self) -> u32 {
10904        // SAFETY: plain scalar read through a live handle.
10905        unsafe { ffi::whiteout_m3_M3SubFlare_get_index(self.raw.as_ptr()) }
10906    }
10907
10908    pub fn set_index(&mut self, value: u32) {
10909        // SAFETY: plain scalar write through a live handle.
10910        unsafe { ffi::whiteout_m3_M3SubFlare_set_index(self.raw.as_ptr(), value) }
10911    }
10912
10913    /// Position along the flare axis (0–1)
10914    pub fn position(&self) -> f32 {
10915        // SAFETY: plain scalar read through a live handle.
10916        unsafe { ffi::whiteout_m3_M3SubFlare_get_position(self.raw.as_ptr()) }
10917    }
10918
10919    pub fn set_position(&mut self, value: f32) {
10920        // SAFETY: plain scalar write through a live handle.
10921        unsafe { ffi::whiteout_m3_M3SubFlare_set_position(self.raw.as_ptr(), value) }
10922    }
10923
10924    /// Base size (width, height)
10925    pub fn size_xy(&self) -> crate::math::Vector2f {
10926        // SAFETY: the getter returns an interior pointer to a
10927        // layout-identical POD; we copy it out immediately.
10928        unsafe {
10929            *(ffi::whiteout_m3_M3SubFlare_get_sizeXY(self.raw.as_ptr())
10930                as *const crate::math::Vector2f)
10931        }
10932    }
10933
10934    pub fn set_size_xy(&mut self, value: crate::math::Vector2f) {
10935        // SAFETY: as above, in the other direction.
10936        unsafe {
10937            ffi::whiteout_m3_M3SubFlare_set_sizeXY(
10938                self.raw.as_ptr(),
10939                &value as *const crate::math::Vector2f as *const _,
10940            )
10941        }
10942    }
10943
10944    /// Scale multiplier (width, height)
10945    pub fn scale_xy(&self) -> crate::math::Vector2f {
10946        // SAFETY: the getter returns an interior pointer to a
10947        // layout-identical POD; we copy it out immediately.
10948        unsafe {
10949            *(ffi::whiteout_m3_M3SubFlare_get_scaleXY(self.raw.as_ptr())
10950                as *const crate::math::Vector2f)
10951        }
10952    }
10953
10954    pub fn set_scale_xy(&mut self, value: crate::math::Vector2f) {
10955        // SAFETY: as above, in the other direction.
10956        unsafe {
10957            ffi::whiteout_m3_M3SubFlare_set_scaleXY(
10958                self.raw.as_ptr(),
10959                &value as *const crate::math::Vector2f as *const _,
10960            )
10961        }
10962    }
10963
10964    /// Fade-in range (start, end)
10965    pub fn fade_in(&self) -> crate::math::Vector2f {
10966        // SAFETY: the getter returns an interior pointer to a
10967        // layout-identical POD; we copy it out immediately.
10968        unsafe {
10969            *(ffi::whiteout_m3_M3SubFlare_get_fadeIn(self.raw.as_ptr())
10970                as *const crate::math::Vector2f)
10971        }
10972    }
10973
10974    pub fn set_fade_in(&mut self, value: crate::math::Vector2f) {
10975        // SAFETY: as above, in the other direction.
10976        unsafe {
10977            ffi::whiteout_m3_M3SubFlare_set_fadeIn(
10978                self.raw.as_ptr(),
10979                &value as *const crate::math::Vector2f as *const _,
10980            )
10981        }
10982    }
10983
10984    /// Fade-out range (start, end)
10985    pub fn fade_out(&self) -> crate::math::Vector2f {
10986        // SAFETY: the getter returns an interior pointer to a
10987        // layout-identical POD; we copy it out immediately.
10988        unsafe {
10989            *(ffi::whiteout_m3_M3SubFlare_get_fadeOut(self.raw.as_ptr())
10990                as *const crate::math::Vector2f)
10991        }
10992    }
10993
10994    pub fn set_fade_out(&mut self, value: crate::math::Vector2f) {
10995        // SAFETY: as above, in the other direction.
10996        unsafe {
10997            ffi::whiteout_m3_M3SubFlare_set_fadeOut(
10998                self.raw.as_ptr(),
10999                &value as *const crate::math::Vector2f as *const _,
11000            )
11001        }
11002    }
11003
11004    /// Flare color and alpha
11005    /// Borrows the field in place — no copy, no allocation.
11006    pub fn color_alpha(&self) -> crate::support::Ref<'_, ColorBGRA> {
11007        // SAFETY: an interior pointer into `self`, valid for this
11008        // borrow and never freed by the `Ref`.
11009        unsafe {
11010            crate::support::Ref::new(ColorBGRA {
11011                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3SubFlare_get_colorAlpha(
11012                    self.raw.as_ptr(),
11013                )),
11014            })
11015        }
11016    }
11017
11018    pub fn color_alpha_mut(&mut self) -> crate::support::RefMut<'_, ColorBGRA> {
11019        // SAFETY: as above; `&mut self` guarantees exclusivity.
11020        unsafe {
11021            crate::support::RefMut::new(ColorBGRA {
11022                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3SubFlare_get_colorAlpha(
11023                    self.raw.as_ptr(),
11024                )),
11025            })
11026        }
11027    }
11028
11029    /// Whether to face the flare center
11030    pub fn face_center(&self) -> u32 {
11031        // SAFETY: plain scalar read through a live handle.
11032        unsafe { ffi::whiteout_m3_M3SubFlare_get_faceCenter(self.raw.as_ptr()) }
11033    }
11034
11035    pub fn set_face_center(&mut self, value: u32) {
11036        // SAFETY: plain scalar write through a live handle.
11037        unsafe { ffi::whiteout_m3_M3SubFlare_set_faceCenter(self.raw.as_ptr(), value) }
11038    }
11039
11040    /// Offset from flare center
11041    pub fn offset(&self) -> crate::math::Vector2f {
11042        // SAFETY: the getter returns an interior pointer to a
11043        // layout-identical POD; we copy it out immediately.
11044        unsafe {
11045            *(ffi::whiteout_m3_M3SubFlare_get_offset(self.raw.as_ptr())
11046                as *const crate::math::Vector2f)
11047        }
11048    }
11049
11050    pub fn set_offset(&mut self, value: crate::math::Vector2f) {
11051        // SAFETY: as above, in the other direction.
11052        unsafe {
11053            ffi::whiteout_m3_M3SubFlare_set_offset(
11054                self.raw.as_ptr(),
11055                &value as *const crate::math::Vector2f as *const _,
11056            )
11057        }
11058    }
11059}
11060
11061impl Default for SubFlare {
11062    fn default() -> Self {
11063        Self::new()
11064    }
11065}
11066
11067/// LFLR — Lens flare material (v0–v3, 152 bytes)
11068///
11069/// Lens flare effect with animated intensity, color, HDR, size, sub-flare elements, and flipbook texture grid parameters.
11070pub struct LensFlare {
11071    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3LensFlare>,
11072}
11073
11074impl Drop for LensFlare {
11075    fn drop(&mut self) {
11076        // SAFETY: `raw` came from a native constructor and Drop runs once.
11077        unsafe { ffi::whiteout_m3_M3LensFlare_delete(self.raw.as_ptr()) }
11078    }
11079}
11080
11081impl LensFlare {
11082    /// # Safety
11083    /// `raw` must be a live handle this value takes ownership of.
11084    #[allow(dead_code)] // used by whichever methods return this type
11085    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3LensFlare) -> Option<Self> {
11086        core::ptr::NonNull::new(raw).map(|raw| LensFlare { raw })
11087    }
11088}
11089
11090// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
11091// is deliberately NOT implemented — the C++ types make no documented
11092// guarantee about concurrent use, and claiming one we haven't verified
11093// would be unsound. See `@bind thread_safe` in the plan.
11094unsafe impl Send for LensFlare {}
11095
11096impl core::fmt::Debug for LensFlare {
11097    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
11098        f.debug_struct("LensFlare").finish_non_exhaustive()
11099    }
11100}
11101
11102impl LensFlare {
11103    /// # Panics
11104    /// Panics if the native allocation fails.
11105    pub fn new() -> Self {
11106        // SAFETY: the native constructor returns a live handle; a null here
11107        // means the library is unusable.
11108        unsafe {
11109            let raw = ffi::whiteout_m3_M3LensFlare_new();
11110            Self::from_raw(raw).expect("native LensFlare allocation failed")
11111        }
11112    }
11113
11114    /// Flare name (`Ref<CHAR>`)
11115    pub fn name(&self) -> String {
11116        // SAFETY: the native side hands over an owned CString.
11117        unsafe {
11118            crate::support::take_string(ffi::whiteout_m3_M3LensFlare_get_name(self.raw.as_ptr()))
11119        }
11120    }
11121
11122    pub fn set_name(&mut self, value: &str) {
11123        let value = std::ffi::CString::new(value).unwrap_or_default();
11124        // SAFETY: the pointer outlives the call.
11125        unsafe { ffi::whiteout_m3_M3LensFlare_set_name(self.raw.as_ptr(), value.as_ptr()) }
11126    }
11127
11128    /// Sub-flare elements (LFSB)
11129    pub fn sub_flares_len(&self) -> usize {
11130        // SAFETY: scalar read through a live handle.
11131        unsafe { ffi::whiteout_m3_M3LensFlare_get_subFlares_count(self.raw.as_ptr()) }
11132    }
11133
11134    /// Borrows element `index` in place. `None` when out of range.
11135    pub fn sub_flares(&self, index: usize) -> Option<crate::support::Ref<'_, SubFlare>> {
11136        if index >= self.sub_flares_len() {
11137            return None;
11138        }
11139        // SAFETY: index checked above; the pointer is interior to `self`.
11140        unsafe {
11141            Some(crate::support::Ref::new(SubFlare {
11142                raw: core::ptr::NonNull::new_unchecked(
11143                    ffi::whiteout_m3_M3LensFlare_get_subFlares_at(self.raw.as_ptr(), index),
11144                ),
11145            }))
11146        }
11147    }
11148
11149    pub fn sub_flares_mut(&mut self, index: usize) -> Option<crate::support::RefMut<'_, SubFlare>> {
11150        if index >= self.sub_flares_len() {
11151            return None;
11152        }
11153        // SAFETY: as above; `&mut self` guarantees exclusivity.
11154        unsafe {
11155            Some(crate::support::RefMut::new(SubFlare {
11156                raw: core::ptr::NonNull::new_unchecked(
11157                    ffi::whiteout_m3_M3LensFlare_get_subFlares_at(self.raw.as_ptr(), index),
11158                ),
11159            }))
11160        }
11161    }
11162
11163    /// Iterate the elements, borrowing each in turn.
11164    pub fn sub_flares_iter(
11165        &self,
11166    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, SubFlare>> {
11167        (0..self.sub_flares_len()).map(move |i| self.sub_flares(i).expect("index below len"))
11168    }
11169
11170    pub fn resize_sub_flares(&mut self, count: usize) {
11171        // SAFETY: exclusive access, so no borrow is outstanding.
11172        unsafe { ffi::whiteout_m3_M3LensFlare_resize_subFlares(self.raw.as_ptr(), count) }
11173    }
11174
11175    /// Flipbook grid columns
11176    pub fn columns(&self) -> u32 {
11177        // SAFETY: plain scalar read through a live handle.
11178        unsafe { ffi::whiteout_m3_M3LensFlare_get_columns(self.raw.as_ptr()) }
11179    }
11180
11181    pub fn set_columns(&mut self, value: u32) {
11182        // SAFETY: plain scalar write through a live handle.
11183        unsafe { ffi::whiteout_m3_M3LensFlare_set_columns(self.raw.as_ptr(), value) }
11184    }
11185
11186    /// Flipbook grid rows
11187    pub fn rows(&self) -> u32 {
11188        // SAFETY: plain scalar read through a live handle.
11189        unsafe { ffi::whiteout_m3_M3LensFlare_get_rows(self.raw.as_ptr()) }
11190    }
11191
11192    pub fn set_rows(&mut self, value: u32) {
11193        // SAFETY: plain scalar write through a live handle.
11194        unsafe { ffi::whiteout_m3_M3LensFlare_set_rows(self.raw.as_ptr(), value) }
11195    }
11196
11197    /// Distance fade start
11198    pub fn distance_fade(&self) -> f32 {
11199        // SAFETY: plain scalar read through a live handle.
11200        unsafe { ffi::whiteout_m3_M3LensFlare_get_distanceFade(self.raw.as_ptr()) }
11201    }
11202
11203    pub fn set_distance_fade(&mut self, value: f32) {
11204        // SAFETY: plain scalar write through a live handle.
11205        unsafe { ffi::whiteout_m3_M3LensFlare_set_distanceFade(self.raw.as_ptr(), value) }
11206    }
11207
11208    /// Library name (`Ref<CHAR>`)
11209    pub fn lib_name(&self) -> String {
11210        // SAFETY: the native side hands over an owned CString.
11211        unsafe {
11212            crate::support::take_string(ffi::whiteout_m3_M3LensFlare_get_libName(self.raw.as_ptr()))
11213        }
11214    }
11215
11216    pub fn set_lib_name(&mut self, value: &str) {
11217        let value = std::ffi::CString::new(value).unwrap_or_default();
11218        // SAFETY: the pointer outlives the call.
11219        unsafe { ffi::whiteout_m3_M3LensFlare_set_libName(self.raw.as_ptr(), value.as_ptr()) }
11220    }
11221
11222    /// Animated intensity
11223    /// Borrows the field in place — no copy, no allocation.
11224    pub fn intensity(&self) -> crate::support::Ref<'_, AnimRefF32> {
11225        // SAFETY: an interior pointer into `self`, valid for this
11226        // borrow and never freed by the `Ref`.
11227        unsafe {
11228            crate::support::Ref::new(AnimRefF32 {
11229                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3LensFlare_get_intensity(
11230                    self.raw.as_ptr(),
11231                )),
11232            })
11233        }
11234    }
11235
11236    pub fn intensity_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
11237        // SAFETY: as above; `&mut self` guarantees exclusivity.
11238        unsafe {
11239            crate::support::RefMut::new(AnimRefF32 {
11240                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3LensFlare_get_intensity(
11241                    self.raw.as_ptr(),
11242                )),
11243            })
11244        }
11245    }
11246
11247    /// Animated color
11248    /// Borrows the field in place — no copy, no allocation.
11249    pub fn color(&self) -> crate::support::Ref<'_, AnimRefM3ColorBGRA> {
11250        // SAFETY: an interior pointer into `self`, valid for this
11251        // borrow and never freed by the `Ref`.
11252        unsafe {
11253            crate::support::Ref::new(AnimRefM3ColorBGRA {
11254                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3LensFlare_get_color(
11255                    self.raw.as_ptr(),
11256                )),
11257            })
11258        }
11259    }
11260
11261    pub fn color_mut(&mut self) -> crate::support::RefMut<'_, AnimRefM3ColorBGRA> {
11262        // SAFETY: as above; `&mut self` guarantees exclusivity.
11263        unsafe {
11264            crate::support::RefMut::new(AnimRefM3ColorBGRA {
11265                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3LensFlare_get_color(
11266                    self.raw.as_ptr(),
11267                )),
11268            })
11269        }
11270    }
11271
11272    /// Animated HDR multiplier
11273    /// Borrows the field in place — no copy, no allocation.
11274    pub fn hdr(&self) -> crate::support::Ref<'_, AnimRefF32> {
11275        // SAFETY: an interior pointer into `self`, valid for this
11276        // borrow and never freed by the `Ref`.
11277        unsafe {
11278            crate::support::Ref::new(AnimRefF32 {
11279                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3LensFlare_get_hdr(
11280                    self.raw.as_ptr(),
11281                )),
11282            })
11283        }
11284    }
11285
11286    pub fn hdr_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
11287        // SAFETY: as above; `&mut self` guarantees exclusivity.
11288        unsafe {
11289            crate::support::RefMut::new(AnimRefF32 {
11290                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3LensFlare_get_hdr(
11291                    self.raw.as_ptr(),
11292                )),
11293            })
11294        }
11295    }
11296
11297    /// Animated size
11298    /// Borrows the field in place — no copy, no allocation.
11299    pub fn size(&self) -> crate::support::Ref<'_, AnimRefF32> {
11300        // SAFETY: an interior pointer into `self`, valid for this
11301        // borrow and never freed by the `Ref`.
11302        unsafe {
11303            crate::support::Ref::new(AnimRefF32 {
11304                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3LensFlare_get_size(
11305                    self.raw.as_ptr(),
11306                )),
11307            })
11308        }
11309    }
11310
11311    pub fn size_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
11312        // SAFETY: as above; `&mut self` guarantees exclusivity.
11313        unsafe {
11314            crate::support::RefMut::new(AnimRefF32 {
11315                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3LensFlare_get_size(
11316                    self.raw.as_ptr(),
11317                )),
11318            })
11319        }
11320    }
11321}
11322
11323impl Default for LensFlare {
11324    fn default() -> Self {
11325        Self::new()
11326    }
11327}
11328
11329/// MADD — Material additional data (v0–v3, 140–160 bytes)
11330///
11331/// Buffer-style material extension storing key–value pairs, hashes, and animation parameters. Added in MODL v30.
11332pub struct MaterialAddData {
11333    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3MaterialAddData>,
11334}
11335
11336impl Drop for MaterialAddData {
11337    fn drop(&mut self) {
11338        // SAFETY: `raw` came from a native constructor and Drop runs once.
11339        unsafe { ffi::whiteout_m3_M3MaterialAddData_delete(self.raw.as_ptr()) }
11340    }
11341}
11342
11343impl MaterialAddData {
11344    /// # Safety
11345    /// `raw` must be a live handle this value takes ownership of.
11346    #[allow(dead_code)] // used by whichever methods return this type
11347    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3MaterialAddData) -> Option<Self> {
11348        core::ptr::NonNull::new(raw).map(|raw| MaterialAddData { raw })
11349    }
11350}
11351
11352// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
11353// is deliberately NOT implemented — the C++ types make no documented
11354// guarantee about concurrent use, and claiming one we haven't verified
11355// would be unsound. See `@bind thread_safe` in the plan.
11356unsafe impl Send for MaterialAddData {}
11357
11358impl core::fmt::Debug for MaterialAddData {
11359    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
11360        f.debug_struct("MaterialAddData").finish_non_exhaustive()
11361    }
11362}
11363
11364impl MaterialAddData {
11365    /// # Panics
11366    /// Panics if the native allocation fails.
11367    pub fn new() -> Self {
11368        // SAFETY: the native constructor returns a live handle; a null here
11369        // means the library is unusable.
11370        unsafe {
11371            let raw = ffi::whiteout_m3_M3MaterialAddData_new();
11372            Self::from_raw(raw).expect("native MaterialAddData allocation failed")
11373        }
11374    }
11375
11376    /// Key name (`Ref<CHAR>`)
11377    pub fn key_name(&self) -> String {
11378        // SAFETY: the native side hands over an owned CString.
11379        unsafe {
11380            crate::support::take_string(ffi::whiteout_m3_M3MaterialAddData_get_keyName(
11381                self.raw.as_ptr(),
11382            ))
11383        }
11384    }
11385
11386    pub fn set_key_name(&mut self, value: &str) {
11387        let value = std::ffi::CString::new(value).unwrap_or_default();
11388        // SAFETY: the pointer outlives the call.
11389        unsafe { ffi::whiteout_m3_M3MaterialAddData_set_keyName(self.raw.as_ptr(), value.as_ptr()) }
11390    }
11391
11392    /// Key hash values (U32_)
11393    /// Zero-copy view of the underlying `std::vector`.
11394    pub fn key_hash(&self) -> &[u32] {
11395        // SAFETY: `_data`/`_count` describe one contiguous C++
11396        // allocation, borrowed for as long as `self` is.
11397        unsafe {
11398            let n = ffi::whiteout_m3_M3MaterialAddData_get_keyHash_count(self.raw.as_ptr());
11399            let p = ffi::whiteout_m3_M3MaterialAddData_get_keyHash_data(self.raw.as_ptr());
11400            if p.is_null() || n == 0 {
11401                &[]
11402            } else {
11403                core::slice::from_raw_parts(p, n)
11404            }
11405        }
11406    }
11407
11408    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
11409    pub fn key_hash_mut(&mut self) -> &mut [u32] {
11410        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
11411        unsafe {
11412            let n = ffi::whiteout_m3_M3MaterialAddData_get_keyHash_count(self.raw.as_ptr());
11413            let p =
11414                ffi::whiteout_m3_M3MaterialAddData_get_keyHash_data(self.raw.as_ptr()) as *mut u32;
11415            if p.is_null() || n == 0 {
11416                &mut []
11417            } else {
11418                core::slice::from_raw_parts_mut(p, n)
11419            }
11420        }
11421    }
11422
11423    pub fn set_key_hash(&mut self, values: &[u32]) {
11424        // SAFETY: the native side copies `values` before returning.
11425        unsafe {
11426            ffi::whiteout_m3_M3MaterialAddData_assign_keyHash(
11427                self.raw.as_ptr(),
11428                values.as_ptr() as *const _,
11429                values.len(),
11430            )
11431        }
11432    }
11433
11434    pub fn resize_key_hash(&mut self, count: usize) {
11435        // SAFETY: reallocation is safe here precisely because
11436        // `&mut self` means no slice borrow is outstanding.
11437        unsafe { ffi::whiteout_m3_M3MaterialAddData_resize_keyHash(self.raw.as_ptr(), count) }
11438    }
11439
11440    /// Extra hash values (U32_, v2+)
11441    /// Zero-copy view of the underlying `std::vector`.
11442    pub fn extra_hash(&self) -> &[u32] {
11443        // SAFETY: `_data`/`_count` describe one contiguous C++
11444        // allocation, borrowed for as long as `self` is.
11445        unsafe {
11446            let n = ffi::whiteout_m3_M3MaterialAddData_get_extraHash_count(self.raw.as_ptr());
11447            let p = ffi::whiteout_m3_M3MaterialAddData_get_extraHash_data(self.raw.as_ptr());
11448            if p.is_null() || n == 0 {
11449                &[]
11450            } else {
11451                core::slice::from_raw_parts(p, n)
11452            }
11453        }
11454    }
11455
11456    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
11457    pub fn extra_hash_mut(&mut self) -> &mut [u32] {
11458        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
11459        unsafe {
11460            let n = ffi::whiteout_m3_M3MaterialAddData_get_extraHash_count(self.raw.as_ptr());
11461            let p = ffi::whiteout_m3_M3MaterialAddData_get_extraHash_data(self.raw.as_ptr())
11462                as *mut u32;
11463            if p.is_null() || n == 0 {
11464                &mut []
11465            } else {
11466                core::slice::from_raw_parts_mut(p, n)
11467            }
11468        }
11469    }
11470
11471    pub fn set_extra_hash(&mut self, values: &[u32]) {
11472        // SAFETY: the native side copies `values` before returning.
11473        unsafe {
11474            ffi::whiteout_m3_M3MaterialAddData_assign_extraHash(
11475                self.raw.as_ptr(),
11476                values.as_ptr() as *const _,
11477                values.len(),
11478            )
11479        }
11480    }
11481
11482    pub fn resize_extra_hash(&mut self, count: usize) {
11483        // SAFETY: reallocation is safe here precisely because
11484        // `&mut self` means no slice borrow is outstanding.
11485        unsafe { ffi::whiteout_m3_M3MaterialAddData_resize_extraHash(self.raw.as_ptr(), count) }
11486    }
11487
11488    /// Value file path (`Ref<CHAR>`)
11489    pub fn value_path(&self) -> String {
11490        // SAFETY: the native side hands over an owned CString.
11491        unsafe {
11492            crate::support::take_string(ffi::whiteout_m3_M3MaterialAddData_get_valuePath(
11493                self.raw.as_ptr(),
11494            ))
11495        }
11496    }
11497
11498    pub fn set_value_path(&mut self, value: &str) {
11499        let value = std::ffi::CString::new(value).unwrap_or_default();
11500        // SAFETY: the pointer outlives the call.
11501        unsafe {
11502            ffi::whiteout_m3_M3MaterialAddData_set_valuePath(self.raw.as_ptr(), value.as_ptr())
11503        }
11504    }
11505
11506    /// Animation frequency
11507    pub fn frequency(&self) -> f32 {
11508        // SAFETY: plain scalar read through a live handle.
11509        unsafe { ffi::whiteout_m3_M3MaterialAddData_get_frequency(self.raw.as_ptr()) }
11510    }
11511
11512    pub fn set_frequency(&mut self, value: f32) {
11513        // SAFETY: plain scalar write through a live handle.
11514        unsafe { ffi::whiteout_m3_M3MaterialAddData_set_frequency(self.raw.as_ptr(), value) }
11515    }
11516
11517    /// Effect intensity
11518    pub fn intensity(&self) -> f32 {
11519        // SAFETY: plain scalar read through a live handle.
11520        unsafe { ffi::whiteout_m3_M3MaterialAddData_get_intensity(self.raw.as_ptr()) }
11521    }
11522
11523    pub fn set_intensity(&mut self, value: f32) {
11524        // SAFETY: plain scalar write through a live handle.
11525        unsafe { ffi::whiteout_m3_M3MaterialAddData_set_intensity(self.raw.as_ptr(), value) }
11526    }
11527
11528    /// Hold time duration
11529    pub fn hold_time(&self) -> f32 {
11530        // SAFETY: plain scalar read through a live handle.
11531        unsafe { ffi::whiteout_m3_M3MaterialAddData_get_holdTime(self.raw.as_ptr()) }
11532    }
11533
11534    pub fn set_hold_time(&mut self, value: f32) {
11535        // SAFETY: plain scalar write through a live handle.
11536        unsafe { ffi::whiteout_m3_M3MaterialAddData_set_holdTime(self.raw.as_ptr(), value) }
11537    }
11538
11539    /// Random seed hash
11540    pub fn random_hash(&self) -> u32 {
11541        // SAFETY: plain scalar read through a live handle.
11542        unsafe { ffi::whiteout_m3_M3MaterialAddData_get_randomHash(self.raw.as_ptr()) }
11543    }
11544
11545    pub fn set_random_hash(&mut self, value: u32) {
11546        // SAFETY: plain scalar write through a live handle.
11547        unsafe { ffi::whiteout_m3_M3MaterialAddData_set_randomHash(self.raw.as_ptr(), value) }
11548    }
11549
11550    /// Animation type code
11551    pub fn animation_type(&self) -> u32 {
11552        // SAFETY: plain scalar read through a live handle.
11553        unsafe { ffi::whiteout_m3_M3MaterialAddData_get_animationType(self.raw.as_ptr()) }
11554    }
11555
11556    pub fn set_animation_type(&mut self, value: u32) {
11557        // SAFETY: plain scalar write through a live handle.
11558        unsafe { ffi::whiteout_m3_M3MaterialAddData_set_animationType(self.raw.as_ptr(), value) }
11559    }
11560
11561    /// Alignment padding
11562    pub fn padding_0(&self) -> u32 {
11563        // SAFETY: plain scalar read through a live handle.
11564        unsafe { ffi::whiteout_m3_M3MaterialAddData_get_padding0(self.raw.as_ptr()) }
11565    }
11566
11567    pub fn set_padding_0(&mut self, value: u32) {
11568        // SAFETY: plain scalar write through a live handle.
11569        unsafe { ffi::whiteout_m3_M3MaterialAddData_set_padding0(self.raw.as_ptr(), value) }
11570    }
11571
11572    /// Loop count (-1 = infinite)
11573    pub fn loop_count(&self) -> i32 {
11574        // SAFETY: plain scalar read through a live handle.
11575        unsafe { ffi::whiteout_m3_M3MaterialAddData_get_loopCount(self.raw.as_ptr()) }
11576    }
11577
11578    pub fn set_loop_count(&mut self, value: i32) {
11579        // SAFETY: plain scalar write through a live handle.
11580        unsafe { ffi::whiteout_m3_M3MaterialAddData_set_loopCount(self.raw.as_ptr(), value) }
11581    }
11582
11583    /// Flags
11584    pub fn flags(&self) -> u32 {
11585        // SAFETY: plain scalar read through a live handle.
11586        unsafe { ffi::whiteout_m3_M3MaterialAddData_get_flags(self.raw.as_ptr()) }
11587    }
11588
11589    pub fn set_flags(&mut self, value: u32) {
11590        // SAFETY: plain scalar write through a live handle.
11591        unsafe { ffi::whiteout_m3_M3MaterialAddData_set_flags(self.raw.as_ptr(), value) }
11592    }
11593
11594    /// Sub-type identifier
11595    pub fn sub_type(&self) -> u32 {
11596        // SAFETY: plain scalar read through a live handle.
11597        unsafe { ffi::whiteout_m3_M3MaterialAddData_get_subType(self.raw.as_ptr()) }
11598    }
11599
11600    pub fn set_sub_type(&mut self, value: u32) {
11601        // SAFETY: plain scalar write through a live handle.
11602        unsafe { ffi::whiteout_m3_M3MaterialAddData_set_subType(self.raw.as_ptr(), value) }
11603    }
11604
11605    /// Configuration parameter A
11606    pub fn config_a(&self) -> u32 {
11607        // SAFETY: plain scalar read through a live handle.
11608        unsafe { ffi::whiteout_m3_M3MaterialAddData_get_configA(self.raw.as_ptr()) }
11609    }
11610
11611    pub fn set_config_a(&mut self, value: u32) {
11612        // SAFETY: plain scalar write through a live handle.
11613        unsafe { ffi::whiteout_m3_M3MaterialAddData_set_configA(self.raw.as_ptr(), value) }
11614    }
11615
11616    /// Configuration parameter B
11617    pub fn config_b(&self) -> u32 {
11618        // SAFETY: plain scalar read through a live handle.
11619        unsafe { ffi::whiteout_m3_M3MaterialAddData_get_configB(self.raw.as_ptr()) }
11620    }
11621
11622    pub fn set_config_b(&mut self, value: u32) {
11623        // SAFETY: plain scalar write through a live handle.
11624        unsafe { ffi::whiteout_m3_M3MaterialAddData_set_configB(self.raw.as_ptr(), value) }
11625    }
11626
11627    /// Extra identifier 0 (v3+)
11628    pub fn extra_id_0(&self) -> u32 {
11629        // SAFETY: plain scalar read through a live handle.
11630        unsafe { ffi::whiteout_m3_M3MaterialAddData_get_extraId0(self.raw.as_ptr()) }
11631    }
11632
11633    pub fn set_extra_id_0(&mut self, value: u32) {
11634        // SAFETY: plain scalar write through a live handle.
11635        unsafe { ffi::whiteout_m3_M3MaterialAddData_set_extraId0(self.raw.as_ptr(), value) }
11636    }
11637
11638    /// Extra identifier 1 (v3+)
11639    pub fn extra_id_1(&self) -> u32 {
11640        // SAFETY: plain scalar read through a live handle.
11641        unsafe { ffi::whiteout_m3_M3MaterialAddData_get_extraId1(self.raw.as_ptr()) }
11642    }
11643
11644    pub fn set_extra_id_1(&mut self, value: u32) {
11645        // SAFETY: plain scalar write through a live handle.
11646        unsafe { ffi::whiteout_m3_M3MaterialAddData_set_extraId1(self.raw.as_ptr(), value) }
11647    }
11648}
11649
11650impl Default for MaterialAddData {
11651    fn default() -> Self {
11652        Self::new()
11653    }
11654}
11655
11656/// BONE — Skeleton bone (v0–v1, 160 bytes)
11657///
11658/// Each bone has a parent index, animated position/rotation/scale/visibility, and flags controlling inheritance, billboard mode, and IK.
11659pub struct Bone {
11660    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3Bone>,
11661}
11662
11663impl Drop for Bone {
11664    fn drop(&mut self) {
11665        // SAFETY: `raw` came from a native constructor and Drop runs once.
11666        unsafe { ffi::whiteout_m3_M3Bone_delete(self.raw.as_ptr()) }
11667    }
11668}
11669
11670impl Bone {
11671    /// # Safety
11672    /// `raw` must be a live handle this value takes ownership of.
11673    #[allow(dead_code)] // used by whichever methods return this type
11674    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3Bone) -> Option<Self> {
11675        core::ptr::NonNull::new(raw).map(|raw| Bone { raw })
11676    }
11677}
11678
11679// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
11680// is deliberately NOT implemented — the C++ types make no documented
11681// guarantee about concurrent use, and claiming one we haven't verified
11682// would be unsound. See `@bind thread_safe` in the plan.
11683unsafe impl Send for Bone {}
11684
11685impl core::fmt::Debug for Bone {
11686    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
11687        f.debug_struct("Bone").finish_non_exhaustive()
11688    }
11689}
11690
11691impl Bone {
11692    /// # Panics
11693    /// Panics if the native allocation fails.
11694    pub fn new() -> Self {
11695        // SAFETY: the native constructor returns a live handle; a null here
11696        // means the library is unusable.
11697        unsafe {
11698            let raw = ffi::whiteout_m3_M3Bone_new();
11699            Self::from_raw(raw).expect("native Bone allocation failed")
11700        }
11701    }
11702
11703    /// Unknown field
11704    pub fn unknown(&self) -> u32 {
11705        // SAFETY: plain scalar read through a live handle.
11706        unsafe { ffi::whiteout_m3_M3Bone_get_unknown(self.raw.as_ptr()) }
11707    }
11708
11709    pub fn set_unknown(&mut self, value: u32) {
11710        // SAFETY: plain scalar write through a live handle.
11711        unsafe { ffi::whiteout_m3_M3Bone_set_unknown(self.raw.as_ptr(), value) }
11712    }
11713
11714    /// Bone name (`Ref<CHAR>`)
11715    pub fn name(&self) -> String {
11716        // SAFETY: the native side hands over an owned CString.
11717        unsafe { crate::support::take_string(ffi::whiteout_m3_M3Bone_get_name(self.raw.as_ptr())) }
11718    }
11719
11720    pub fn set_name(&mut self, value: &str) {
11721        let value = std::ffi::CString::new(value).unwrap_or_default();
11722        // SAFETY: the pointer outlives the call.
11723        unsafe { ffi::whiteout_m3_M3Bone_set_name(self.raw.as_ptr(), value.as_ptr()) }
11724    }
11725
11726    /// Bone flags (inherit, billboard, IK, skin)
11727    pub fn flags(&self) -> BoneFlag {
11728        // SAFETY: scalar read; a flag set accepts any bits.
11729        BoneFlag(unsafe { ffi::whiteout_m3_M3Bone_get_flags(self.raw.as_ptr()) })
11730    }
11731
11732    pub fn set_flags(&mut self, value: BoneFlag) {
11733        // SAFETY: scalar write through a live handle.
11734        unsafe { ffi::whiteout_m3_M3Bone_set_flags(self.raw.as_ptr(), value.0) }
11735    }
11736
11737    /// Parent bone index (0xFFFF = root)
11738    pub fn parent_index(&self) -> u16 {
11739        // SAFETY: plain scalar read through a live handle.
11740        unsafe { ffi::whiteout_m3_M3Bone_get_parentIndex(self.raw.as_ptr()) }
11741    }
11742
11743    pub fn set_parent_index(&mut self, value: u16) {
11744        // SAFETY: plain scalar write through a live handle.
11745        unsafe { ffi::whiteout_m3_M3Bone_set_parentIndex(self.raw.as_ptr(), value) }
11746    }
11747
11748    /// Alignment padding
11749    pub fn padding(&self) -> u16 {
11750        // SAFETY: plain scalar read through a live handle.
11751        unsafe { ffi::whiteout_m3_M3Bone_get_padding(self.raw.as_ptr()) }
11752    }
11753
11754    pub fn set_padding(&mut self, value: u16) {
11755        // SAFETY: plain scalar write through a live handle.
11756        unsafe { ffi::whiteout_m3_M3Bone_set_padding(self.raw.as_ptr(), value) }
11757    }
11758
11759    /// Animated translation (36 bytes)
11760    /// Borrows the field in place — no copy, no allocation.
11761    pub fn position(&self) -> crate::support::Ref<'_, AnimRefVector3f> {
11762        // SAFETY: an interior pointer into `self`, valid for this
11763        // borrow and never freed by the `Ref`.
11764        unsafe {
11765            crate::support::Ref::new(AnimRefVector3f {
11766                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Bone_get_position(
11767                    self.raw.as_ptr(),
11768                )),
11769            })
11770        }
11771    }
11772
11773    pub fn position_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector3f> {
11774        // SAFETY: as above; `&mut self` guarantees exclusivity.
11775        unsafe {
11776            crate::support::RefMut::new(AnimRefVector3f {
11777                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Bone_get_position(
11778                    self.raw.as_ptr(),
11779                )),
11780            })
11781        }
11782    }
11783
11784    /// Animated rotation (44 bytes)
11785    /// Borrows the field in place — no copy, no allocation.
11786    pub fn rotation(&self) -> crate::support::Ref<'_, AnimRefQuaternion> {
11787        // SAFETY: an interior pointer into `self`, valid for this
11788        // borrow and never freed by the `Ref`.
11789        unsafe {
11790            crate::support::Ref::new(AnimRefQuaternion {
11791                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Bone_get_rotation(
11792                    self.raw.as_ptr(),
11793                )),
11794            })
11795        }
11796    }
11797
11798    pub fn rotation_mut(&mut self) -> crate::support::RefMut<'_, AnimRefQuaternion> {
11799        // SAFETY: as above; `&mut self` guarantees exclusivity.
11800        unsafe {
11801            crate::support::RefMut::new(AnimRefQuaternion {
11802                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Bone_get_rotation(
11803                    self.raw.as_ptr(),
11804                )),
11805            })
11806        }
11807    }
11808
11809    /// Animated scale (36 bytes)
11810    /// Borrows the field in place — no copy, no allocation.
11811    pub fn scale(&self) -> crate::support::Ref<'_, AnimRefVector3f> {
11812        // SAFETY: an interior pointer into `self`, valid for this
11813        // borrow and never freed by the `Ref`.
11814        unsafe {
11815            crate::support::Ref::new(AnimRefVector3f {
11816                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Bone_get_scale(
11817                    self.raw.as_ptr(),
11818                )),
11819            })
11820        }
11821    }
11822
11823    pub fn scale_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector3f> {
11824        // SAFETY: as above; `&mut self` guarantees exclusivity.
11825        unsafe {
11826            crate::support::RefMut::new(AnimRefVector3f {
11827                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Bone_get_scale(
11828                    self.raw.as_ptr(),
11829                )),
11830            })
11831        }
11832    }
11833
11834    /// Animated visibility flag (20 bytes)
11835    /// Borrows the field in place — no copy, no allocation.
11836    pub fn visibility(&self) -> crate::support::Ref<'_, AnimRefU32> {
11837        // SAFETY: an interior pointer into `self`, valid for this
11838        // borrow and never freed by the `Ref`.
11839        unsafe {
11840            crate::support::Ref::new(AnimRefU32 {
11841                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Bone_get_visibility(
11842                    self.raw.as_ptr(),
11843                )),
11844            })
11845        }
11846    }
11847
11848    pub fn visibility_mut(&mut self) -> crate::support::RefMut<'_, AnimRefU32> {
11849        // SAFETY: as above; `&mut self` guarantees exclusivity.
11850        unsafe {
11851            crate::support::RefMut::new(AnimRefU32 {
11852                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Bone_get_visibility(
11853                    self.raw.as_ptr(),
11854                )),
11855            })
11856        }
11857    }
11858}
11859
11860impl Default for Bone {
11861    fn default() -> Self {
11862        Self::new()
11863    }
11864}
11865
11866/// REGN — Region / submesh (v0–v5, 48 bytes)
11867///
11868/// Describes a contiguous range of vertices and indices forming a submesh, with bone lookup info for skinning and UV scale/offset for texturing.
11869pub struct Region {
11870    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3Region>,
11871}
11872
11873impl Drop for Region {
11874    fn drop(&mut self) {
11875        // SAFETY: `raw` came from a native constructor and Drop runs once.
11876        unsafe { ffi::whiteout_m3_M3Region_delete(self.raw.as_ptr()) }
11877    }
11878}
11879
11880impl Region {
11881    /// # Safety
11882    /// `raw` must be a live handle this value takes ownership of.
11883    #[allow(dead_code)] // used by whichever methods return this type
11884    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3Region) -> Option<Self> {
11885        core::ptr::NonNull::new(raw).map(|raw| Region { raw })
11886    }
11887}
11888
11889// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
11890// is deliberately NOT implemented — the C++ types make no documented
11891// guarantee about concurrent use, and claiming one we haven't verified
11892// would be unsound. See `@bind thread_safe` in the plan.
11893unsafe impl Send for Region {}
11894
11895impl core::fmt::Debug for Region {
11896    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
11897        f.debug_struct("Region").finish_non_exhaustive()
11898    }
11899}
11900
11901impl Region {
11902    /// # Panics
11903    /// Panics if the native allocation fails.
11904    pub fn new() -> Self {
11905        // SAFETY: the native constructor returns a live handle; a null here
11906        // means the library is unusable.
11907        unsafe {
11908            let raw = ffi::whiteout_m3_M3Region_new();
11909            Self::from_raw(raw).expect("native Region allocation failed")
11910        }
11911    }
11912
11913    /// Region index
11914    pub fn index(&self) -> u32 {
11915        // SAFETY: plain scalar read through a live handle.
11916        unsafe { ffi::whiteout_m3_M3Region_get_index(self.raw.as_ptr()) }
11917    }
11918
11919    pub fn set_index(&mut self, value: u32) {
11920        // SAFETY: plain scalar write through a live handle.
11921        unsafe { ffi::whiteout_m3_M3Region_set_index(self.raw.as_ptr(), value) }
11922    }
11923
11924    /// Unknown field
11925    pub fn unknown(&self) -> u32 {
11926        // SAFETY: plain scalar read through a live handle.
11927        unsafe { ffi::whiteout_m3_M3Region_get_unknown(self.raw.as_ptr()) }
11928    }
11929
11930    pub fn set_unknown(&mut self, value: u32) {
11931        // SAFETY: plain scalar write through a live handle.
11932        unsafe { ffi::whiteout_m3_M3Region_set_unknown(self.raw.as_ptr(), value) }
11933    }
11934
11935    /// First vertex in the vertex buffer
11936    pub fn first_vertex(&self) -> u32 {
11937        // SAFETY: plain scalar read through a live handle.
11938        unsafe { ffi::whiteout_m3_M3Region_get_firstVertex(self.raw.as_ptr()) }
11939    }
11940
11941    pub fn set_first_vertex(&mut self, value: u32) {
11942        // SAFETY: plain scalar write through a live handle.
11943        unsafe { ffi::whiteout_m3_M3Region_set_firstVertex(self.raw.as_ptr(), value) }
11944    }
11945
11946    /// Number of vertices
11947    pub fn vertex_count(&self) -> u32 {
11948        // SAFETY: plain scalar read through a live handle.
11949        unsafe { ffi::whiteout_m3_M3Region_get_vertexCount(self.raw.as_ptr()) }
11950    }
11951
11952    pub fn set_vertex_count(&mut self, value: u32) {
11953        // SAFETY: plain scalar write through a live handle.
11954        unsafe { ffi::whiteout_m3_M3Region_set_vertexCount(self.raw.as_ptr(), value) }
11955    }
11956
11957    /// First index in the index buffer
11958    pub fn first_index(&self) -> u32 {
11959        // SAFETY: plain scalar read through a live handle.
11960        unsafe { ffi::whiteout_m3_M3Region_get_firstIndex(self.raw.as_ptr()) }
11961    }
11962
11963    pub fn set_first_index(&mut self, value: u32) {
11964        // SAFETY: plain scalar write through a live handle.
11965        unsafe { ffi::whiteout_m3_M3Region_set_firstIndex(self.raw.as_ptr(), value) }
11966    }
11967
11968    /// Number of indices (triangles × 3)
11969    pub fn index_count(&self) -> u32 {
11970        // SAFETY: plain scalar read through a live handle.
11971        unsafe { ffi::whiteout_m3_M3Region_get_indexCount(self.raw.as_ptr()) }
11972    }
11973
11974    pub fn set_index_count(&mut self, value: u32) {
11975        // SAFETY: plain scalar write through a live handle.
11976        unsafe { ffi::whiteout_m3_M3Region_set_indexCount(self.raw.as_ptr(), value) }
11977    }
11978
11979    /// Unknown field
11980    pub fn unknown_2(&self) -> u16 {
11981        // SAFETY: plain scalar read through a live handle.
11982        unsafe { ffi::whiteout_m3_M3Region_get_unknown2(self.raw.as_ptr()) }
11983    }
11984
11985    pub fn set_unknown_2(&mut self, value: u16) {
11986        // SAFETY: plain scalar write through a live handle.
11987        unsafe { ffi::whiteout_m3_M3Region_set_unknown2(self.raw.as_ptr(), value) }
11988    }
11989
11990    /// First entry in bone lookup table
11991    pub fn first_bone_lookup(&self) -> u16 {
11992        // SAFETY: plain scalar read through a live handle.
11993        unsafe { ffi::whiteout_m3_M3Region_get_firstBoneLookup(self.raw.as_ptr()) }
11994    }
11995
11996    pub fn set_first_bone_lookup(&mut self, value: u16) {
11997        // SAFETY: plain scalar write through a live handle.
11998        unsafe { ffi::whiteout_m3_M3Region_set_firstBoneLookup(self.raw.as_ptr(), value) }
11999    }
12000
12001    /// Number of bone lookup entries
12002    pub fn bone_lookup_count(&self) -> u16 {
12003        // SAFETY: plain scalar read through a live handle.
12004        unsafe { ffi::whiteout_m3_M3Region_get_boneLookupCount(self.raw.as_ptr()) }
12005    }
12006
12007    pub fn set_bone_lookup_count(&mut self, value: u16) {
12008        // SAFETY: plain scalar write through a live handle.
12009        unsafe { ffi::whiteout_m3_M3Region_set_boneLookupCount(self.raw.as_ptr(), value) }
12010    }
12011
12012    /// Alignment padding
12013    pub fn padding(&self) -> u16 {
12014        // SAFETY: plain scalar read through a live handle.
12015        unsafe { ffi::whiteout_m3_M3Region_get_padding(self.raw.as_ptr()) }
12016    }
12017
12018    pub fn set_padding(&mut self, value: u16) {
12019        // SAFETY: plain scalar write through a live handle.
12020        unsafe { ffi::whiteout_m3_M3Region_set_padding(self.raw.as_ptr(), value) }
12021    }
12022
12023    /// Number of bone weight pairs per vertex
12024    pub fn bone_weight_pairs(&self) -> u8 {
12025        // SAFETY: plain scalar read through a live handle.
12026        unsafe { ffi::whiteout_m3_M3Region_get_boneWeightPairs(self.raw.as_ptr()) }
12027    }
12028
12029    pub fn set_bone_weight_pairs(&mut self, value: u8) {
12030        // SAFETY: plain scalar write through a live handle.
12031        unsafe { ffi::whiteout_m3_M3Region_set_boneWeightPairs(self.raw.as_ptr(), value) }
12032    }
12033
12034    /// Number of bone index pairs per vertex
12035    pub fn bone_index_pairs(&self) -> u8 {
12036        // SAFETY: plain scalar read through a live handle.
12037        unsafe { ffi::whiteout_m3_M3Region_get_boneIndexPairs(self.raw.as_ptr()) }
12038    }
12039
12040    pub fn set_bone_index_pairs(&mut self, value: u8) {
12041        // SAFETY: plain scalar write through a live handle.
12042        unsafe { ffi::whiteout_m3_M3Region_set_boneIndexPairs(self.raw.as_ptr(), value) }
12043    }
12044
12045    /// Root bone for this region
12046    pub fn root_bone(&self) -> u16 {
12047        // SAFETY: plain scalar read through a live handle.
12048        unsafe { ffi::whiteout_m3_M3Region_get_rootBone(self.raw.as_ptr()) }
12049    }
12050
12051    pub fn set_root_bone(&mut self, value: u16) {
12052        // SAFETY: plain scalar write through a live handle.
12053        unsafe { ffi::whiteout_m3_M3Region_set_rootBone(self.raw.as_ptr(), value) }
12054    }
12055
12056    /// Region flags (hidden, cloth, etc.)
12057    pub fn flags(&self) -> RegionFlag {
12058        // SAFETY: scalar read; a flag set accepts any bits.
12059        RegionFlag(unsafe { ffi::whiteout_m3_M3Region_get_flags(self.raw.as_ptr()) })
12060    }
12061
12062    pub fn set_flags(&mut self, value: RegionFlag) {
12063        // SAFETY: scalar write through a live handle.
12064        unsafe { ffi::whiteout_m3_M3Region_set_flags(self.raw.as_ptr(), value.0) }
12065    }
12066
12067    /// UV coordinate scale factor
12068    pub fn uv_scale(&self) -> f32 {
12069        // SAFETY: plain scalar read through a live handle.
12070        unsafe { ffi::whiteout_m3_M3Region_get_uvScale(self.raw.as_ptr()) }
12071    }
12072
12073    pub fn set_uv_scale(&mut self, value: f32) {
12074        // SAFETY: plain scalar write through a live handle.
12075        unsafe { ffi::whiteout_m3_M3Region_set_uvScale(self.raw.as_ptr(), value) }
12076    }
12077
12078    /// UV coordinate offset
12079    pub fn uv_offset(&self) -> f32 {
12080        // SAFETY: plain scalar read through a live handle.
12081        unsafe { ffi::whiteout_m3_M3Region_get_uvOffset(self.raw.as_ptr()) }
12082    }
12083
12084    pub fn set_uv_offset(&mut self, value: f32) {
12085        // SAFETY: plain scalar write through a live handle.
12086        unsafe { ffi::whiteout_m3_M3Region_set_uvOffset(self.raw.as_ptr(), value) }
12087    }
12088}
12089
12090impl Default for Region {
12091    fn default() -> Self {
12092        Self::new()
12093    }
12094}
12095
12096/// BAT_ — Batch / draw call (v0–v1, 14 bytes)
12097///
12098/// Associates a Region with a material for rendering. Multiple batches may reference the same region with different materials.
12099pub struct Batch {
12100    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3Batch>,
12101}
12102
12103impl Drop for Batch {
12104    fn drop(&mut self) {
12105        // SAFETY: `raw` came from a native constructor and Drop runs once.
12106        unsafe { ffi::whiteout_m3_M3Batch_delete(self.raw.as_ptr()) }
12107    }
12108}
12109
12110impl Batch {
12111    /// # Safety
12112    /// `raw` must be a live handle this value takes ownership of.
12113    #[allow(dead_code)] // used by whichever methods return this type
12114    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3Batch) -> Option<Self> {
12115        core::ptr::NonNull::new(raw).map(|raw| Batch { raw })
12116    }
12117}
12118
12119// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
12120// is deliberately NOT implemented — the C++ types make no documented
12121// guarantee about concurrent use, and claiming one we haven't verified
12122// would be unsound. See `@bind thread_safe` in the plan.
12123unsafe impl Send for Batch {}
12124
12125impl core::fmt::Debug for Batch {
12126    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
12127        f.debug_struct("Batch").finish_non_exhaustive()
12128    }
12129}
12130
12131impl Batch {
12132    /// # Panics
12133    /// Panics if the native allocation fails.
12134    pub fn new() -> Self {
12135        // SAFETY: the native constructor returns a live handle; a null here
12136        // means the library is unusable.
12137        unsafe {
12138            let raw = ffi::whiteout_m3_M3Batch_new();
12139            Self::from_raw(raw).expect("native Batch allocation failed")
12140        }
12141    }
12142
12143    /// Unknown field
12144    pub fn unknown(&self) -> u32 {
12145        // SAFETY: plain scalar read through a live handle.
12146        unsafe { ffi::whiteout_m3_M3Batch_get_unknown(self.raw.as_ptr()) }
12147    }
12148
12149    pub fn set_unknown(&mut self, value: u32) {
12150        // SAFETY: plain scalar write through a live handle.
12151        unsafe { ffi::whiteout_m3_M3Batch_set_unknown(self.raw.as_ptr(), value) }
12152    }
12153
12154    /// Index into REGN array
12155    pub fn region_index(&self) -> u16 {
12156        // SAFETY: plain scalar read through a live handle.
12157        unsafe { ffi::whiteout_m3_M3Batch_get_regionIndex(self.raw.as_ptr()) }
12158    }
12159
12160    pub fn set_region_index(&mut self, value: u16) {
12161        // SAFETY: plain scalar write through a live handle.
12162        unsafe { ffi::whiteout_m3_M3Batch_set_regionIndex(self.raw.as_ptr(), value) }
12163    }
12164
12165    /// Unknown field
12166    pub fn unknown_2(&self) -> u32 {
12167        // SAFETY: plain scalar read through a live handle.
12168        unsafe { ffi::whiteout_m3_M3Batch_get_unknown2(self.raw.as_ptr()) }
12169    }
12170
12171    pub fn set_unknown_2(&mut self, value: u32) {
12172        // SAFETY: plain scalar write through a live handle.
12173        unsafe { ffi::whiteout_m3_M3Batch_set_unknown2(self.raw.as_ptr(), value) }
12174    }
12175
12176    /// Index into MATM material map array
12177    pub fn material_index(&self) -> u16 {
12178        // SAFETY: plain scalar read through a live handle.
12179        unsafe { ffi::whiteout_m3_M3Batch_get_materialIndex(self.raw.as_ptr()) }
12180    }
12181
12182    pub fn set_material_index(&mut self, value: u16) {
12183        // SAFETY: plain scalar write through a live handle.
12184        unsafe { ffi::whiteout_m3_M3Batch_set_materialIndex(self.raw.as_ptr(), value) }
12185    }
12186
12187    /// Number of bones affecting this batch
12188    pub fn bone_count(&self) -> u16 {
12189        // SAFETY: plain scalar read through a live handle.
12190        unsafe { ffi::whiteout_m3_M3Batch_get_boneCount(self.raw.as_ptr()) }
12191    }
12192
12193    pub fn set_bone_count(&mut self, value: u16) {
12194        // SAFETY: plain scalar write through a live handle.
12195        unsafe { ffi::whiteout_m3_M3Batch_set_boneCount(self.raw.as_ptr(), value) }
12196    }
12197}
12198
12199impl Default for Batch {
12200    fn default() -> Self {
12201        Self::new()
12202    }
12203}
12204
12205/// MSEC — Mesh section bounds (v0–v1, 80 bytes)
12206///
12207/// Per-node animated bounding extent used for culling and LOD.
12208pub struct MeshSection {
12209    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3MeshSection>,
12210}
12211
12212impl Drop for MeshSection {
12213    fn drop(&mut self) {
12214        // SAFETY: `raw` came from a native constructor and Drop runs once.
12215        unsafe { ffi::whiteout_m3_M3MeshSection_delete(self.raw.as_ptr()) }
12216    }
12217}
12218
12219impl MeshSection {
12220    /// # Safety
12221    /// `raw` must be a live handle this value takes ownership of.
12222    #[allow(dead_code)] // used by whichever methods return this type
12223    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3MeshSection) -> Option<Self> {
12224        core::ptr::NonNull::new(raw).map(|raw| MeshSection { raw })
12225    }
12226}
12227
12228// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
12229// is deliberately NOT implemented — the C++ types make no documented
12230// guarantee about concurrent use, and claiming one we haven't verified
12231// would be unsound. See `@bind thread_safe` in the plan.
12232unsafe impl Send for MeshSection {}
12233
12234impl core::fmt::Debug for MeshSection {
12235    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
12236        f.debug_struct("MeshSection").finish_non_exhaustive()
12237    }
12238}
12239
12240impl MeshSection {
12241    /// # Panics
12242    /// Panics if the native allocation fails.
12243    pub fn new() -> Self {
12244        // SAFETY: the native constructor returns a live handle; a null here
12245        // means the library is unusable.
12246        unsafe {
12247            let raw = ffi::whiteout_m3_M3MeshSection_new();
12248            Self::from_raw(raw).expect("native MeshSection allocation failed")
12249        }
12250    }
12251
12252    /// Index into BONE array
12253    pub fn node_index(&self) -> u32 {
12254        // SAFETY: plain scalar read through a live handle.
12255        unsafe { ffi::whiteout_m3_M3MeshSection_get_nodeIndex(self.raw.as_ptr()) }
12256    }
12257
12258    pub fn set_node_index(&mut self, value: u32) {
12259        // SAFETY: plain scalar write through a live handle.
12260        unsafe { ffi::whiteout_m3_M3MeshSection_set_nodeIndex(self.raw.as_ptr(), value) }
12261    }
12262
12263    /// Animated bounding volume (76 bytes)
12264    /// Borrows the field in place — no copy, no allocation.
12265    pub fn bounds(&self) -> crate::support::Ref<'_, AnimRefM3Extent> {
12266        // SAFETY: an interior pointer into `self`, valid for this
12267        // borrow and never freed by the `Ref`.
12268        unsafe {
12269            crate::support::Ref::new(AnimRefM3Extent {
12270                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3MeshSection_get_bounds(
12271                    self.raw.as_ptr(),
12272                )),
12273            })
12274        }
12275    }
12276
12277    pub fn bounds_mut(&mut self) -> crate::support::RefMut<'_, AnimRefM3Extent> {
12278        // SAFETY: as above; `&mut self` guarantees exclusivity.
12279        unsafe {
12280            crate::support::RefMut::new(AnimRefM3Extent {
12281                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3MeshSection_get_bounds(
12282                    self.raw.as_ptr(),
12283                )),
12284            })
12285        }
12286    }
12287}
12288
12289impl Default for MeshSection {
12290    fn default() -> Self {
12291        Self::new()
12292    }
12293}
12294
12295/// DIV_ — Mesh division (v0–v2, 52 bytes)
12296///
12297/// Top-level mesh container grouping face indices, regions, batches, and mesh sections. Most models have a single division.
12298pub struct MeshDivision {
12299    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3MeshDivision>,
12300}
12301
12302impl Drop for MeshDivision {
12303    fn drop(&mut self) {
12304        // SAFETY: `raw` came from a native constructor and Drop runs once.
12305        unsafe { ffi::whiteout_m3_M3MeshDivision_delete(self.raw.as_ptr()) }
12306    }
12307}
12308
12309impl MeshDivision {
12310    /// # Safety
12311    /// `raw` must be a live handle this value takes ownership of.
12312    #[allow(dead_code)] // used by whichever methods return this type
12313    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3MeshDivision) -> Option<Self> {
12314        core::ptr::NonNull::new(raw).map(|raw| MeshDivision { raw })
12315    }
12316}
12317
12318// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
12319// is deliberately NOT implemented — the C++ types make no documented
12320// guarantee about concurrent use, and claiming one we haven't verified
12321// would be unsound. See `@bind thread_safe` in the plan.
12322unsafe impl Send for MeshDivision {}
12323
12324impl core::fmt::Debug for MeshDivision {
12325    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
12326        f.debug_struct("MeshDivision").finish_non_exhaustive()
12327    }
12328}
12329
12330impl MeshDivision {
12331    /// # Panics
12332    /// Panics if the native allocation fails.
12333    pub fn new() -> Self {
12334        // SAFETY: the native constructor returns a live handle; a null here
12335        // means the library is unusable.
12336        unsafe {
12337            let raw = ffi::whiteout_m3_M3MeshDivision_new();
12338            Self::from_raw(raw).expect("native MeshDivision allocation failed")
12339        }
12340    }
12341
12342    /// Triangle indices (U16_)
12343    /// Zero-copy view of the underlying `std::vector`.
12344    pub fn faces(&self) -> &[u16] {
12345        // SAFETY: `_data`/`_count` describe one contiguous C++
12346        // allocation, borrowed for as long as `self` is.
12347        unsafe {
12348            let n = ffi::whiteout_m3_M3MeshDivision_get_faces_count(self.raw.as_ptr());
12349            let p = ffi::whiteout_m3_M3MeshDivision_get_faces_data(self.raw.as_ptr());
12350            if p.is_null() || n == 0 {
12351                &[]
12352            } else {
12353                core::slice::from_raw_parts(p, n)
12354            }
12355        }
12356    }
12357
12358    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
12359    pub fn faces_mut(&mut self) -> &mut [u16] {
12360        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
12361        unsafe {
12362            let n = ffi::whiteout_m3_M3MeshDivision_get_faces_count(self.raw.as_ptr());
12363            let p = ffi::whiteout_m3_M3MeshDivision_get_faces_data(self.raw.as_ptr()) as *mut u16;
12364            if p.is_null() || n == 0 {
12365                &mut []
12366            } else {
12367                core::slice::from_raw_parts_mut(p, n)
12368            }
12369        }
12370    }
12371
12372    pub fn set_faces(&mut self, values: &[u16]) {
12373        // SAFETY: the native side copies `values` before returning.
12374        unsafe {
12375            ffi::whiteout_m3_M3MeshDivision_assign_faces(
12376                self.raw.as_ptr(),
12377                values.as_ptr() as *const _,
12378                values.len(),
12379            )
12380        }
12381    }
12382
12383    pub fn resize_faces(&mut self, count: usize) {
12384        // SAFETY: reallocation is safe here precisely because
12385        // `&mut self` means no slice borrow is outstanding.
12386        unsafe { ffi::whiteout_m3_M3MeshDivision_resize_faces(self.raw.as_ptr(), count) }
12387    }
12388
12389    /// Regions / submeshes (REGN)
12390    pub fn regions_len(&self) -> usize {
12391        // SAFETY: scalar read through a live handle.
12392        unsafe { ffi::whiteout_m3_M3MeshDivision_get_regions_count(self.raw.as_ptr()) }
12393    }
12394
12395    /// Borrows element `index` in place. `None` when out of range.
12396    pub fn regions(&self, index: usize) -> Option<crate::support::Ref<'_, Region>> {
12397        if index >= self.regions_len() {
12398            return None;
12399        }
12400        // SAFETY: index checked above; the pointer is interior to `self`.
12401        unsafe {
12402            Some(crate::support::Ref::new(Region {
12403                raw: core::ptr::NonNull::new_unchecked(
12404                    ffi::whiteout_m3_M3MeshDivision_get_regions_at(self.raw.as_ptr(), index),
12405                ),
12406            }))
12407        }
12408    }
12409
12410    pub fn regions_mut(&mut self, index: usize) -> Option<crate::support::RefMut<'_, Region>> {
12411        if index >= self.regions_len() {
12412            return None;
12413        }
12414        // SAFETY: as above; `&mut self` guarantees exclusivity.
12415        unsafe {
12416            Some(crate::support::RefMut::new(Region {
12417                raw: core::ptr::NonNull::new_unchecked(
12418                    ffi::whiteout_m3_M3MeshDivision_get_regions_at(self.raw.as_ptr(), index),
12419                ),
12420            }))
12421        }
12422    }
12423
12424    /// Iterate the elements, borrowing each in turn.
12425    pub fn regions_iter(&self) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, Region>> {
12426        (0..self.regions_len()).map(move |i| self.regions(i).expect("index below len"))
12427    }
12428
12429    pub fn resize_regions(&mut self, count: usize) {
12430        // SAFETY: exclusive access, so no borrow is outstanding.
12431        unsafe { ffi::whiteout_m3_M3MeshDivision_resize_regions(self.raw.as_ptr(), count) }
12432    }
12433
12434    /// Draw call batches (BAT_)
12435    pub fn batches_len(&self) -> usize {
12436        // SAFETY: scalar read through a live handle.
12437        unsafe { ffi::whiteout_m3_M3MeshDivision_get_batches_count(self.raw.as_ptr()) }
12438    }
12439
12440    /// Borrows element `index` in place. `None` when out of range.
12441    pub fn batches(&self, index: usize) -> Option<crate::support::Ref<'_, Batch>> {
12442        if index >= self.batches_len() {
12443            return None;
12444        }
12445        // SAFETY: index checked above; the pointer is interior to `self`.
12446        unsafe {
12447            Some(crate::support::Ref::new(Batch {
12448                raw: core::ptr::NonNull::new_unchecked(
12449                    ffi::whiteout_m3_M3MeshDivision_get_batches_at(self.raw.as_ptr(), index),
12450                ),
12451            }))
12452        }
12453    }
12454
12455    pub fn batches_mut(&mut self, index: usize) -> Option<crate::support::RefMut<'_, Batch>> {
12456        if index >= self.batches_len() {
12457            return None;
12458        }
12459        // SAFETY: as above; `&mut self` guarantees exclusivity.
12460        unsafe {
12461            Some(crate::support::RefMut::new(Batch {
12462                raw: core::ptr::NonNull::new_unchecked(
12463                    ffi::whiteout_m3_M3MeshDivision_get_batches_at(self.raw.as_ptr(), index),
12464                ),
12465            }))
12466        }
12467    }
12468
12469    /// Iterate the elements, borrowing each in turn.
12470    pub fn batches_iter(&self) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, Batch>> {
12471        (0..self.batches_len()).map(move |i| self.batches(i).expect("index below len"))
12472    }
12473
12474    pub fn resize_batches(&mut self, count: usize) {
12475        // SAFETY: exclusive access, so no borrow is outstanding.
12476        unsafe { ffi::whiteout_m3_M3MeshDivision_resize_batches(self.raw.as_ptr(), count) }
12477    }
12478
12479    /// Per-node mesh section bounds (MSEC)
12480    pub fn msec_len(&self) -> usize {
12481        // SAFETY: scalar read through a live handle.
12482        unsafe { ffi::whiteout_m3_M3MeshDivision_get_msec_count(self.raw.as_ptr()) }
12483    }
12484
12485    /// Borrows element `index` in place. `None` when out of range.
12486    pub fn msec(&self, index: usize) -> Option<crate::support::Ref<'_, MeshSection>> {
12487        if index >= self.msec_len() {
12488            return None;
12489        }
12490        // SAFETY: index checked above; the pointer is interior to `self`.
12491        unsafe {
12492            Some(crate::support::Ref::new(MeshSection {
12493                raw: core::ptr::NonNull::new_unchecked(
12494                    ffi::whiteout_m3_M3MeshDivision_get_msec_at(self.raw.as_ptr(), index),
12495                ),
12496            }))
12497        }
12498    }
12499
12500    pub fn msec_mut(&mut self, index: usize) -> Option<crate::support::RefMut<'_, MeshSection>> {
12501        if index >= self.msec_len() {
12502            return None;
12503        }
12504        // SAFETY: as above; `&mut self` guarantees exclusivity.
12505        unsafe {
12506            Some(crate::support::RefMut::new(MeshSection {
12507                raw: core::ptr::NonNull::new_unchecked(
12508                    ffi::whiteout_m3_M3MeshDivision_get_msec_at(self.raw.as_ptr(), index),
12509                ),
12510            }))
12511        }
12512    }
12513
12514    /// Iterate the elements, borrowing each in turn.
12515    pub fn msec_iter(&self) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, MeshSection>> {
12516        (0..self.msec_len()).map(move |i| self.msec(i).expect("index below len"))
12517    }
12518
12519    pub fn resize_msec(&mut self, count: usize) {
12520        // SAFETY: exclusive access, so no borrow is outstanding.
12521        unsafe { ffi::whiteout_m3_M3MeshDivision_resize_msec(self.raw.as_ptr(), count) }
12522    }
12523
12524    /// Instance count
12525    pub fn instances(&self) -> u32 {
12526        // SAFETY: plain scalar read through a live handle.
12527        unsafe { ffi::whiteout_m3_M3MeshDivision_get_instances(self.raw.as_ptr()) }
12528    }
12529
12530    pub fn set_instances(&mut self, value: u32) {
12531        // SAFETY: plain scalar write through a live handle.
12532        unsafe { ffi::whiteout_m3_M3MeshDivision_set_instances(self.raw.as_ptr(), value) }
12533    }
12534}
12535
12536impl Default for MeshDivision {
12537    fn default() -> Self {
12538        Self::new()
12539    }
12540}
12541
12542/// IREF — Initial reference / inverse bind-pose (v0, 64 bytes)
12543///
12544/// Stores the 4×4 inverse bind-pose matrix for a bone, used to transform vertices from model space into bone-local space for skinning.
12545pub struct InitialReference {
12546    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3InitialReference>,
12547}
12548
12549impl Drop for InitialReference {
12550    fn drop(&mut self) {
12551        // SAFETY: `raw` came from a native constructor and Drop runs once.
12552        unsafe { ffi::whiteout_m3_M3InitialReference_delete(self.raw.as_ptr()) }
12553    }
12554}
12555
12556impl InitialReference {
12557    /// # Safety
12558    /// `raw` must be a live handle this value takes ownership of.
12559    #[allow(dead_code)] // used by whichever methods return this type
12560    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3InitialReference) -> Option<Self> {
12561        core::ptr::NonNull::new(raw).map(|raw| InitialReference { raw })
12562    }
12563}
12564
12565// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
12566// is deliberately NOT implemented — the C++ types make no documented
12567// guarantee about concurrent use, and claiming one we haven't verified
12568// would be unsound. See `@bind thread_safe` in the plan.
12569unsafe impl Send for InitialReference {}
12570
12571impl core::fmt::Debug for InitialReference {
12572    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
12573        f.debug_struct("InitialReference").finish_non_exhaustive()
12574    }
12575}
12576
12577impl InitialReference {
12578    /// # Panics
12579    /// Panics if the native allocation fails.
12580    pub fn new() -> Self {
12581        // SAFETY: the native constructor returns a live handle; a null here
12582        // means the library is unusable.
12583        unsafe {
12584            let raw = ffi::whiteout_m3_M3InitialReference_new();
12585            Self::from_raw(raw).expect("native InitialReference allocation failed")
12586        }
12587    }
12588}
12589
12590impl Default for InitialReference {
12591    fn default() -> Self {
12592        Self::new()
12593    }
12594}
12595
12596/// ATT_ — Attachment point (v0–v1, 20 bytes)
12597///
12598/// Named bone location used by the engine to attach effects, weapons, or other models to specific skeleton bones.
12599pub struct AttachmentPoint {
12600    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3AttachmentPoint>,
12601}
12602
12603impl Drop for AttachmentPoint {
12604    fn drop(&mut self) {
12605        // SAFETY: `raw` came from a native constructor and Drop runs once.
12606        unsafe { ffi::whiteout_m3_M3AttachmentPoint_delete(self.raw.as_ptr()) }
12607    }
12608}
12609
12610impl AttachmentPoint {
12611    /// # Safety
12612    /// `raw` must be a live handle this value takes ownership of.
12613    #[allow(dead_code)] // used by whichever methods return this type
12614    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3AttachmentPoint) -> Option<Self> {
12615        core::ptr::NonNull::new(raw).map(|raw| AttachmentPoint { raw })
12616    }
12617}
12618
12619// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
12620// is deliberately NOT implemented — the C++ types make no documented
12621// guarantee about concurrent use, and claiming one we haven't verified
12622// would be unsound. See `@bind thread_safe` in the plan.
12623unsafe impl Send for AttachmentPoint {}
12624
12625impl core::fmt::Debug for AttachmentPoint {
12626    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
12627        f.debug_struct("AttachmentPoint").finish_non_exhaustive()
12628    }
12629}
12630
12631impl AttachmentPoint {
12632    /// # Panics
12633    /// Panics if the native allocation fails.
12634    pub fn new() -> Self {
12635        // SAFETY: the native constructor returns a live handle; a null here
12636        // means the library is unusable.
12637        unsafe {
12638            let raw = ffi::whiteout_m3_M3AttachmentPoint_new();
12639            Self::from_raw(raw).expect("native AttachmentPoint allocation failed")
12640        }
12641    }
12642
12643    /// Unknown field
12644    pub fn unknown(&self) -> u32 {
12645        // SAFETY: plain scalar read through a live handle.
12646        unsafe { ffi::whiteout_m3_M3AttachmentPoint_get_unknown(self.raw.as_ptr()) }
12647    }
12648
12649    pub fn set_unknown(&mut self, value: u32) {
12650        // SAFETY: plain scalar write through a live handle.
12651        unsafe { ffi::whiteout_m3_M3AttachmentPoint_set_unknown(self.raw.as_ptr(), value) }
12652    }
12653
12654    /// Attachment point name (`Ref<CHAR>`)
12655    pub fn name(&self) -> String {
12656        // SAFETY: the native side hands over an owned CString.
12657        unsafe {
12658            crate::support::take_string(ffi::whiteout_m3_M3AttachmentPoint_get_name(
12659                self.raw.as_ptr(),
12660            ))
12661        }
12662    }
12663
12664    pub fn set_name(&mut self, value: &str) {
12665        let value = std::ffi::CString::new(value).unwrap_or_default();
12666        // SAFETY: the pointer outlives the call.
12667        unsafe { ffi::whiteout_m3_M3AttachmentPoint_set_name(self.raw.as_ptr(), value.as_ptr()) }
12668    }
12669
12670    /// Index into BONE array
12671    pub fn bone_index(&self) -> u32 {
12672        // SAFETY: plain scalar read through a live handle.
12673        unsafe { ffi::whiteout_m3_M3AttachmentPoint_get_boneIndex(self.raw.as_ptr()) }
12674    }
12675
12676    pub fn set_bone_index(&mut self, value: u32) {
12677        // SAFETY: plain scalar write through a live handle.
12678        unsafe { ffi::whiteout_m3_M3AttachmentPoint_set_boneIndex(self.raw.as_ptr(), value) }
12679    }
12680}
12681
12682impl Default for AttachmentPoint {
12683    fn default() -> Self {
12684        Self::new()
12685    }
12686}
12687
12688/// SSGS — Hit-test shape (v0–v1, 108 bytes)
12689///
12690/// Defines a collision / selection volume (box, sphere, capsule, cylinder, or mesh) attached to a bone. Used for both tight and fuzzy hit testing.
12691pub struct HitTestShape {
12692    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3HitTestShape>,
12693}
12694
12695impl Drop for HitTestShape {
12696    fn drop(&mut self) {
12697        // SAFETY: `raw` came from a native constructor and Drop runs once.
12698        unsafe { ffi::whiteout_m3_M3HitTestShape_delete(self.raw.as_ptr()) }
12699    }
12700}
12701
12702impl HitTestShape {
12703    /// # Safety
12704    /// `raw` must be a live handle this value takes ownership of.
12705    #[allow(dead_code)] // used by whichever methods return this type
12706    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3HitTestShape) -> Option<Self> {
12707        core::ptr::NonNull::new(raw).map(|raw| HitTestShape { raw })
12708    }
12709}
12710
12711// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
12712// is deliberately NOT implemented — the C++ types make no documented
12713// guarantee about concurrent use, and claiming one we haven't verified
12714// would be unsound. See `@bind thread_safe` in the plan.
12715unsafe impl Send for HitTestShape {}
12716
12717impl core::fmt::Debug for HitTestShape {
12718    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
12719        f.debug_struct("HitTestShape").finish_non_exhaustive()
12720    }
12721}
12722
12723impl HitTestShape {
12724    /// # Panics
12725    /// Panics if the native allocation fails.
12726    pub fn new() -> Self {
12727        // SAFETY: the native constructor returns a live handle; a null here
12728        // means the library is unusable.
12729        unsafe {
12730            let raw = ffi::whiteout_m3_M3HitTestShape_new();
12731            Self::from_raw(raw).expect("native HitTestShape allocation failed")
12732        }
12733    }
12734
12735    /// Shape type (box/sphere/capsule/cylinder/mesh)
12736    pub fn shape_type(&self) -> HitTestShapeType {
12737        // SAFETY: scalar read; the discriminant is validated below.
12738        unsafe { ffi::whiteout_m3_M3HitTestShape_get_shapeType(self.raw.as_ptr()) }
12739            .try_into()
12740            .expect("unknown enum discriminant from the native library")
12741    }
12742
12743    pub fn set_shape_type(&mut self, value: HitTestShapeType) {
12744        // SAFETY: scalar write through a live handle.
12745        unsafe { ffi::whiteout_m3_M3HitTestShape_set_shapeType(self.raw.as_ptr(), value as i32) }
12746    }
12747
12748    /// Index into BONE array
12749    pub fn bone_index(&self) -> u16 {
12750        // SAFETY: plain scalar read through a live handle.
12751        unsafe { ffi::whiteout_m3_M3HitTestShape_get_boneIndex(self.raw.as_ptr()) }
12752    }
12753
12754    pub fn set_bone_index(&mut self, value: u16) {
12755        // SAFETY: plain scalar write through a live handle.
12756        unsafe { ffi::whiteout_m3_M3HitTestShape_set_boneIndex(self.raw.as_ptr(), value) }
12757    }
12758
12759    /// Alignment padding
12760    pub fn padding(&self) -> u16 {
12761        // SAFETY: plain scalar read through a live handle.
12762        unsafe { ffi::whiteout_m3_M3HitTestShape_get_padding(self.raw.as_ptr()) }
12763    }
12764
12765    pub fn set_padding(&mut self, value: u16) {
12766        // SAFETY: plain scalar write through a live handle.
12767        unsafe { ffi::whiteout_m3_M3HitTestShape_set_padding(self.raw.as_ptr(), value) }
12768    }
12769
12770    /// Mesh vertex positions (VEC3, mesh type only)
12771    /// Zero-copy view of the underlying `std::vector`.
12772    pub fn vertex_positions(&self) -> &[crate::math::Vector3f] {
12773        // SAFETY: `_data`/`_count` describe one contiguous C++
12774        // allocation, borrowed for as long as `self` is.
12775        unsafe {
12776            let n = ffi::whiteout_m3_M3HitTestShape_get_vertexPositions_count(self.raw.as_ptr());
12777            let p = ffi::whiteout_m3_M3HitTestShape_get_vertexPositions_data(self.raw.as_ptr())
12778                as *const crate::math::Vector3f;
12779            if p.is_null() || n == 0 {
12780                &[]
12781            } else {
12782                core::slice::from_raw_parts(p, n)
12783            }
12784        }
12785    }
12786
12787    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
12788    pub fn vertex_positions_mut(&mut self) -> &mut [crate::math::Vector3f] {
12789        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
12790        unsafe {
12791            let n = ffi::whiteout_m3_M3HitTestShape_get_vertexPositions_count(self.raw.as_ptr());
12792            let p = ffi::whiteout_m3_M3HitTestShape_get_vertexPositions_data(self.raw.as_ptr())
12793                as *const crate::math::Vector3f as *mut crate::math::Vector3f;
12794            if p.is_null() || n == 0 {
12795                &mut []
12796            } else {
12797                core::slice::from_raw_parts_mut(p, n)
12798            }
12799        }
12800    }
12801
12802    pub fn set_vertex_positions(&mut self, values: &[crate::math::Vector3f]) {
12803        // SAFETY: the native side copies `values` before returning.
12804        unsafe {
12805            ffi::whiteout_m3_M3HitTestShape_assign_vertexPositions(
12806                self.raw.as_ptr(),
12807                values.as_ptr() as *const _,
12808                values.len(),
12809            )
12810        }
12811    }
12812
12813    pub fn resize_vertex_positions(&mut self, count: usize) {
12814        // SAFETY: reallocation is safe here precisely because
12815        // `&mut self` means no slice borrow is outstanding.
12816        unsafe { ffi::whiteout_m3_M3HitTestShape_resize_vertexPositions(self.raw.as_ptr(), count) }
12817    }
12818
12819    /// Mesh triangle indices (U16_, mesh type only)
12820    /// Zero-copy view of the underlying `std::vector`.
12821    pub fn face_indices(&self) -> &[u16] {
12822        // SAFETY: `_data`/`_count` describe one contiguous C++
12823        // allocation, borrowed for as long as `self` is.
12824        unsafe {
12825            let n = ffi::whiteout_m3_M3HitTestShape_get_faceIndices_count(self.raw.as_ptr());
12826            let p = ffi::whiteout_m3_M3HitTestShape_get_faceIndices_data(self.raw.as_ptr());
12827            if p.is_null() || n == 0 {
12828                &[]
12829            } else {
12830                core::slice::from_raw_parts(p, n)
12831            }
12832        }
12833    }
12834
12835    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
12836    pub fn face_indices_mut(&mut self) -> &mut [u16] {
12837        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
12838        unsafe {
12839            let n = ffi::whiteout_m3_M3HitTestShape_get_faceIndices_count(self.raw.as_ptr());
12840            let p =
12841                ffi::whiteout_m3_M3HitTestShape_get_faceIndices_data(self.raw.as_ptr()) as *mut u16;
12842            if p.is_null() || n == 0 {
12843                &mut []
12844            } else {
12845                core::slice::from_raw_parts_mut(p, n)
12846            }
12847        }
12848    }
12849
12850    pub fn set_face_indices(&mut self, values: &[u16]) {
12851        // SAFETY: the native side copies `values` before returning.
12852        unsafe {
12853            ffi::whiteout_m3_M3HitTestShape_assign_faceIndices(
12854                self.raw.as_ptr(),
12855                values.as_ptr() as *const _,
12856                values.len(),
12857            )
12858        }
12859    }
12860
12861    pub fn resize_face_indices(&mut self, count: usize) {
12862        // SAFETY: reallocation is safe here precisely because
12863        // `&mut self` means no slice borrow is outstanding.
12864        unsafe { ffi::whiteout_m3_M3HitTestShape_resize_faceIndices(self.raw.as_ptr(), count) }
12865    }
12866
12867    /// X dimension (radius for sphere/capsule)
12868    pub fn size_x(&self) -> f32 {
12869        // SAFETY: plain scalar read through a live handle.
12870        unsafe { ffi::whiteout_m3_M3HitTestShape_get_sizeX(self.raw.as_ptr()) }
12871    }
12872
12873    pub fn set_size_x(&mut self, value: f32) {
12874        // SAFETY: plain scalar write through a live handle.
12875        unsafe { ffi::whiteout_m3_M3HitTestShape_set_sizeX(self.raw.as_ptr(), value) }
12876    }
12877
12878    /// Y dimension (height for capsule/cylinder)
12879    pub fn size_y(&self) -> f32 {
12880        // SAFETY: plain scalar read through a live handle.
12881        unsafe { ffi::whiteout_m3_M3HitTestShape_get_sizeY(self.raw.as_ptr()) }
12882    }
12883
12884    pub fn set_size_y(&mut self, value: f32) {
12885        // SAFETY: plain scalar write through a live handle.
12886        unsafe { ffi::whiteout_m3_M3HitTestShape_set_sizeY(self.raw.as_ptr(), value) }
12887    }
12888
12889    /// Z dimension
12890    pub fn size_z(&self) -> f32 {
12891        // SAFETY: plain scalar read through a live handle.
12892        unsafe { ffi::whiteout_m3_M3HitTestShape_get_sizeZ(self.raw.as_ptr()) }
12893    }
12894
12895    pub fn set_size_z(&mut self, value: f32) {
12896        // SAFETY: plain scalar write through a live handle.
12897        unsafe { ffi::whiteout_m3_M3HitTestShape_set_sizeZ(self.raw.as_ptr(), value) }
12898    }
12899}
12900
12901impl Default for HitTestShape {
12902    fn default() -> Self {
12903        Self::new()
12904    }
12905}
12906
12907/// ATVL — Attachment volume (v0, 116 bytes)
12908///
12909/// Like HitTestShape but with two bone indices for attachment-point volumes.
12910pub struct AttachmentVolume {
12911    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3AttachmentVolume>,
12912}
12913
12914impl Drop for AttachmentVolume {
12915    fn drop(&mut self) {
12916        // SAFETY: `raw` came from a native constructor and Drop runs once.
12917        unsafe { ffi::whiteout_m3_M3AttachmentVolume_delete(self.raw.as_ptr()) }
12918    }
12919}
12920
12921impl AttachmentVolume {
12922    /// # Safety
12923    /// `raw` must be a live handle this value takes ownership of.
12924    #[allow(dead_code)] // used by whichever methods return this type
12925    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3AttachmentVolume) -> Option<Self> {
12926        core::ptr::NonNull::new(raw).map(|raw| AttachmentVolume { raw })
12927    }
12928}
12929
12930// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
12931// is deliberately NOT implemented — the C++ types make no documented
12932// guarantee about concurrent use, and claiming one we haven't verified
12933// would be unsound. See `@bind thread_safe` in the plan.
12934unsafe impl Send for AttachmentVolume {}
12935
12936impl core::fmt::Debug for AttachmentVolume {
12937    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
12938        f.debug_struct("AttachmentVolume").finish_non_exhaustive()
12939    }
12940}
12941
12942impl AttachmentVolume {
12943    /// # Panics
12944    /// Panics if the native allocation fails.
12945    pub fn new() -> Self {
12946        // SAFETY: the native constructor returns a live handle; a null here
12947        // means the library is unusable.
12948        unsafe {
12949            let raw = ffi::whiteout_m3_M3AttachmentVolume_new();
12950            Self::from_raw(raw).expect("native AttachmentVolume allocation failed")
12951        }
12952    }
12953
12954    /// First bone index
12955    pub fn bone_1(&self) -> u32 {
12956        // SAFETY: plain scalar read through a live handle.
12957        unsafe { ffi::whiteout_m3_M3AttachmentVolume_get_bone1(self.raw.as_ptr()) }
12958    }
12959
12960    pub fn set_bone_1(&mut self, value: u32) {
12961        // SAFETY: plain scalar write through a live handle.
12962        unsafe { ffi::whiteout_m3_M3AttachmentVolume_set_bone1(self.raw.as_ptr(), value) }
12963    }
12964
12965    /// Second bone index
12966    pub fn bone_2(&self) -> u32 {
12967        // SAFETY: plain scalar read through a live handle.
12968        unsafe { ffi::whiteout_m3_M3AttachmentVolume_get_bone2(self.raw.as_ptr()) }
12969    }
12970
12971    pub fn set_bone_2(&mut self, value: u32) {
12972        // SAFETY: plain scalar write through a live handle.
12973        unsafe { ffi::whiteout_m3_M3AttachmentVolume_set_bone2(self.raw.as_ptr(), value) }
12974    }
12975
12976    /// Shape type
12977    pub fn shape_type(&self) -> HitTestShapeType {
12978        // SAFETY: scalar read; the discriminant is validated below.
12979        unsafe { ffi::whiteout_m3_M3AttachmentVolume_get_shapeType(self.raw.as_ptr()) }
12980            .try_into()
12981            .expect("unknown enum discriminant from the native library")
12982    }
12983
12984    pub fn set_shape_type(&mut self, value: HitTestShapeType) {
12985        // SAFETY: scalar write through a live handle.
12986        unsafe {
12987            ffi::whiteout_m3_M3AttachmentVolume_set_shapeType(self.raw.as_ptr(), value as i32)
12988        }
12989    }
12990
12991    /// Primary bone index
12992    pub fn bone_index(&self) -> u16 {
12993        // SAFETY: plain scalar read through a live handle.
12994        unsafe { ffi::whiteout_m3_M3AttachmentVolume_get_boneIndex(self.raw.as_ptr()) }
12995    }
12996
12997    pub fn set_bone_index(&mut self, value: u16) {
12998        // SAFETY: plain scalar write through a live handle.
12999        unsafe { ffi::whiteout_m3_M3AttachmentVolume_set_boneIndex(self.raw.as_ptr(), value) }
13000    }
13001
13002    /// Alignment padding
13003    pub fn padding(&self) -> u16 {
13004        // SAFETY: plain scalar read through a live handle.
13005        unsafe { ffi::whiteout_m3_M3AttachmentVolume_get_padding(self.raw.as_ptr()) }
13006    }
13007
13008    pub fn set_padding(&mut self, value: u16) {
13009        // SAFETY: plain scalar write through a live handle.
13010        unsafe { ffi::whiteout_m3_M3AttachmentVolume_set_padding(self.raw.as_ptr(), value) }
13011    }
13012
13013    /// Mesh vertex positions (VEC3)
13014    /// Zero-copy view of the underlying `std::vector`.
13015    pub fn vertex_positions(&self) -> &[crate::math::Vector3f] {
13016        // SAFETY: `_data`/`_count` describe one contiguous C++
13017        // allocation, borrowed for as long as `self` is.
13018        unsafe {
13019            let n =
13020                ffi::whiteout_m3_M3AttachmentVolume_get_vertexPositions_count(self.raw.as_ptr());
13021            let p = ffi::whiteout_m3_M3AttachmentVolume_get_vertexPositions_data(self.raw.as_ptr())
13022                as *const crate::math::Vector3f;
13023            if p.is_null() || n == 0 {
13024                &[]
13025            } else {
13026                core::slice::from_raw_parts(p, n)
13027            }
13028        }
13029    }
13030
13031    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
13032    pub fn vertex_positions_mut(&mut self) -> &mut [crate::math::Vector3f] {
13033        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
13034        unsafe {
13035            let n =
13036                ffi::whiteout_m3_M3AttachmentVolume_get_vertexPositions_count(self.raw.as_ptr());
13037            let p = ffi::whiteout_m3_M3AttachmentVolume_get_vertexPositions_data(self.raw.as_ptr())
13038                as *const crate::math::Vector3f as *mut crate::math::Vector3f;
13039            if p.is_null() || n == 0 {
13040                &mut []
13041            } else {
13042                core::slice::from_raw_parts_mut(p, n)
13043            }
13044        }
13045    }
13046
13047    pub fn set_vertex_positions(&mut self, values: &[crate::math::Vector3f]) {
13048        // SAFETY: the native side copies `values` before returning.
13049        unsafe {
13050            ffi::whiteout_m3_M3AttachmentVolume_assign_vertexPositions(
13051                self.raw.as_ptr(),
13052                values.as_ptr() as *const _,
13053                values.len(),
13054            )
13055        }
13056    }
13057
13058    pub fn resize_vertex_positions(&mut self, count: usize) {
13059        // SAFETY: reallocation is safe here precisely because
13060        // `&mut self` means no slice borrow is outstanding.
13061        unsafe {
13062            ffi::whiteout_m3_M3AttachmentVolume_resize_vertexPositions(self.raw.as_ptr(), count)
13063        }
13064    }
13065
13066    /// Mesh triangle indices (U16_)
13067    /// Zero-copy view of the underlying `std::vector`.
13068    pub fn face_indices(&self) -> &[u16] {
13069        // SAFETY: `_data`/`_count` describe one contiguous C++
13070        // allocation, borrowed for as long as `self` is.
13071        unsafe {
13072            let n = ffi::whiteout_m3_M3AttachmentVolume_get_faceIndices_count(self.raw.as_ptr());
13073            let p = ffi::whiteout_m3_M3AttachmentVolume_get_faceIndices_data(self.raw.as_ptr());
13074            if p.is_null() || n == 0 {
13075                &[]
13076            } else {
13077                core::slice::from_raw_parts(p, n)
13078            }
13079        }
13080    }
13081
13082    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
13083    pub fn face_indices_mut(&mut self) -> &mut [u16] {
13084        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
13085        unsafe {
13086            let n = ffi::whiteout_m3_M3AttachmentVolume_get_faceIndices_count(self.raw.as_ptr());
13087            let p = ffi::whiteout_m3_M3AttachmentVolume_get_faceIndices_data(self.raw.as_ptr())
13088                as *mut u16;
13089            if p.is_null() || n == 0 {
13090                &mut []
13091            } else {
13092                core::slice::from_raw_parts_mut(p, n)
13093            }
13094        }
13095    }
13096
13097    pub fn set_face_indices(&mut self, values: &[u16]) {
13098        // SAFETY: the native side copies `values` before returning.
13099        unsafe {
13100            ffi::whiteout_m3_M3AttachmentVolume_assign_faceIndices(
13101                self.raw.as_ptr(),
13102                values.as_ptr() as *const _,
13103                values.len(),
13104            )
13105        }
13106    }
13107
13108    pub fn resize_face_indices(&mut self, count: usize) {
13109        // SAFETY: reallocation is safe here precisely because
13110        // `&mut self` means no slice borrow is outstanding.
13111        unsafe { ffi::whiteout_m3_M3AttachmentVolume_resize_faceIndices(self.raw.as_ptr(), count) }
13112    }
13113
13114    /// X dimension
13115    pub fn size_x(&self) -> f32 {
13116        // SAFETY: plain scalar read through a live handle.
13117        unsafe { ffi::whiteout_m3_M3AttachmentVolume_get_sizeX(self.raw.as_ptr()) }
13118    }
13119
13120    pub fn set_size_x(&mut self, value: f32) {
13121        // SAFETY: plain scalar write through a live handle.
13122        unsafe { ffi::whiteout_m3_M3AttachmentVolume_set_sizeX(self.raw.as_ptr(), value) }
13123    }
13124
13125    /// Y dimension
13126    pub fn size_y(&self) -> f32 {
13127        // SAFETY: plain scalar read through a live handle.
13128        unsafe { ffi::whiteout_m3_M3AttachmentVolume_get_sizeY(self.raw.as_ptr()) }
13129    }
13130
13131    pub fn set_size_y(&mut self, value: f32) {
13132        // SAFETY: plain scalar write through a live handle.
13133        unsafe { ffi::whiteout_m3_M3AttachmentVolume_set_sizeY(self.raw.as_ptr(), value) }
13134    }
13135
13136    /// Z dimension
13137    pub fn size_z(&self) -> f32 {
13138        // SAFETY: plain scalar read through a live handle.
13139        unsafe { ffi::whiteout_m3_M3AttachmentVolume_get_sizeZ(self.raw.as_ptr()) }
13140    }
13141
13142    pub fn set_size_z(&mut self, value: f32) {
13143        // SAFETY: plain scalar write through a live handle.
13144        unsafe { ffi::whiteout_m3_M3AttachmentVolume_set_sizeZ(self.raw.as_ptr(), value) }
13145    }
13146}
13147
13148impl Default for AttachmentVolume {
13149    fn default() -> Self {
13150        Self::new()
13151    }
13152}
13153
13154/// TRGD — Trigger data (v0, 24 bytes)
13155///
13156/// Named trigger with associated data indices for gameplay events.
13157pub struct TriggerData {
13158    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3TriggerData>,
13159}
13160
13161impl Drop for TriggerData {
13162    fn drop(&mut self) {
13163        // SAFETY: `raw` came from a native constructor and Drop runs once.
13164        unsafe { ffi::whiteout_m3_M3TriggerData_delete(self.raw.as_ptr()) }
13165    }
13166}
13167
13168impl TriggerData {
13169    /// # Safety
13170    /// `raw` must be a live handle this value takes ownership of.
13171    #[allow(dead_code)] // used by whichever methods return this type
13172    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3TriggerData) -> Option<Self> {
13173        core::ptr::NonNull::new(raw).map(|raw| TriggerData { raw })
13174    }
13175}
13176
13177// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
13178// is deliberately NOT implemented — the C++ types make no documented
13179// guarantee about concurrent use, and claiming one we haven't verified
13180// would be unsound. See `@bind thread_safe` in the plan.
13181unsafe impl Send for TriggerData {}
13182
13183impl core::fmt::Debug for TriggerData {
13184    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
13185        f.debug_struct("TriggerData").finish_non_exhaustive()
13186    }
13187}
13188
13189impl TriggerData {
13190    /// # Panics
13191    /// Panics if the native allocation fails.
13192    pub fn new() -> Self {
13193        // SAFETY: the native constructor returns a live handle; a null here
13194        // means the library is unusable.
13195        unsafe {
13196            let raw = ffi::whiteout_m3_M3TriggerData_new();
13197            Self::from_raw(raw).expect("native TriggerData allocation failed")
13198        }
13199    }
13200
13201    /// Data index array (U32_)
13202    /// Zero-copy view of the underlying `std::vector`.
13203    pub fn data_indices(&self) -> &[u32] {
13204        // SAFETY: `_data`/`_count` describe one contiguous C++
13205        // allocation, borrowed for as long as `self` is.
13206        unsafe {
13207            let n = ffi::whiteout_m3_M3TriggerData_get_dataIndices_count(self.raw.as_ptr());
13208            let p = ffi::whiteout_m3_M3TriggerData_get_dataIndices_data(self.raw.as_ptr());
13209            if p.is_null() || n == 0 {
13210                &[]
13211            } else {
13212                core::slice::from_raw_parts(p, n)
13213            }
13214        }
13215    }
13216
13217    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
13218    pub fn data_indices_mut(&mut self) -> &mut [u32] {
13219        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
13220        unsafe {
13221            let n = ffi::whiteout_m3_M3TriggerData_get_dataIndices_count(self.raw.as_ptr());
13222            let p =
13223                ffi::whiteout_m3_M3TriggerData_get_dataIndices_data(self.raw.as_ptr()) as *mut u32;
13224            if p.is_null() || n == 0 {
13225                &mut []
13226            } else {
13227                core::slice::from_raw_parts_mut(p, n)
13228            }
13229        }
13230    }
13231
13232    pub fn set_data_indices(&mut self, values: &[u32]) {
13233        // SAFETY: the native side copies `values` before returning.
13234        unsafe {
13235            ffi::whiteout_m3_M3TriggerData_assign_dataIndices(
13236                self.raw.as_ptr(),
13237                values.as_ptr() as *const _,
13238                values.len(),
13239            )
13240        }
13241    }
13242
13243    pub fn resize_data_indices(&mut self, count: usize) {
13244        // SAFETY: reallocation is safe here precisely because
13245        // `&mut self` means no slice borrow is outstanding.
13246        unsafe { ffi::whiteout_m3_M3TriggerData_resize_dataIndices(self.raw.as_ptr(), count) }
13247    }
13248
13249    /// Trigger name (`Ref<CHAR>`)
13250    pub fn name(&self) -> String {
13251        // SAFETY: the native side hands over an owned CString.
13252        unsafe {
13253            crate::support::take_string(ffi::whiteout_m3_M3TriggerData_get_name(self.raw.as_ptr()))
13254        }
13255    }
13256
13257    pub fn set_name(&mut self, value: &str) {
13258        let value = std::ffi::CString::new(value).unwrap_or_default();
13259        // SAFETY: the pointer outlives the call.
13260        unsafe { ffi::whiteout_m3_M3TriggerData_set_name(self.raw.as_ptr(), value.as_ptr()) }
13261    }
13262}
13263
13264impl Default for TriggerData {
13265    fn default() -> Self {
13266        Self::new()
13267    }
13268}
13269
13270/// PATU — Turret behavior (v0–v4, 152 bytes)
13271///
13272/// Configures turret rotation constraints for a bone with yaw/pitch limits, weights, and an optional main-turret flag.
13273pub struct TurretBehavior {
13274    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3TurretBehavior>,
13275}
13276
13277impl Drop for TurretBehavior {
13278    fn drop(&mut self) {
13279        // SAFETY: `raw` came from a native constructor and Drop runs once.
13280        unsafe { ffi::whiteout_m3_M3TurretBehavior_delete(self.raw.as_ptr()) }
13281    }
13282}
13283
13284impl TurretBehavior {
13285    /// # Safety
13286    /// `raw` must be a live handle this value takes ownership of.
13287    #[allow(dead_code)] // used by whichever methods return this type
13288    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3TurretBehavior) -> Option<Self> {
13289        core::ptr::NonNull::new(raw).map(|raw| TurretBehavior { raw })
13290    }
13291}
13292
13293// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
13294// is deliberately NOT implemented — the C++ types make no documented
13295// guarantee about concurrent use, and claiming one we haven't verified
13296// would be unsound. See `@bind thread_safe` in the plan.
13297unsafe impl Send for TurretBehavior {}
13298
13299impl core::fmt::Debug for TurretBehavior {
13300    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
13301        f.debug_struct("TurretBehavior").finish_non_exhaustive()
13302    }
13303}
13304
13305impl TurretBehavior {
13306    /// # Panics
13307    /// Panics if the native allocation fails.
13308    pub fn new() -> Self {
13309        // SAFETY: the native constructor returns a live handle; a null here
13310        // means the library is unusable.
13311        unsafe {
13312            let raw = ffi::whiteout_m3_M3TurretBehavior_new();
13313            Self::from_raw(raw).expect("native TurretBehavior allocation failed")
13314        }
13315    }
13316
13317    /// Unknown vector 1
13318    pub fn unknown_1(&self) -> crate::math::Vector4f {
13319        // SAFETY: the getter returns an interior pointer to a
13320        // layout-identical POD; we copy it out immediately.
13321        unsafe {
13322            *(ffi::whiteout_m3_M3TurretBehavior_get_unknown1(self.raw.as_ptr())
13323                as *const crate::math::Vector4f)
13324        }
13325    }
13326
13327    pub fn set_unknown_1(&mut self, value: crate::math::Vector4f) {
13328        // SAFETY: as above, in the other direction.
13329        unsafe {
13330            ffi::whiteout_m3_M3TurretBehavior_set_unknown1(
13331                self.raw.as_ptr(),
13332                &value as *const crate::math::Vector4f as *const _,
13333            )
13334        }
13335    }
13336
13337    /// Unknown vector 2
13338    pub fn unknown_2(&self) -> crate::math::Vector4f {
13339        // SAFETY: the getter returns an interior pointer to a
13340        // layout-identical POD; we copy it out immediately.
13341        unsafe {
13342            *(ffi::whiteout_m3_M3TurretBehavior_get_unknown2(self.raw.as_ptr())
13343                as *const crate::math::Vector4f)
13344        }
13345    }
13346
13347    pub fn set_unknown_2(&mut self, value: crate::math::Vector4f) {
13348        // SAFETY: as above, in the other direction.
13349        unsafe {
13350            ffi::whiteout_m3_M3TurretBehavior_set_unknown2(
13351                self.raw.as_ptr(),
13352                &value as *const crate::math::Vector4f as *const _,
13353            )
13354        }
13355    }
13356
13357    /// Index into BONE array
13358    pub fn bone_index(&self) -> u16 {
13359        // SAFETY: plain scalar read through a live handle.
13360        unsafe { ffi::whiteout_m3_M3TurretBehavior_get_boneIndex(self.raw.as_ptr()) }
13361    }
13362
13363    pub fn set_bone_index(&mut self, value: u16) {
13364        // SAFETY: plain scalar write through a live handle.
13365        unsafe { ffi::whiteout_m3_M3TurretBehavior_set_boneIndex(self.raw.as_ptr(), value) }
13366    }
13367
13368    /// Non-zero if this is the main turret
13369    pub fn use_as_main_turret(&self) -> u8 {
13370        // SAFETY: plain scalar read through a live handle.
13371        unsafe { ffi::whiteout_m3_M3TurretBehavior_get_useAsMainTurret(self.raw.as_ptr()) }
13372    }
13373
13374    pub fn set_use_as_main_turret(&mut self, value: u8) {
13375        // SAFETY: plain scalar write through a live handle.
13376        unsafe { ffi::whiteout_m3_M3TurretBehavior_set_useAsMainTurret(self.raw.as_ptr(), value) }
13377    }
13378
13379    /// Turret group identifier
13380    pub fn turret_group_id(&self) -> u8 {
13381        // SAFETY: plain scalar read through a live handle.
13382        unsafe { ffi::whiteout_m3_M3TurretBehavior_get_turretGroupId(self.raw.as_ptr()) }
13383    }
13384
13385    pub fn set_turret_group_id(&mut self, value: u8) {
13386        // SAFETY: plain scalar write through a live handle.
13387        unsafe { ffi::whiteout_m3_M3TurretBehavior_set_turretGroupId(self.raw.as_ptr(), value) }
13388    }
13389
13390    /// Enable yaw limits
13391    pub fn yaw_limited(&self) -> u32 {
13392        // SAFETY: plain scalar read through a live handle.
13393        unsafe { ffi::whiteout_m3_M3TurretBehavior_get_yawLimited(self.raw.as_ptr()) }
13394    }
13395
13396    pub fn set_yaw_limited(&mut self, value: u32) {
13397        // SAFETY: plain scalar write through a live handle.
13398        unsafe { ffi::whiteout_m3_M3TurretBehavior_set_yawLimited(self.raw.as_ptr(), value) }
13399    }
13400
13401    /// Minimum yaw angle (radians)
13402    pub fn yaw_min(&self) -> f32 {
13403        // SAFETY: plain scalar read through a live handle.
13404        unsafe { ffi::whiteout_m3_M3TurretBehavior_get_yawMin(self.raw.as_ptr()) }
13405    }
13406
13407    pub fn set_yaw_min(&mut self, value: f32) {
13408        // SAFETY: plain scalar write through a live handle.
13409        unsafe { ffi::whiteout_m3_M3TurretBehavior_set_yawMin(self.raw.as_ptr(), value) }
13410    }
13411
13412    /// Maximum yaw angle (radians)
13413    pub fn yaw_max(&self) -> f32 {
13414        // SAFETY: plain scalar read through a live handle.
13415        unsafe { ffi::whiteout_m3_M3TurretBehavior_get_yawMax(self.raw.as_ptr()) }
13416    }
13417
13418    pub fn set_yaw_max(&mut self, value: f32) {
13419        // SAFETY: plain scalar write through a live handle.
13420        unsafe { ffi::whiteout_m3_M3TurretBehavior_set_yawMax(self.raw.as_ptr(), value) }
13421    }
13422
13423    /// Yaw rotation weight
13424    pub fn yaw_weight(&self) -> f32 {
13425        // SAFETY: plain scalar read through a live handle.
13426        unsafe { ffi::whiteout_m3_M3TurretBehavior_get_yawWeight(self.raw.as_ptr()) }
13427    }
13428
13429    pub fn set_yaw_weight(&mut self, value: f32) {
13430        // SAFETY: plain scalar write through a live handle.
13431        unsafe { ffi::whiteout_m3_M3TurretBehavior_set_yawWeight(self.raw.as_ptr(), value) }
13432    }
13433
13434    /// Enable pitch limits
13435    pub fn pitch_limited(&self) -> u32 {
13436        // SAFETY: plain scalar read through a live handle.
13437        unsafe { ffi::whiteout_m3_M3TurretBehavior_get_pitchLimited(self.raw.as_ptr()) }
13438    }
13439
13440    pub fn set_pitch_limited(&mut self, value: u32) {
13441        // SAFETY: plain scalar write through a live handle.
13442        unsafe { ffi::whiteout_m3_M3TurretBehavior_set_pitchLimited(self.raw.as_ptr(), value) }
13443    }
13444
13445    /// Minimum pitch angle (radians)
13446    pub fn pitch_min(&self) -> f32 {
13447        // SAFETY: plain scalar read through a live handle.
13448        unsafe { ffi::whiteout_m3_M3TurretBehavior_get_pitchMin(self.raw.as_ptr()) }
13449    }
13450
13451    pub fn set_pitch_min(&mut self, value: f32) {
13452        // SAFETY: plain scalar write through a live handle.
13453        unsafe { ffi::whiteout_m3_M3TurretBehavior_set_pitchMin(self.raw.as_ptr(), value) }
13454    }
13455
13456    /// Maximum pitch angle (radians)
13457    pub fn pitch_max(&self) -> f32 {
13458        // SAFETY: plain scalar read through a live handle.
13459        unsafe { ffi::whiteout_m3_M3TurretBehavior_get_pitchMax(self.raw.as_ptr()) }
13460    }
13461
13462    pub fn set_pitch_max(&mut self, value: f32) {
13463        // SAFETY: plain scalar write through a live handle.
13464        unsafe { ffi::whiteout_m3_M3TurretBehavior_set_pitchMax(self.raw.as_ptr(), value) }
13465    }
13466
13467    /// Pitch rotation weight
13468    pub fn pitch_weight(&self) -> f32 {
13469        // SAFETY: plain scalar read through a live handle.
13470        unsafe { ffi::whiteout_m3_M3TurretBehavior_get_pitchWeight(self.raw.as_ptr()) }
13471    }
13472
13473    pub fn set_pitch_weight(&mut self, value: f32) {
13474        // SAFETY: plain scalar write through a live handle.
13475        unsafe { ffi::whiteout_m3_M3TurretBehavior_set_pitchWeight(self.raw.as_ptr(), value) }
13476    }
13477
13478    /// Unknown field
13479    pub fn unknown_3(&self) -> f32 {
13480        // SAFETY: plain scalar read through a live handle.
13481        unsafe { ffi::whiteout_m3_M3TurretBehavior_get_unknown3(self.raw.as_ptr()) }
13482    }
13483
13484    pub fn set_unknown_3(&mut self, value: f32) {
13485        // SAFETY: plain scalar write through a live handle.
13486        unsafe { ffi::whiteout_m3_M3TurretBehavior_set_unknown3(self.raw.as_ptr(), value) }
13487    }
13488
13489    /// Unknown field
13490    pub fn unknown_4(&self) -> f32 {
13491        // SAFETY: plain scalar read through a live handle.
13492        unsafe { ffi::whiteout_m3_M3TurretBehavior_get_unknown4(self.raw.as_ptr()) }
13493    }
13494
13495    pub fn set_unknown_4(&mut self, value: f32) {
13496        // SAFETY: plain scalar write through a live handle.
13497        unsafe { ffi::whiteout_m3_M3TurretBehavior_set_unknown4(self.raw.as_ptr(), value) }
13498    }
13499
13500    /// Offset from main bone
13501    pub fn main_bone_offset(&self) -> crate::math::Vector3f {
13502        // SAFETY: the getter returns an interior pointer to a
13503        // layout-identical POD; we copy it out immediately.
13504        unsafe {
13505            *(ffi::whiteout_m3_M3TurretBehavior_get_mainBoneOffset(self.raw.as_ptr())
13506                as *const crate::math::Vector3f)
13507        }
13508    }
13509
13510    pub fn set_main_bone_offset(&mut self, value: crate::math::Vector3f) {
13511        // SAFETY: as above, in the other direction.
13512        unsafe {
13513            ffi::whiteout_m3_M3TurretBehavior_set_mainBoneOffset(
13514                self.raw.as_ptr(),
13515                &value as *const crate::math::Vector3f as *const _,
13516            )
13517        }
13518    }
13519}
13520
13521impl Default for TurretBehavior {
13522    fn default() -> Self {
13523        Self::new()
13524    }
13525}
13526
13527/// BBSC — Billboard behavior (v0, 48 bytes)
13528///
13529/// Makes a bone always face the camera or a specified direction.
13530pub struct BillboardBehavior {
13531    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3BillboardBehavior>,
13532}
13533
13534impl Drop for BillboardBehavior {
13535    fn drop(&mut self) {
13536        // SAFETY: `raw` came from a native constructor and Drop runs once.
13537        unsafe { ffi::whiteout_m3_M3BillboardBehavior_delete(self.raw.as_ptr()) }
13538    }
13539}
13540
13541impl BillboardBehavior {
13542    /// # Safety
13543    /// `raw` must be a live handle this value takes ownership of.
13544    #[allow(dead_code)] // used by whichever methods return this type
13545    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3BillboardBehavior) -> Option<Self> {
13546        core::ptr::NonNull::new(raw).map(|raw| BillboardBehavior { raw })
13547    }
13548}
13549
13550// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
13551// is deliberately NOT implemented — the C++ types make no documented
13552// guarantee about concurrent use, and claiming one we haven't verified
13553// would be unsound. See `@bind thread_safe` in the plan.
13554unsafe impl Send for BillboardBehavior {}
13555
13556impl core::fmt::Debug for BillboardBehavior {
13557    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
13558        f.debug_struct("BillboardBehavior").finish_non_exhaustive()
13559    }
13560}
13561
13562impl BillboardBehavior {
13563    /// # Panics
13564    /// Panics if the native allocation fails.
13565    pub fn new() -> Self {
13566        // SAFETY: the native constructor returns a live handle; a null here
13567        // means the library is unusable.
13568        unsafe {
13569            let raw = ffi::whiteout_m3_M3BillboardBehavior_new();
13570            Self::from_raw(raw).expect("native BillboardBehavior allocation failed")
13571        }
13572    }
13573
13574    /// Dependent bone indices (U16_)
13575    /// Zero-copy view of the underlying `std::vector`.
13576    pub fn dependents(&self) -> &[u16] {
13577        // SAFETY: `_data`/`_count` describe one contiguous C++
13578        // allocation, borrowed for as long as `self` is.
13579        unsafe {
13580            let n = ffi::whiteout_m3_M3BillboardBehavior_get_dependents_count(self.raw.as_ptr());
13581            let p = ffi::whiteout_m3_M3BillboardBehavior_get_dependents_data(self.raw.as_ptr());
13582            if p.is_null() || n == 0 {
13583                &[]
13584            } else {
13585                core::slice::from_raw_parts(p, n)
13586            }
13587        }
13588    }
13589
13590    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
13591    pub fn dependents_mut(&mut self) -> &mut [u16] {
13592        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
13593        unsafe {
13594            let n = ffi::whiteout_m3_M3BillboardBehavior_get_dependents_count(self.raw.as_ptr());
13595            let p = ffi::whiteout_m3_M3BillboardBehavior_get_dependents_data(self.raw.as_ptr())
13596                as *mut u16;
13597            if p.is_null() || n == 0 {
13598                &mut []
13599            } else {
13600                core::slice::from_raw_parts_mut(p, n)
13601            }
13602        }
13603    }
13604
13605    pub fn set_dependents(&mut self, values: &[u16]) {
13606        // SAFETY: the native side copies `values` before returning.
13607        unsafe {
13608            ffi::whiteout_m3_M3BillboardBehavior_assign_dependents(
13609                self.raw.as_ptr(),
13610                values.as_ptr() as *const _,
13611                values.len(),
13612            )
13613        }
13614    }
13615
13616    pub fn resize_dependents(&mut self, count: usize) {
13617        // SAFETY: reallocation is safe here precisely because
13618        // `&mut self` means no slice borrow is outstanding.
13619        unsafe { ffi::whiteout_m3_M3BillboardBehavior_resize_dependents(self.raw.as_ptr(), count) }
13620    }
13621
13622    /// Index into BONE array
13623    pub fn bone_index(&self) -> u16 {
13624        // SAFETY: plain scalar read through a live handle.
13625        unsafe { ffi::whiteout_m3_M3BillboardBehavior_get_boneIndex(self.raw.as_ptr()) }
13626    }
13627
13628    pub fn set_bone_index(&mut self, value: u16) {
13629        // SAFETY: plain scalar write through a live handle.
13630        unsafe { ffi::whiteout_m3_M3BillboardBehavior_set_boneIndex(self.raw.as_ptr(), value) }
13631    }
13632
13633    /// Billboard mode type
13634    pub fn billboard_type(&self) -> u8 {
13635        // SAFETY: plain scalar read through a live handle.
13636        unsafe { ffi::whiteout_m3_M3BillboardBehavior_get_billboardType(self.raw.as_ptr()) }
13637    }
13638
13639    pub fn set_billboard_type(&mut self, value: u8) {
13640        // SAFETY: plain scalar write through a live handle.
13641        unsafe { ffi::whiteout_m3_M3BillboardBehavior_set_billboardType(self.raw.as_ptr(), value) }
13642    }
13643
13644    /// Camera look-at flag (default: enabled)
13645    pub fn camera_look_at(&self) -> u8 {
13646        // SAFETY: plain scalar read through a live handle.
13647        unsafe { ffi::whiteout_m3_M3BillboardBehavior_get_cameraLookAt(self.raw.as_ptr()) }
13648    }
13649
13650    pub fn set_camera_look_at(&mut self, value: u8) {
13651        // SAFETY: plain scalar write through a live handle.
13652        unsafe { ffi::whiteout_m3_M3BillboardBehavior_set_cameraLookAt(self.raw.as_ptr(), value) }
13653    }
13654
13655    /// Up direction quaternion
13656    pub fn up(&self) -> crate::math::Quaternion {
13657        // SAFETY: the getter returns an interior pointer to a
13658        // layout-identical POD; we copy it out immediately.
13659        unsafe {
13660            *(ffi::whiteout_m3_M3BillboardBehavior_get_up(self.raw.as_ptr())
13661                as *const crate::math::Quaternion)
13662        }
13663    }
13664
13665    pub fn set_up(&mut self, value: crate::math::Quaternion) {
13666        // SAFETY: as above, in the other direction.
13667        unsafe {
13668            ffi::whiteout_m3_M3BillboardBehavior_set_up(
13669                self.raw.as_ptr(),
13670                &value as *const crate::math::Quaternion as *const _,
13671            )
13672        }
13673    }
13674
13675    /// Forward direction quaternion
13676    pub fn forward(&self) -> crate::math::Quaternion {
13677        // SAFETY: the getter returns an interior pointer to a
13678        // layout-identical POD; we copy it out immediately.
13679        unsafe {
13680            *(ffi::whiteout_m3_M3BillboardBehavior_get_forward(self.raw.as_ptr())
13681                as *const crate::math::Quaternion)
13682        }
13683    }
13684
13685    pub fn set_forward(&mut self, value: crate::math::Quaternion) {
13686        // SAFETY: as above, in the other direction.
13687        unsafe {
13688            ffi::whiteout_m3_M3BillboardBehavior_set_forward(
13689                self.raw.as_ptr(),
13690                &value as *const crate::math::Quaternion as *const _,
13691            )
13692        }
13693    }
13694}
13695
13696impl Default for BillboardBehavior {
13697    fn default() -> Self {
13698        Self::new()
13699    }
13700}
13701
13702/// IKJT — IK joint (v0, 32 bytes)
13703///
13704/// Inverse kinematics joint with raycast up/down range, max speed, and goal threshold for terrain-following or foot-planting.
13705pub struct IKJoint {
13706    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3IKJoint>,
13707}
13708
13709impl Drop for IKJoint {
13710    fn drop(&mut self) {
13711        // SAFETY: `raw` came from a native constructor and Drop runs once.
13712        unsafe { ffi::whiteout_m3_M3IKJoint_delete(self.raw.as_ptr()) }
13713    }
13714}
13715
13716impl IKJoint {
13717    /// # Safety
13718    /// `raw` must be a live handle this value takes ownership of.
13719    #[allow(dead_code)] // used by whichever methods return this type
13720    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3IKJoint) -> Option<Self> {
13721        core::ptr::NonNull::new(raw).map(|raw| IKJoint { raw })
13722    }
13723}
13724
13725// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
13726// is deliberately NOT implemented — the C++ types make no documented
13727// guarantee about concurrent use, and claiming one we haven't verified
13728// would be unsound. See `@bind thread_safe` in the plan.
13729unsafe impl Send for IKJoint {}
13730
13731impl core::fmt::Debug for IKJoint {
13732    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
13733        f.debug_struct("IKJoint").finish_non_exhaustive()
13734    }
13735}
13736
13737impl IKJoint {
13738    /// # Panics
13739    /// Panics if the native allocation fails.
13740    pub fn new() -> Self {
13741        // SAFETY: the native constructor returns a live handle; a null here
13742        // means the library is unusable.
13743        unsafe {
13744            let raw = ffi::whiteout_m3_M3IKJoint_new();
13745            Self::from_raw(raw).expect("native IKJoint allocation failed")
13746        }
13747    }
13748
13749    /// Dependent bone indices (U16_)
13750    /// Zero-copy view of the underlying `std::vector`.
13751    pub fn dependents(&self) -> &[u16] {
13752        // SAFETY: `_data`/`_count` describe one contiguous C++
13753        // allocation, borrowed for as long as `self` is.
13754        unsafe {
13755            let n = ffi::whiteout_m3_M3IKJoint_get_dependents_count(self.raw.as_ptr());
13756            let p = ffi::whiteout_m3_M3IKJoint_get_dependents_data(self.raw.as_ptr());
13757            if p.is_null() || n == 0 {
13758                &[]
13759            } else {
13760                core::slice::from_raw_parts(p, n)
13761            }
13762        }
13763    }
13764
13765    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
13766    pub fn dependents_mut(&mut self) -> &mut [u16] {
13767        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
13768        unsafe {
13769            let n = ffi::whiteout_m3_M3IKJoint_get_dependents_count(self.raw.as_ptr());
13770            let p = ffi::whiteout_m3_M3IKJoint_get_dependents_data(self.raw.as_ptr()) as *mut u16;
13771            if p.is_null() || n == 0 {
13772                &mut []
13773            } else {
13774                core::slice::from_raw_parts_mut(p, n)
13775            }
13776        }
13777    }
13778
13779    pub fn set_dependents(&mut self, values: &[u16]) {
13780        // SAFETY: the native side copies `values` before returning.
13781        unsafe {
13782            ffi::whiteout_m3_M3IKJoint_assign_dependents(
13783                self.raw.as_ptr(),
13784                values.as_ptr() as *const _,
13785                values.len(),
13786            )
13787        }
13788    }
13789
13790    pub fn resize_dependents(&mut self, count: usize) {
13791        // SAFETY: reallocation is safe here precisely because
13792        // `&mut self` means no slice borrow is outstanding.
13793        unsafe { ffi::whiteout_m3_M3IKJoint_resize_dependents(self.raw.as_ptr(), count) }
13794    }
13795
13796    /// First bone index
13797    pub fn bone_index_1(&self) -> u16 {
13798        // SAFETY: plain scalar read through a live handle.
13799        unsafe { ffi::whiteout_m3_M3IKJoint_get_boneIndex1(self.raw.as_ptr()) }
13800    }
13801
13802    pub fn set_bone_index_1(&mut self, value: u16) {
13803        // SAFETY: plain scalar write through a live handle.
13804        unsafe { ffi::whiteout_m3_M3IKJoint_set_boneIndex1(self.raw.as_ptr(), value) }
13805    }
13806
13807    /// Second bone index
13808    pub fn bone_index_2(&self) -> u16 {
13809        // SAFETY: plain scalar read through a live handle.
13810        unsafe { ffi::whiteout_m3_M3IKJoint_get_boneIndex2(self.raw.as_ptr()) }
13811    }
13812
13813    pub fn set_bone_index_2(&mut self, value: u16) {
13814        // SAFETY: plain scalar write through a live handle.
13815        unsafe { ffi::whiteout_m3_M3IKJoint_set_boneIndex2(self.raw.as_ptr(), value) }
13816    }
13817
13818    /// Raycast upward distance
13819    pub fn raycast_up(&self) -> f32 {
13820        // SAFETY: plain scalar read through a live handle.
13821        unsafe { ffi::whiteout_m3_M3IKJoint_get_raycastUp(self.raw.as_ptr()) }
13822    }
13823
13824    pub fn set_raycast_up(&mut self, value: f32) {
13825        // SAFETY: plain scalar write through a live handle.
13826        unsafe { ffi::whiteout_m3_M3IKJoint_set_raycastUp(self.raw.as_ptr(), value) }
13827    }
13828
13829    /// Raycast downward distance
13830    pub fn raycast_down(&self) -> f32 {
13831        // SAFETY: plain scalar read through a live handle.
13832        unsafe { ffi::whiteout_m3_M3IKJoint_get_raycastDown(self.raw.as_ptr()) }
13833    }
13834
13835    pub fn set_raycast_down(&mut self, value: f32) {
13836        // SAFETY: plain scalar write through a live handle.
13837        unsafe { ffi::whiteout_m3_M3IKJoint_set_raycastDown(self.raw.as_ptr(), value) }
13838    }
13839
13840    /// Maximum IK solving speed
13841    pub fn max_speed(&self) -> f32 {
13842        // SAFETY: plain scalar read through a live handle.
13843        unsafe { ffi::whiteout_m3_M3IKJoint_get_maxSpeed(self.raw.as_ptr()) }
13844    }
13845
13846    pub fn set_max_speed(&mut self, value: f32) {
13847        // SAFETY: plain scalar write through a live handle.
13848        unsafe { ffi::whiteout_m3_M3IKJoint_set_maxSpeed(self.raw.as_ptr(), value) }
13849    }
13850
13851    /// Goal distance threshold
13852    pub fn goal_threshold(&self) -> f32 {
13853        // SAFETY: plain scalar read through a live handle.
13854        unsafe { ffi::whiteout_m3_M3IKJoint_get_goalThreshold(self.raw.as_ptr()) }
13855    }
13856
13857    pub fn set_goal_threshold(&mut self, value: f32) {
13858        // SAFETY: plain scalar write through a live handle.
13859        unsafe { ffi::whiteout_m3_M3IKJoint_set_goalThreshold(self.raw.as_ptr(), value) }
13860    }
13861}
13862
13863impl Default for IKJoint {
13864    fn default() -> Self {
13865        Self::new()
13866    }
13867}
13868
13869/// IK2J — Two-joint IK solver (v0, 48 bytes)
13870///
13871/// Classic two-bone IK (e.g. elbow/knee) with hinge axis, angle limits, and search range for target acquisition.
13872pub struct IKTwoJoint {
13873    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3IKTwoJoint>,
13874}
13875
13876impl Drop for IKTwoJoint {
13877    fn drop(&mut self) {
13878        // SAFETY: `raw` came from a native constructor and Drop runs once.
13879        unsafe { ffi::whiteout_m3_M3IKTwoJoint_delete(self.raw.as_ptr()) }
13880    }
13881}
13882
13883impl IKTwoJoint {
13884    /// # Safety
13885    /// `raw` must be a live handle this value takes ownership of.
13886    #[allow(dead_code)] // used by whichever methods return this type
13887    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3IKTwoJoint) -> Option<Self> {
13888        core::ptr::NonNull::new(raw).map(|raw| IKTwoJoint { raw })
13889    }
13890}
13891
13892// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
13893// is deliberately NOT implemented — the C++ types make no documented
13894// guarantee about concurrent use, and claiming one we haven't verified
13895// would be unsound. See `@bind thread_safe` in the plan.
13896unsafe impl Send for IKTwoJoint {}
13897
13898impl core::fmt::Debug for IKTwoJoint {
13899    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
13900        f.debug_struct("IKTwoJoint").finish_non_exhaustive()
13901    }
13902}
13903
13904impl IKTwoJoint {
13905    /// # Panics
13906    /// Panics if the native allocation fails.
13907    pub fn new() -> Self {
13908        // SAFETY: the native constructor returns a live handle; a null here
13909        // means the library is unusable.
13910        unsafe {
13911            let raw = ffi::whiteout_m3_M3IKTwoJoint_new();
13912            Self::from_raw(raw).expect("native IKTwoJoint allocation failed")
13913        }
13914    }
13915
13916    /// Dependent bone indices (U16_)
13917    /// Zero-copy view of the underlying `std::vector`.
13918    pub fn dependents(&self) -> &[u16] {
13919        // SAFETY: `_data`/`_count` describe one contiguous C++
13920        // allocation, borrowed for as long as `self` is.
13921        unsafe {
13922            let n = ffi::whiteout_m3_M3IKTwoJoint_get_dependents_count(self.raw.as_ptr());
13923            let p = ffi::whiteout_m3_M3IKTwoJoint_get_dependents_data(self.raw.as_ptr());
13924            if p.is_null() || n == 0 {
13925                &[]
13926            } else {
13927                core::slice::from_raw_parts(p, n)
13928            }
13929        }
13930    }
13931
13932    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
13933    pub fn dependents_mut(&mut self) -> &mut [u16] {
13934        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
13935        unsafe {
13936            let n = ffi::whiteout_m3_M3IKTwoJoint_get_dependents_count(self.raw.as_ptr());
13937            let p =
13938                ffi::whiteout_m3_M3IKTwoJoint_get_dependents_data(self.raw.as_ptr()) as *mut u16;
13939            if p.is_null() || n == 0 {
13940                &mut []
13941            } else {
13942                core::slice::from_raw_parts_mut(p, n)
13943            }
13944        }
13945    }
13946
13947    pub fn set_dependents(&mut self, values: &[u16]) {
13948        // SAFETY: the native side copies `values` before returning.
13949        unsafe {
13950            ffi::whiteout_m3_M3IKTwoJoint_assign_dependents(
13951                self.raw.as_ptr(),
13952                values.as_ptr() as *const _,
13953                values.len(),
13954            )
13955        }
13956    }
13957
13958    pub fn resize_dependents(&mut self, count: usize) {
13959        // SAFETY: reallocation is safe here precisely because
13960        // `&mut self` means no slice borrow is outstanding.
13961        unsafe { ffi::whiteout_m3_M3IKTwoJoint_resize_dependents(self.raw.as_ptr(), count) }
13962    }
13963
13964    /// Base bone (e.g. upper arm/thigh)
13965    pub fn bone_base(&self) -> u16 {
13966        // SAFETY: plain scalar read through a live handle.
13967        unsafe { ffi::whiteout_m3_M3IKTwoJoint_get_boneBase(self.raw.as_ptr()) }
13968    }
13969
13970    pub fn set_bone_base(&mut self, value: u16) {
13971        // SAFETY: plain scalar write through a live handle.
13972        unsafe { ffi::whiteout_m3_M3IKTwoJoint_set_boneBase(self.raw.as_ptr(), value) }
13973    }
13974
13975    /// Target bone (e.g. forearm/shin)
13976    pub fn bone_target(&self) -> u16 {
13977        // SAFETY: plain scalar read through a live handle.
13978        unsafe { ffi::whiteout_m3_M3IKTwoJoint_get_boneTarget(self.raw.as_ptr()) }
13979    }
13980
13981    pub fn set_bone_target(&mut self, value: u16) {
13982        // SAFETY: plain scalar write through a live handle.
13983        unsafe { ffi::whiteout_m3_M3IKTwoJoint_set_boneTarget(self.raw.as_ptr(), value) }
13984    }
13985
13986    /// End effector bone (e.g. hand/foot)
13987    pub fn bone_end(&self) -> u16 {
13988        // SAFETY: plain scalar read through a live handle.
13989        unsafe { ffi::whiteout_m3_M3IKTwoJoint_get_boneEnd(self.raw.as_ptr()) }
13990    }
13991
13992    pub fn set_bone_end(&mut self, value: u16) {
13993        // SAFETY: plain scalar write through a live handle.
13994        unsafe { ffi::whiteout_m3_M3IKTwoJoint_set_boneEnd(self.raw.as_ptr(), value) }
13995    }
13996
13997    /// Alignment padding
13998    pub fn padding(&self) -> u16 {
13999        // SAFETY: plain scalar read through a live handle.
14000        unsafe { ffi::whiteout_m3_M3IKTwoJoint_get_padding(self.raw.as_ptr()) }
14001    }
14002
14003    pub fn set_padding(&mut self, value: u16) {
14004        // SAFETY: plain scalar write through a live handle.
14005        unsafe { ffi::whiteout_m3_M3IKTwoJoint_set_padding(self.raw.as_ptr(), value) }
14006    }
14007
14008    /// Hinge rotation axis
14009    pub fn hinge_axis(&self) -> crate::math::Vector3f {
14010        // SAFETY: the getter returns an interior pointer to a
14011        // layout-identical POD; we copy it out immediately.
14012        unsafe {
14013            *(ffi::whiteout_m3_M3IKTwoJoint_get_hingeAxis(self.raw.as_ptr())
14014                as *const crate::math::Vector3f)
14015        }
14016    }
14017
14018    pub fn set_hinge_axis(&mut self, value: crate::math::Vector3f) {
14019        // SAFETY: as above, in the other direction.
14020        unsafe {
14021            ffi::whiteout_m3_M3IKTwoJoint_set_hingeAxis(
14022                self.raw.as_ptr(),
14023                &value as *const crate::math::Vector3f as *const _,
14024            )
14025        }
14026    }
14027
14028    /// Maximum inner angle
14029    pub fn max_angle_inner(&self) -> f32 {
14030        // SAFETY: plain scalar read through a live handle.
14031        unsafe { ffi::whiteout_m3_M3IKTwoJoint_get_maxAngleInner(self.raw.as_ptr()) }
14032    }
14033
14034    pub fn set_max_angle_inner(&mut self, value: f32) {
14035        // SAFETY: plain scalar write through a live handle.
14036        unsafe { ffi::whiteout_m3_M3IKTwoJoint_set_maxAngleInner(self.raw.as_ptr(), value) }
14037    }
14038
14039    /// Maximum outer angle
14040    pub fn max_angle_outer(&self) -> f32 {
14041        // SAFETY: plain scalar read through a live handle.
14042        unsafe { ffi::whiteout_m3_M3IKTwoJoint_get_maxAngleOuter(self.raw.as_ptr()) }
14043    }
14044
14045    pub fn set_max_angle_outer(&mut self, value: f32) {
14046        // SAFETY: plain scalar write through a live handle.
14047        unsafe { ffi::whiteout_m3_M3IKTwoJoint_set_maxAngleOuter(self.raw.as_ptr(), value) }
14048    }
14049
14050    /// Search range upward
14051    pub fn search_up(&self) -> f32 {
14052        // SAFETY: plain scalar read through a live handle.
14053        unsafe { ffi::whiteout_m3_M3IKTwoJoint_get_searchUp(self.raw.as_ptr()) }
14054    }
14055
14056    pub fn set_search_up(&mut self, value: f32) {
14057        // SAFETY: plain scalar write through a live handle.
14058        unsafe { ffi::whiteout_m3_M3IKTwoJoint_set_searchUp(self.raw.as_ptr(), value) }
14059    }
14060
14061    /// Search range downward
14062    pub fn search_down(&self) -> f32 {
14063        // SAFETY: plain scalar read through a live handle.
14064        unsafe { ffi::whiteout_m3_M3IKTwoJoint_get_searchDown(self.raw.as_ptr()) }
14065    }
14066
14067    pub fn set_search_down(&mut self, value: f32) {
14068        // SAFETY: plain scalar write through a live handle.
14069        unsafe { ffi::whiteout_m3_M3IKTwoJoint_set_searchDown(self.raw.as_ptr(), value) }
14070    }
14071}
14072
14073impl Default for IKTwoJoint {
14074    fn default() -> Self {
14075        Self::new()
14076    }
14077}
14078
14079/// IKCC — CCD IK solver (v0, 24 bytes)
14080///
14081/// Cyclic Coordinate Descent IK solver with base/target bones and vertical search range.
14082pub struct IKCCD {
14083    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3IKCCD>,
14084}
14085
14086impl Drop for IKCCD {
14087    fn drop(&mut self) {
14088        // SAFETY: `raw` came from a native constructor and Drop runs once.
14089        unsafe { ffi::whiteout_m3_M3IKCCD_delete(self.raw.as_ptr()) }
14090    }
14091}
14092
14093impl IKCCD {
14094    /// # Safety
14095    /// `raw` must be a live handle this value takes ownership of.
14096    #[allow(dead_code)] // used by whichever methods return this type
14097    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3IKCCD) -> Option<Self> {
14098        core::ptr::NonNull::new(raw).map(|raw| IKCCD { raw })
14099    }
14100}
14101
14102// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
14103// is deliberately NOT implemented — the C++ types make no documented
14104// guarantee about concurrent use, and claiming one we haven't verified
14105// would be unsound. See `@bind thread_safe` in the plan.
14106unsafe impl Send for IKCCD {}
14107
14108impl core::fmt::Debug for IKCCD {
14109    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
14110        f.debug_struct("IKCCD").finish_non_exhaustive()
14111    }
14112}
14113
14114impl IKCCD {
14115    /// # Panics
14116    /// Panics if the native allocation fails.
14117    pub fn new() -> Self {
14118        // SAFETY: the native constructor returns a live handle; a null here
14119        // means the library is unusable.
14120        unsafe {
14121            let raw = ffi::whiteout_m3_M3IKCCD_new();
14122            Self::from_raw(raw).expect("native IKCCD allocation failed")
14123        }
14124    }
14125
14126    /// Dependent bone indices (U16_)
14127    /// Zero-copy view of the underlying `std::vector`.
14128    pub fn dependents(&self) -> &[u16] {
14129        // SAFETY: `_data`/`_count` describe one contiguous C++
14130        // allocation, borrowed for as long as `self` is.
14131        unsafe {
14132            let n = ffi::whiteout_m3_M3IKCCD_get_dependents_count(self.raw.as_ptr());
14133            let p = ffi::whiteout_m3_M3IKCCD_get_dependents_data(self.raw.as_ptr());
14134            if p.is_null() || n == 0 {
14135                &[]
14136            } else {
14137                core::slice::from_raw_parts(p, n)
14138            }
14139        }
14140    }
14141
14142    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
14143    pub fn dependents_mut(&mut self) -> &mut [u16] {
14144        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
14145        unsafe {
14146            let n = ffi::whiteout_m3_M3IKCCD_get_dependents_count(self.raw.as_ptr());
14147            let p = ffi::whiteout_m3_M3IKCCD_get_dependents_data(self.raw.as_ptr()) as *mut u16;
14148            if p.is_null() || n == 0 {
14149                &mut []
14150            } else {
14151                core::slice::from_raw_parts_mut(p, n)
14152            }
14153        }
14154    }
14155
14156    pub fn set_dependents(&mut self, values: &[u16]) {
14157        // SAFETY: the native side copies `values` before returning.
14158        unsafe {
14159            ffi::whiteout_m3_M3IKCCD_assign_dependents(
14160                self.raw.as_ptr(),
14161                values.as_ptr() as *const _,
14162                values.len(),
14163            )
14164        }
14165    }
14166
14167    pub fn resize_dependents(&mut self, count: usize) {
14168        // SAFETY: reallocation is safe here precisely because
14169        // `&mut self` means no slice borrow is outstanding.
14170        unsafe { ffi::whiteout_m3_M3IKCCD_resize_dependents(self.raw.as_ptr(), count) }
14171    }
14172
14173    /// Base bone index
14174    pub fn bone_base(&self) -> u16 {
14175        // SAFETY: plain scalar read through a live handle.
14176        unsafe { ffi::whiteout_m3_M3IKCCD_get_boneBase(self.raw.as_ptr()) }
14177    }
14178
14179    pub fn set_bone_base(&mut self, value: u16) {
14180        // SAFETY: plain scalar write through a live handle.
14181        unsafe { ffi::whiteout_m3_M3IKCCD_set_boneBase(self.raw.as_ptr(), value) }
14182    }
14183
14184    /// Target bone index
14185    pub fn bone_target(&self) -> u16 {
14186        // SAFETY: plain scalar read through a live handle.
14187        unsafe { ffi::whiteout_m3_M3IKCCD_get_boneTarget(self.raw.as_ptr()) }
14188    }
14189
14190    pub fn set_bone_target(&mut self, value: u16) {
14191        // SAFETY: plain scalar write through a live handle.
14192        unsafe { ffi::whiteout_m3_M3IKCCD_set_boneTarget(self.raw.as_ptr(), value) }
14193    }
14194
14195    /// Search range upward
14196    pub fn search_up(&self) -> f32 {
14197        // SAFETY: plain scalar read through a live handle.
14198        unsafe { ffi::whiteout_m3_M3IKCCD_get_searchUp(self.raw.as_ptr()) }
14199    }
14200
14201    pub fn set_search_up(&mut self, value: f32) {
14202        // SAFETY: plain scalar write through a live handle.
14203        unsafe { ffi::whiteout_m3_M3IKCCD_set_searchUp(self.raw.as_ptr(), value) }
14204    }
14205
14206    /// Search range downward
14207    pub fn search_down(&self) -> f32 {
14208        // SAFETY: plain scalar read through a live handle.
14209        unsafe { ffi::whiteout_m3_M3IKCCD_get_searchDown(self.raw.as_ptr()) }
14210    }
14211
14212    pub fn set_search_down(&mut self, value: f32) {
14213        // SAFETY: plain scalar write through a live handle.
14214        unsafe { ffi::whiteout_m3_M3IKCCD_set_searchDown(self.raw.as_ptr(), value) }
14215    }
14216}
14217
14218impl Default for IKCCD {
14219    fn default() -> Self {
14220        Self::new()
14221    }
14222}
14223
14224/// PAOB — One-bone IK solver (v0, 24 bytes)
14225///
14226/// Simple single-bone orientation solver with angle limit and fallback bone.
14227pub struct OneBoneSolver {
14228    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3OneBoneSolver>,
14229}
14230
14231impl Drop for OneBoneSolver {
14232    fn drop(&mut self) {
14233        // SAFETY: `raw` came from a native constructor and Drop runs once.
14234        unsafe { ffi::whiteout_m3_M3OneBoneSolver_delete(self.raw.as_ptr()) }
14235    }
14236}
14237
14238impl OneBoneSolver {
14239    /// # Safety
14240    /// `raw` must be a live handle this value takes ownership of.
14241    #[allow(dead_code)] // used by whichever methods return this type
14242    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3OneBoneSolver) -> Option<Self> {
14243        core::ptr::NonNull::new(raw).map(|raw| OneBoneSolver { raw })
14244    }
14245}
14246
14247// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
14248// is deliberately NOT implemented — the C++ types make no documented
14249// guarantee about concurrent use, and claiming one we haven't verified
14250// would be unsound. See `@bind thread_safe` in the plan.
14251unsafe impl Send for OneBoneSolver {}
14252
14253impl core::fmt::Debug for OneBoneSolver {
14254    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
14255        f.debug_struct("OneBoneSolver").finish_non_exhaustive()
14256    }
14257}
14258
14259impl OneBoneSolver {
14260    /// # Panics
14261    /// Panics if the native allocation fails.
14262    pub fn new() -> Self {
14263        // SAFETY: the native constructor returns a live handle; a null here
14264        // means the library is unusable.
14265        unsafe {
14266            let raw = ffi::whiteout_m3_M3OneBoneSolver_new();
14267            Self::from_raw(raw).expect("native OneBoneSolver allocation failed")
14268        }
14269    }
14270
14271    /// Dependent bone indices (U16_)
14272    /// Zero-copy view of the underlying `std::vector`.
14273    pub fn dependents(&self) -> &[u16] {
14274        // SAFETY: `_data`/`_count` describe one contiguous C++
14275        // allocation, borrowed for as long as `self` is.
14276        unsafe {
14277            let n = ffi::whiteout_m3_M3OneBoneSolver_get_dependents_count(self.raw.as_ptr());
14278            let p = ffi::whiteout_m3_M3OneBoneSolver_get_dependents_data(self.raw.as_ptr());
14279            if p.is_null() || n == 0 {
14280                &[]
14281            } else {
14282                core::slice::from_raw_parts(p, n)
14283            }
14284        }
14285    }
14286
14287    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
14288    pub fn dependents_mut(&mut self) -> &mut [u16] {
14289        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
14290        unsafe {
14291            let n = ffi::whiteout_m3_M3OneBoneSolver_get_dependents_count(self.raw.as_ptr());
14292            let p =
14293                ffi::whiteout_m3_M3OneBoneSolver_get_dependents_data(self.raw.as_ptr()) as *mut u16;
14294            if p.is_null() || n == 0 {
14295                &mut []
14296            } else {
14297                core::slice::from_raw_parts_mut(p, n)
14298            }
14299        }
14300    }
14301
14302    pub fn set_dependents(&mut self, values: &[u16]) {
14303        // SAFETY: the native side copies `values` before returning.
14304        unsafe {
14305            ffi::whiteout_m3_M3OneBoneSolver_assign_dependents(
14306                self.raw.as_ptr(),
14307                values.as_ptr() as *const _,
14308                values.len(),
14309            )
14310        }
14311    }
14312
14313    pub fn resize_dependents(&mut self, count: usize) {
14314        // SAFETY: reallocation is safe here precisely because
14315        // `&mut self` means no slice borrow is outstanding.
14316        unsafe { ffi::whiteout_m3_M3OneBoneSolver_resize_dependents(self.raw.as_ptr(), count) }
14317    }
14318
14319    /// Primary bone index
14320    pub fn bone(&self) -> u16 {
14321        // SAFETY: plain scalar read through a live handle.
14322        unsafe { ffi::whiteout_m3_M3OneBoneSolver_get_bone(self.raw.as_ptr()) }
14323    }
14324
14325    pub fn set_bone(&mut self, value: u16) {
14326        // SAFETY: plain scalar write through a live handle.
14327        unsafe { ffi::whiteout_m3_M3OneBoneSolver_set_bone(self.raw.as_ptr(), value) }
14328    }
14329
14330    /// Fallback bone index
14331    pub fn bone_fallback(&self) -> u16 {
14332        // SAFETY: plain scalar read through a live handle.
14333        unsafe { ffi::whiteout_m3_M3OneBoneSolver_get_boneFallback(self.raw.as_ptr()) }
14334    }
14335
14336    pub fn set_bone_fallback(&mut self, value: u16) {
14337        // SAFETY: plain scalar write through a live handle.
14338        unsafe { ffi::whiteout_m3_M3OneBoneSolver_set_boneFallback(self.raw.as_ptr(), value) }
14339    }
14340
14341    /// Maximum rotation angle
14342    pub fn max_angle(&self) -> f32 {
14343        // SAFETY: plain scalar read through a live handle.
14344        unsafe { ffi::whiteout_m3_M3OneBoneSolver_get_maxAngle(self.raw.as_ptr()) }
14345    }
14346
14347    pub fn set_max_angle(&mut self, value: f32) {
14348        // SAFETY: plain scalar write through a live handle.
14349        unsafe { ffi::whiteout_m3_M3OneBoneSolver_set_maxAngle(self.raw.as_ptr(), value) }
14350    }
14351}
14352
14353impl Default for OneBoneSolver {
14354    fn default() -> Self {
14355        Self::new()
14356    }
14357}
14358
14359/// SHBX — Shadow box (v0, 64 bytes)
14360///
14361/// Axis-aligned shadow volume defined by a 4×4 transform matrix.
14362pub struct ShadowBox {
14363    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3ShadowBox>,
14364}
14365
14366impl Drop for ShadowBox {
14367    fn drop(&mut self) {
14368        // SAFETY: `raw` came from a native constructor and Drop runs once.
14369        unsafe { ffi::whiteout_m3_M3ShadowBox_delete(self.raw.as_ptr()) }
14370    }
14371}
14372
14373impl ShadowBox {
14374    /// # Safety
14375    /// `raw` must be a live handle this value takes ownership of.
14376    #[allow(dead_code)] // used by whichever methods return this type
14377    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3ShadowBox) -> Option<Self> {
14378        core::ptr::NonNull::new(raw).map(|raw| ShadowBox { raw })
14379    }
14380}
14381
14382// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
14383// is deliberately NOT implemented — the C++ types make no documented
14384// guarantee about concurrent use, and claiming one we haven't verified
14385// would be unsound. See `@bind thread_safe` in the plan.
14386unsafe impl Send for ShadowBox {}
14387
14388impl core::fmt::Debug for ShadowBox {
14389    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
14390        f.debug_struct("ShadowBox").finish_non_exhaustive()
14391    }
14392}
14393
14394impl ShadowBox {
14395    /// # Panics
14396    /// Panics if the native allocation fails.
14397    pub fn new() -> Self {
14398        // SAFETY: the native constructor returns a live handle; a null here
14399        // means the library is unusable.
14400        unsafe {
14401            let raw = ffi::whiteout_m3_M3ShadowBox_new();
14402            Self::from_raw(raw).expect("native ShadowBox allocation failed")
14403        }
14404    }
14405}
14406
14407impl Default for ShadowBox {
14408    fn default() -> Self {
14409        Self::new()
14410    }
14411}
14412
14413/// VVOL — View volume (v0, 40 bytes)
14414///
14415/// Animated visibility volume bound to a bone, used for culling decisions.
14416pub struct ViewVolume {
14417    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3ViewVolume>,
14418}
14419
14420impl Drop for ViewVolume {
14421    fn drop(&mut self) {
14422        // SAFETY: `raw` came from a native constructor and Drop runs once.
14423        unsafe { ffi::whiteout_m3_M3ViewVolume_delete(self.raw.as_ptr()) }
14424    }
14425}
14426
14427impl ViewVolume {
14428    /// # Safety
14429    /// `raw` must be a live handle this value takes ownership of.
14430    #[allow(dead_code)] // used by whichever methods return this type
14431    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3ViewVolume) -> Option<Self> {
14432        core::ptr::NonNull::new(raw).map(|raw| ViewVolume { raw })
14433    }
14434}
14435
14436// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
14437// is deliberately NOT implemented — the C++ types make no documented
14438// guarantee about concurrent use, and claiming one we haven't verified
14439// would be unsound. See `@bind thread_safe` in the plan.
14440unsafe impl Send for ViewVolume {}
14441
14442impl core::fmt::Debug for ViewVolume {
14443    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
14444        f.debug_struct("ViewVolume").finish_non_exhaustive()
14445    }
14446}
14447
14448impl ViewVolume {
14449    /// # Panics
14450    /// Panics if the native allocation fails.
14451    pub fn new() -> Self {
14452        // SAFETY: the native constructor returns a live handle; a null here
14453        // means the library is unusable.
14454        unsafe {
14455            let raw = ffi::whiteout_m3_M3ViewVolume_new();
14456            Self::from_raw(raw).expect("native ViewVolume allocation failed")
14457        }
14458    }
14459
14460    /// Index into BONE array
14461    pub fn node_index(&self) -> u32 {
14462        // SAFETY: plain scalar read through a live handle.
14463        unsafe { ffi::whiteout_m3_M3ViewVolume_get_nodeIndex(self.raw.as_ptr()) }
14464    }
14465
14466    pub fn set_node_index(&mut self, value: u32) {
14467        // SAFETY: plain scalar write through a live handle.
14468        unsafe { ffi::whiteout_m3_M3ViewVolume_set_nodeIndex(self.raw.as_ptr(), value) }
14469    }
14470
14471    /// Animated half-extents (36 bytes)
14472    /// Borrows the field in place — no copy, no allocation.
14473    pub fn size(&self) -> crate::support::Ref<'_, AnimRefVector3f> {
14474        // SAFETY: an interior pointer into `self`, valid for this
14475        // borrow and never freed by the `Ref`.
14476        unsafe {
14477            crate::support::Ref::new(AnimRefVector3f {
14478                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3ViewVolume_get_size(
14479                    self.raw.as_ptr(),
14480                )),
14481            })
14482        }
14483    }
14484
14485    pub fn size_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector3f> {
14486        // SAFETY: as above; `&mut self` guarantees exclusivity.
14487        unsafe {
14488            crate::support::RefMut::new(AnimRefVector3f {
14489                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3ViewVolume_get_size(
14490                    self.raw.as_ptr(),
14491                )),
14492            })
14493        }
14494    }
14495}
14496
14497impl Default for ViewVolume {
14498    fn default() -> Self {
14499        Self::new()
14500    }
14501}
14502
14503/// TMD_ — Trailing model (v0–v1, defunct)
14504///
14505/// Legacy trailing model data. Observed in older files but no longer actively used by the engine.
14506pub struct TrailingModel {
14507    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3TrailingModel>,
14508}
14509
14510impl Drop for TrailingModel {
14511    fn drop(&mut self) {
14512        // SAFETY: `raw` came from a native constructor and Drop runs once.
14513        unsafe { ffi::whiteout_m3_M3TrailingModel_delete(self.raw.as_ptr()) }
14514    }
14515}
14516
14517impl TrailingModel {
14518    /// # Safety
14519    /// `raw` must be a live handle this value takes ownership of.
14520    #[allow(dead_code)] // used by whichever methods return this type
14521    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3TrailingModel) -> Option<Self> {
14522        core::ptr::NonNull::new(raw).map(|raw| TrailingModel { raw })
14523    }
14524}
14525
14526// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
14527// is deliberately NOT implemented — the C++ types make no documented
14528// guarantee about concurrent use, and claiming one we haven't verified
14529// would be unsound. See `@bind thread_safe` in the plan.
14530unsafe impl Send for TrailingModel {}
14531
14532impl core::fmt::Debug for TrailingModel {
14533    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
14534        f.debug_struct("TrailingModel").finish_non_exhaustive()
14535    }
14536}
14537
14538impl TrailingModel {
14539    /// # Panics
14540    /// Panics if the native allocation fails.
14541    pub fn new() -> Self {
14542        // SAFETY: the native constructor returns a live handle; a null here
14543        // means the library is unusable.
14544        unsafe {
14545            let raw = ffi::whiteout_m3_M3TrailingModel_new();
14546            Self::from_raw(raw).expect("native TrailingModel allocation failed")
14547        }
14548    }
14549
14550    /// Control vectors (VEC3)
14551    /// Zero-copy view of the underlying `std::vector`.
14552    pub fn vectors(&self) -> &[crate::math::Vector3f] {
14553        // SAFETY: `_data`/`_count` describe one contiguous C++
14554        // allocation, borrowed for as long as `self` is.
14555        unsafe {
14556            let n = ffi::whiteout_m3_M3TrailingModel_get_vectors_count(self.raw.as_ptr());
14557            let p = ffi::whiteout_m3_M3TrailingModel_get_vectors_data(self.raw.as_ptr())
14558                as *const crate::math::Vector3f;
14559            if p.is_null() || n == 0 {
14560                &[]
14561            } else {
14562                core::slice::from_raw_parts(p, n)
14563            }
14564        }
14565    }
14566
14567    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
14568    pub fn vectors_mut(&mut self) -> &mut [crate::math::Vector3f] {
14569        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
14570        unsafe {
14571            let n = ffi::whiteout_m3_M3TrailingModel_get_vectors_count(self.raw.as_ptr());
14572            let p = ffi::whiteout_m3_M3TrailingModel_get_vectors_data(self.raw.as_ptr())
14573                as *const crate::math::Vector3f as *mut crate::math::Vector3f;
14574            if p.is_null() || n == 0 {
14575                &mut []
14576            } else {
14577                core::slice::from_raw_parts_mut(p, n)
14578            }
14579        }
14580    }
14581
14582    pub fn set_vectors(&mut self, values: &[crate::math::Vector3f]) {
14583        // SAFETY: the native side copies `values` before returning.
14584        unsafe {
14585            ffi::whiteout_m3_M3TrailingModel_assign_vectors(
14586                self.raw.as_ptr(),
14587                values.as_ptr() as *const _,
14588                values.len(),
14589            )
14590        }
14591    }
14592
14593    pub fn resize_vectors(&mut self, count: usize) {
14594        // SAFETY: reallocation is safe here precisely because
14595        // `&mut self` means no slice borrow is outstanding.
14596        unsafe { ffi::whiteout_m3_M3TrailingModel_resize_vectors(self.raw.as_ptr(), count) }
14597    }
14598
14599    /// Parameter 0 (observed: 5.0)
14600    pub fn param_0(&self) -> f32 {
14601        // SAFETY: plain scalar read through a live handle.
14602        unsafe { ffi::whiteout_m3_M3TrailingModel_get_param0(self.raw.as_ptr()) }
14603    }
14604
14605    pub fn set_param_0(&mut self, value: f32) {
14606        // SAFETY: plain scalar write through a live handle.
14607        unsafe { ffi::whiteout_m3_M3TrailingModel_set_param0(self.raw.as_ptr(), value) }
14608    }
14609
14610    /// Parameter 1 (observed: 1.0)
14611    pub fn param_1(&self) -> f32 {
14612        // SAFETY: plain scalar read through a live handle.
14613        unsafe { ffi::whiteout_m3_M3TrailingModel_get_param1(self.raw.as_ptr()) }
14614    }
14615
14616    pub fn set_param_1(&mut self, value: f32) {
14617        // SAFETY: plain scalar write through a live handle.
14618        unsafe { ffi::whiteout_m3_M3TrailingModel_set_param1(self.raw.as_ptr(), value) }
14619    }
14620
14621    /// Animated float 0 (init 0.5)
14622    /// Borrows the field in place — no copy, no allocation.
14623    pub fn anim_float_0(&self) -> crate::support::Ref<'_, AnimRefF32> {
14624        // SAFETY: an interior pointer into `self`, valid for this
14625        // borrow and never freed by the `Ref`.
14626        unsafe {
14627            crate::support::Ref::new(AnimRefF32 {
14628                raw: core::ptr::NonNull::new_unchecked(
14629                    ffi::whiteout_m3_M3TrailingModel_get_animFloat0(self.raw.as_ptr()),
14630                ),
14631            })
14632        }
14633    }
14634
14635    pub fn anim_float_0_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
14636        // SAFETY: as above; `&mut self` guarantees exclusivity.
14637        unsafe {
14638            crate::support::RefMut::new(AnimRefF32 {
14639                raw: core::ptr::NonNull::new_unchecked(
14640                    ffi::whiteout_m3_M3TrailingModel_get_animFloat0(self.raw.as_ptr()),
14641                ),
14642            })
14643        }
14644    }
14645
14646    /// Animated float 1 (init 1.0)
14647    /// Borrows the field in place — no copy, no allocation.
14648    pub fn anim_float_1(&self) -> crate::support::Ref<'_, AnimRefF32> {
14649        // SAFETY: an interior pointer into `self`, valid for this
14650        // borrow and never freed by the `Ref`.
14651        unsafe {
14652            crate::support::Ref::new(AnimRefF32 {
14653                raw: core::ptr::NonNull::new_unchecked(
14654                    ffi::whiteout_m3_M3TrailingModel_get_animFloat1(self.raw.as_ptr()),
14655                ),
14656            })
14657        }
14658    }
14659
14660    pub fn anim_float_1_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
14661        // SAFETY: as above; `&mut self` guarantees exclusivity.
14662        unsafe {
14663            crate::support::RefMut::new(AnimRefF32 {
14664                raw: core::ptr::NonNull::new_unchecked(
14665                    ffi::whiteout_m3_M3TrailingModel_get_animFloat1(self.raw.as_ptr()),
14666                ),
14667            })
14668        }
14669    }
14670
14671    /// Flag (observed: 1)
14672    pub fn flag(&self) -> u32 {
14673        // SAFETY: plain scalar read through a live handle.
14674        unsafe { ffi::whiteout_m3_M3TrailingModel_get_flag(self.raw.as_ptr()) }
14675    }
14676
14677    pub fn set_flag(&mut self, value: u32) {
14678        // SAFETY: plain scalar write through a live handle.
14679        unsafe { ffi::whiteout_m3_M3TrailingModel_set_flag(self.raw.as_ptr(), value) }
14680    }
14681
14682    /// Reserved
14683    pub fn reserved_0(&self) -> u32 {
14684        // SAFETY: plain scalar read through a live handle.
14685        unsafe { ffi::whiteout_m3_M3TrailingModel_get_reserved0(self.raw.as_ptr()) }
14686    }
14687
14688    pub fn set_reserved_0(&mut self, value: u32) {
14689        // SAFETY: plain scalar write through a live handle.
14690        unsafe { ffi::whiteout_m3_M3TrailingModel_set_reserved0(self.raw.as_ptr(), value) }
14691    }
14692
14693    /// Reserved
14694    pub fn reserved_1(&self) -> u32 {
14695        // SAFETY: plain scalar read through a live handle.
14696        unsafe { ffi::whiteout_m3_M3TrailingModel_get_reserved1(self.raw.as_ptr()) }
14697    }
14698
14699    pub fn set_reserved_1(&mut self, value: u32) {
14700        // SAFETY: plain scalar write through a live handle.
14701        unsafe { ffi::whiteout_m3_M3TrailingModel_set_reserved1(self.raw.as_ptr(), value) }
14702    }
14703}
14704
14705impl Default for TrailingModel {
14706    fn default() -> Self {
14707        Self::new()
14708    }
14709}
14710
14711/// FOR_ — Force field (v0–v2, 104 bytes)
14712///
14713/// Applies radial, wind, or explosion forces to particles and ribbons within an influence volume shape (sphere, cylinder, box, hemisphere).
14714pub struct Force {
14715    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3Force>,
14716}
14717
14718impl Drop for Force {
14719    fn drop(&mut self) {
14720        // SAFETY: `raw` came from a native constructor and Drop runs once.
14721        unsafe { ffi::whiteout_m3_M3Force_delete(self.raw.as_ptr()) }
14722    }
14723}
14724
14725impl Force {
14726    /// # Safety
14727    /// `raw` must be a live handle this value takes ownership of.
14728    #[allow(dead_code)] // used by whichever methods return this type
14729    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3Force) -> Option<Self> {
14730        core::ptr::NonNull::new(raw).map(|raw| Force { raw })
14731    }
14732}
14733
14734// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
14735// is deliberately NOT implemented — the C++ types make no documented
14736// guarantee about concurrent use, and claiming one we haven't verified
14737// would be unsound. See `@bind thread_safe` in the plan.
14738unsafe impl Send for Force {}
14739
14740impl core::fmt::Debug for Force {
14741    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
14742        f.debug_struct("Force").finish_non_exhaustive()
14743    }
14744}
14745
14746impl Force {
14747    /// # Panics
14748    /// Panics if the native allocation fails.
14749    pub fn new() -> Self {
14750        // SAFETY: the native constructor returns a live handle; a null here
14751        // means the library is unusable.
14752        unsafe {
14753            let raw = ffi::whiteout_m3_M3Force_new();
14754            Self::from_raw(raw).expect("native Force allocation failed")
14755        }
14756    }
14757
14758    /// Force influence type (radial/wind/explosion)
14759    pub fn force_type(&self) -> ForceType {
14760        // SAFETY: scalar read; the discriminant is validated below.
14761        unsafe { ffi::whiteout_m3_M3Force_get_forceType(self.raw.as_ptr()) }
14762            .try_into()
14763            .expect("unknown enum discriminant from the native library")
14764    }
14765
14766    pub fn set_force_type(&mut self, value: ForceType) {
14767        // SAFETY: scalar write through a live handle.
14768        unsafe { ffi::whiteout_m3_M3Force_set_forceType(self.raw.as_ptr(), value as i32) }
14769    }
14770
14771    /// Influence volume shape
14772    pub fn force_shape(&self) -> ForceShape {
14773        // SAFETY: scalar read; the discriminant is validated below.
14774        unsafe { ffi::whiteout_m3_M3Force_get_forceShape(self.raw.as_ptr()) }
14775            .try_into()
14776            .expect("unknown enum discriminant from the native library")
14777    }
14778
14779    pub fn set_force_shape(&mut self, value: ForceShape) {
14780        // SAFETY: scalar write through a live handle.
14781        unsafe { ffi::whiteout_m3_M3Force_set_forceShape(self.raw.as_ptr(), value as i32) }
14782    }
14783
14784    /// Unknown field
14785    pub fn unknown(&self) -> u32 {
14786        // SAFETY: plain scalar read through a live handle.
14787        unsafe { ffi::whiteout_m3_M3Force_get_unknown(self.raw.as_ptr()) }
14788    }
14789
14790    pub fn set_unknown(&mut self, value: u32) {
14791        // SAFETY: plain scalar write through a live handle.
14792        unsafe { ffi::whiteout_m3_M3Force_set_unknown(self.raw.as_ptr(), value) }
14793    }
14794
14795    /// Index into BONE array
14796    pub fn bone_index(&self) -> u32 {
14797        // SAFETY: plain scalar read through a live handle.
14798        unsafe { ffi::whiteout_m3_M3Force_get_boneIndex(self.raw.as_ptr()) }
14799    }
14800
14801    pub fn set_bone_index(&mut self, value: u32) {
14802        // SAFETY: plain scalar write through a live handle.
14803        unsafe { ffi::whiteout_m3_M3Force_set_boneIndex(self.raw.as_ptr(), value) }
14804    }
14805
14806    /// Force flags (falloff, height gradient, unbounded)
14807    pub fn flags(&self) -> ForceFlag {
14808        // SAFETY: scalar read; a flag set accepts any bits.
14809        ForceFlag(unsafe { ffi::whiteout_m3_M3Force_get_flags(self.raw.as_ptr()) })
14810    }
14811
14812    pub fn set_flags(&mut self, value: ForceFlag) {
14813        // SAFETY: scalar write through a live handle.
14814        unsafe { ffi::whiteout_m3_M3Force_set_flags(self.raw.as_ptr(), value.0) }
14815    }
14816
14817    /// Local channel bitmask
14818    pub fn local_channels(&self) -> u32 {
14819        // SAFETY: plain scalar read through a live handle.
14820        unsafe { ffi::whiteout_m3_M3Force_get_localChannels(self.raw.as_ptr()) }
14821    }
14822
14823    pub fn set_local_channels(&mut self, value: u32) {
14824        // SAFETY: plain scalar write through a live handle.
14825        unsafe { ffi::whiteout_m3_M3Force_set_localChannels(self.raw.as_ptr(), value) }
14826    }
14827
14828    /// Animated force strength
14829    /// Borrows the field in place — no copy, no allocation.
14830    pub fn strength(&self) -> crate::support::Ref<'_, AnimRefF32> {
14831        // SAFETY: an interior pointer into `self`, valid for this
14832        // borrow and never freed by the `Ref`.
14833        unsafe {
14834            crate::support::Ref::new(AnimRefF32 {
14835                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Force_get_strength(
14836                    self.raw.as_ptr(),
14837                )),
14838            })
14839        }
14840    }
14841
14842    pub fn strength_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
14843        // SAFETY: as above; `&mut self` guarantees exclusivity.
14844        unsafe {
14845            crate::support::RefMut::new(AnimRefF32 {
14846                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Force_get_strength(
14847                    self.raw.as_ptr(),
14848                )),
14849            })
14850        }
14851    }
14852
14853    /// Animated influence width
14854    /// Borrows the field in place — no copy, no allocation.
14855    pub fn width(&self) -> crate::support::Ref<'_, AnimRefF32> {
14856        // SAFETY: an interior pointer into `self`, valid for this
14857        // borrow and never freed by the `Ref`.
14858        unsafe {
14859            crate::support::Ref::new(AnimRefF32 {
14860                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Force_get_width(
14861                    self.raw.as_ptr(),
14862                )),
14863            })
14864        }
14865    }
14866
14867    pub fn width_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
14868        // SAFETY: as above; `&mut self` guarantees exclusivity.
14869        unsafe {
14870            crate::support::RefMut::new(AnimRefF32 {
14871                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Force_get_width(
14872                    self.raw.as_ptr(),
14873                )),
14874            })
14875        }
14876    }
14877
14878    /// Animated influence height
14879    /// Borrows the field in place — no copy, no allocation.
14880    pub fn height(&self) -> crate::support::Ref<'_, AnimRefF32> {
14881        // SAFETY: an interior pointer into `self`, valid for this
14882        // borrow and never freed by the `Ref`.
14883        unsafe {
14884            crate::support::Ref::new(AnimRefF32 {
14885                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Force_get_height(
14886                    self.raw.as_ptr(),
14887                )),
14888            })
14889        }
14890    }
14891
14892    pub fn height_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
14893        // SAFETY: as above; `&mut self` guarantees exclusivity.
14894        unsafe {
14895            crate::support::RefMut::new(AnimRefF32 {
14896                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Force_get_height(
14897                    self.raw.as_ptr(),
14898                )),
14899            })
14900        }
14901    }
14902
14903    /// Animated influence length
14904    /// Borrows the field in place — no copy, no allocation.
14905    pub fn length(&self) -> crate::support::Ref<'_, AnimRefF32> {
14906        // SAFETY: an interior pointer into `self`, valid for this
14907        // borrow and never freed by the `Ref`.
14908        unsafe {
14909            crate::support::Ref::new(AnimRefF32 {
14910                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Force_get_length(
14911                    self.raw.as_ptr(),
14912                )),
14913            })
14914        }
14915    }
14916
14917    pub fn length_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
14918        // SAFETY: as above; `&mut self` guarantees exclusivity.
14919        unsafe {
14920            crate::support::RefMut::new(AnimRefF32 {
14921                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Force_get_length(
14922                    self.raw.as_ptr(),
14923                )),
14924            })
14925        }
14926    }
14927}
14928
14929impl Default for Force {
14930    fn default() -> Self {
14931        Self::new()
14932    }
14933}
14934
14935/// WRP_ — Warp field (v0–v1, 132 bytes)
14936///
14937/// Warps particle/ribbon trajectories with animated radius, height, and angular/axial/radial strength components.
14938pub struct Warp {
14939    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3Warp>,
14940}
14941
14942impl Drop for Warp {
14943    fn drop(&mut self) {
14944        // SAFETY: `raw` came from a native constructor and Drop runs once.
14945        unsafe { ffi::whiteout_m3_M3Warp_delete(self.raw.as_ptr()) }
14946    }
14947}
14948
14949impl Warp {
14950    /// # Safety
14951    /// `raw` must be a live handle this value takes ownership of.
14952    #[allow(dead_code)] // used by whichever methods return this type
14953    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3Warp) -> Option<Self> {
14954        core::ptr::NonNull::new(raw).map(|raw| Warp { raw })
14955    }
14956}
14957
14958// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
14959// is deliberately NOT implemented — the C++ types make no documented
14960// guarantee about concurrent use, and claiming one we haven't verified
14961// would be unsound. See `@bind thread_safe` in the plan.
14962unsafe impl Send for Warp {}
14963
14964impl core::fmt::Debug for Warp {
14965    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
14966        f.debug_struct("Warp").finish_non_exhaustive()
14967    }
14968}
14969
14970impl Warp {
14971    /// # Panics
14972    /// Panics if the native allocation fails.
14973    pub fn new() -> Self {
14974        // SAFETY: the native constructor returns a live handle; a null here
14975        // means the library is unusable.
14976        unsafe {
14977            let raw = ffi::whiteout_m3_M3Warp_new();
14978            Self::from_raw(raw).expect("native Warp allocation failed")
14979        }
14980    }
14981
14982    /// Warp type
14983    pub fn warp_type(&self) -> u32 {
14984        // SAFETY: plain scalar read through a live handle.
14985        unsafe { ffi::whiteout_m3_M3Warp_get_warpType(self.raw.as_ptr()) }
14986    }
14987
14988    pub fn set_warp_type(&mut self, value: u32) {
14989        // SAFETY: plain scalar write through a live handle.
14990        unsafe { ffi::whiteout_m3_M3Warp_set_warpType(self.raw.as_ptr(), value) }
14991    }
14992
14993    /// Index into BONE array
14994    pub fn bone_index(&self) -> u32 {
14995        // SAFETY: plain scalar read through a live handle.
14996        unsafe { ffi::whiteout_m3_M3Warp_get_boneIndex(self.raw.as_ptr()) }
14997    }
14998
14999    pub fn set_bone_index(&mut self, value: u32) {
15000        // SAFETY: plain scalar write through a live handle.
15001        unsafe { ffi::whiteout_m3_M3Warp_set_boneIndex(self.raw.as_ptr(), value) }
15002    }
15003
15004    /// Unknown field
15005    pub fn unknown(&self) -> u32 {
15006        // SAFETY: plain scalar read through a live handle.
15007        unsafe { ffi::whiteout_m3_M3Warp_get_unknown(self.raw.as_ptr()) }
15008    }
15009
15010    pub fn set_unknown(&mut self, value: u32) {
15011        // SAFETY: plain scalar write through a live handle.
15012        unsafe { ffi::whiteout_m3_M3Warp_set_unknown(self.raw.as_ptr(), value) }
15013    }
15014
15015    /// Animated warp radius
15016    /// Borrows the field in place — no copy, no allocation.
15017    pub fn radius(&self) -> crate::support::Ref<'_, AnimRefF32> {
15018        // SAFETY: an interior pointer into `self`, valid for this
15019        // borrow and never freed by the `Ref`.
15020        unsafe {
15021            crate::support::Ref::new(AnimRefF32 {
15022                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Warp_get_radius(
15023                    self.raw.as_ptr(),
15024                )),
15025            })
15026        }
15027    }
15028
15029    pub fn radius_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
15030        // SAFETY: as above; `&mut self` guarantees exclusivity.
15031        unsafe {
15032            crate::support::RefMut::new(AnimRefF32 {
15033                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Warp_get_radius(
15034                    self.raw.as_ptr(),
15035                )),
15036            })
15037        }
15038    }
15039
15040    /// Animated warp height
15041    /// Borrows the field in place — no copy, no allocation.
15042    pub fn height(&self) -> crate::support::Ref<'_, AnimRefF32> {
15043        // SAFETY: an interior pointer into `self`, valid for this
15044        // borrow and never freed by the `Ref`.
15045        unsafe {
15046            crate::support::Ref::new(AnimRefF32 {
15047                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Warp_get_height(
15048                    self.raw.as_ptr(),
15049                )),
15050            })
15051        }
15052    }
15053
15054    pub fn height_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
15055        // SAFETY: as above; `&mut self` guarantees exclusivity.
15056        unsafe {
15057            crate::support::RefMut::new(AnimRefF32 {
15058                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Warp_get_height(
15059                    self.raw.as_ptr(),
15060                )),
15061            })
15062        }
15063    }
15064
15065    /// Animated warp strength
15066    /// Borrows the field in place — no copy, no allocation.
15067    pub fn strength(&self) -> crate::support::Ref<'_, AnimRefF32> {
15068        // SAFETY: an interior pointer into `self`, valid for this
15069        // borrow and never freed by the `Ref`.
15070        unsafe {
15071            crate::support::Ref::new(AnimRefF32 {
15072                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Warp_get_strength(
15073                    self.raw.as_ptr(),
15074                )),
15075            })
15076        }
15077    }
15078
15079    pub fn strength_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
15080        // SAFETY: as above; `&mut self` guarantees exclusivity.
15081        unsafe {
15082            crate::support::RefMut::new(AnimRefF32 {
15083                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Warp_get_strength(
15084                    self.raw.as_ptr(),
15085                )),
15086            })
15087        }
15088    }
15089
15090    /// Animated angular component
15091    /// Borrows the field in place — no copy, no allocation.
15092    pub fn angular(&self) -> crate::support::Ref<'_, AnimRefF32> {
15093        // SAFETY: an interior pointer into `self`, valid for this
15094        // borrow and never freed by the `Ref`.
15095        unsafe {
15096            crate::support::Ref::new(AnimRefF32 {
15097                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Warp_get_angular(
15098                    self.raw.as_ptr(),
15099                )),
15100            })
15101        }
15102    }
15103
15104    pub fn angular_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
15105        // SAFETY: as above; `&mut self` guarantees exclusivity.
15106        unsafe {
15107            crate::support::RefMut::new(AnimRefF32 {
15108                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Warp_get_angular(
15109                    self.raw.as_ptr(),
15110                )),
15111            })
15112        }
15113    }
15114
15115    /// Animated axial component
15116    /// Borrows the field in place — no copy, no allocation.
15117    pub fn axial(&self) -> crate::support::Ref<'_, AnimRefF32> {
15118        // SAFETY: an interior pointer into `self`, valid for this
15119        // borrow and never freed by the `Ref`.
15120        unsafe {
15121            crate::support::Ref::new(AnimRefF32 {
15122                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Warp_get_axial(
15123                    self.raw.as_ptr(),
15124                )),
15125            })
15126        }
15127    }
15128
15129    pub fn axial_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
15130        // SAFETY: as above; `&mut self` guarantees exclusivity.
15131        unsafe {
15132            crate::support::RefMut::new(AnimRefF32 {
15133                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Warp_get_axial(
15134                    self.raw.as_ptr(),
15135                )),
15136            })
15137        }
15138    }
15139
15140    /// Animated radial component
15141    /// Borrows the field in place — no copy, no allocation.
15142    pub fn radial(&self) -> crate::support::Ref<'_, AnimRefF32> {
15143        // SAFETY: an interior pointer into `self`, valid for this
15144        // borrow and never freed by the `Ref`.
15145        unsafe {
15146            crate::support::Ref::new(AnimRefF32 {
15147                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Warp_get_radial(
15148                    self.raw.as_ptr(),
15149                )),
15150            })
15151        }
15152    }
15153
15154    pub fn radial_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
15155        // SAFETY: as above; `&mut self` guarantees exclusivity.
15156        unsafe {
15157            crate::support::RefMut::new(AnimRefF32 {
15158                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Warp_get_radial(
15159                    self.raw.as_ptr(),
15160                )),
15161            })
15162        }
15163    }
15164}
15165
15166impl Default for Warp {
15167    fn default() -> Self {
15168        Self::new()
15169    }
15170}
15171
15172/// DMSE — Convex hull half-edge (v0, 4 bytes)
15173///
15174/// 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.
15175pub struct ConvexHullHalfEdge {
15176    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3ConvexHullHalfEdge>,
15177}
15178
15179impl Drop for ConvexHullHalfEdge {
15180    fn drop(&mut self) {
15181        // SAFETY: `raw` came from a native constructor and Drop runs once.
15182        unsafe { ffi::whiteout_m3_M3ConvexHullHalfEdge_delete(self.raw.as_ptr()) }
15183    }
15184}
15185
15186impl ConvexHullHalfEdge {
15187    /// # Safety
15188    /// `raw` must be a live handle this value takes ownership of.
15189    #[allow(dead_code)] // used by whichever methods return this type
15190    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3ConvexHullHalfEdge) -> Option<Self> {
15191        core::ptr::NonNull::new(raw).map(|raw| ConvexHullHalfEdge { raw })
15192    }
15193}
15194
15195// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
15196// is deliberately NOT implemented — the C++ types make no documented
15197// guarantee about concurrent use, and claiming one we haven't verified
15198// would be unsound. See `@bind thread_safe` in the plan.
15199unsafe impl Send for ConvexHullHalfEdge {}
15200
15201impl core::fmt::Debug for ConvexHullHalfEdge {
15202    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
15203        f.debug_struct("ConvexHullHalfEdge").finish_non_exhaustive()
15204    }
15205}
15206
15207impl ConvexHullHalfEdge {
15208    /// # Panics
15209    /// Panics if the native allocation fails.
15210    pub fn new() -> Self {
15211        // SAFETY: the native constructor returns a live handle; a null here
15212        // means the library is unusable.
15213        unsafe {
15214            let raw = ffi::whiteout_m3_M3ConvexHullHalfEdge_new();
15215            Self::from_raw(raw).expect("native ConvexHullHalfEdge allocation failed")
15216        }
15217    }
15218
15219    /// 0x01 = forward, 0xFF = reverse (twin)
15220    pub fn type_(&self) -> u8 {
15221        // SAFETY: plain scalar read through a live handle.
15222        unsafe { ffi::whiteout_m3_M3ConvexHullHalfEdge_get_type(self.raw.as_ptr()) }
15223    }
15224
15225    pub fn set_type_(&mut self, value: u8) {
15226        // SAFETY: plain scalar write through a live handle.
15227        unsafe { ffi::whiteout_m3_M3ConvexHullHalfEdge_set_type(self.raw.as_ptr(), value) }
15228    }
15229
15230    /// Face this half-edge borders
15231    pub fn face_index(&self) -> u8 {
15232        // SAFETY: plain scalar read through a live handle.
15233        unsafe { ffi::whiteout_m3_M3ConvexHullHalfEdge_get_faceIndex(self.raw.as_ptr()) }
15234    }
15235
15236    pub fn set_face_index(&mut self, value: u8) {
15237        // SAFETY: plain scalar write through a live handle.
15238        unsafe { ffi::whiteout_m3_M3ConvexHullHalfEdge_set_faceIndex(self.raw.as_ptr(), value) }
15239    }
15240
15241    /// Target vertex of this half-edge
15242    pub fn vertex_index(&self) -> u8 {
15243        // SAFETY: plain scalar read through a live handle.
15244        unsafe { ffi::whiteout_m3_M3ConvexHullHalfEdge_get_vertexIndex(self.raw.as_ptr()) }
15245    }
15246
15247    pub fn set_vertex_index(&mut self, value: u8) {
15248        // SAFETY: plain scalar write through a live handle.
15249        unsafe { ffi::whiteout_m3_M3ConvexHullHalfEdge_set_vertexIndex(self.raw.as_ptr(), value) }
15250    }
15251
15252    /// Next half-edge around the same vertex
15253    pub fn next_around_vertex(&self) -> u8 {
15254        // SAFETY: plain scalar read through a live handle.
15255        unsafe { ffi::whiteout_m3_M3ConvexHullHalfEdge_get_nextAroundVertex(self.raw.as_ptr()) }
15256    }
15257
15258    pub fn set_next_around_vertex(&mut self, value: u8) {
15259        // SAFETY: plain scalar write through a live handle.
15260        unsafe {
15261            ffi::whiteout_m3_M3ConvexHullHalfEdge_set_nextAroundVertex(self.raw.as_ptr(), value)
15262        }
15263    }
15264}
15265
15266impl Default for ConvexHullHalfEdge {
15267    fn default() -> Self {
15268        Self::new()
15269    }
15270}
15271
15272/// DMMN — Physics mesh BVH node (v0: 12 bytes, v1: 8 bytes)
15273///
15274/// 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.
15275///
15276/// **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
15277///
15278/// **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).
15279///
15280/// **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)
15281///
15282/// **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)
15283///
15284/// 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.
15285///
15286/// PHSH meshTreeDepth gives the tree height (longest root-to-leaf path in nodes).
15287pub struct PhysicsMeshBvhNode {
15288    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3PhysicsMeshBvhNode>,
15289}
15290
15291impl Drop for PhysicsMeshBvhNode {
15292    fn drop(&mut self) {
15293        // SAFETY: `raw` came from a native constructor and Drop runs once.
15294        unsafe { ffi::whiteout_m3_M3PhysicsMeshBvhNode_delete(self.raw.as_ptr()) }
15295    }
15296}
15297
15298impl PhysicsMeshBvhNode {
15299    /// # Safety
15300    /// `raw` must be a live handle this value takes ownership of.
15301    #[allow(dead_code)] // used by whichever methods return this type
15302    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3PhysicsMeshBvhNode) -> Option<Self> {
15303        core::ptr::NonNull::new(raw).map(|raw| PhysicsMeshBvhNode { raw })
15304    }
15305}
15306
15307// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
15308// is deliberately NOT implemented — the C++ types make no documented
15309// guarantee about concurrent use, and claiming one we haven't verified
15310// would be unsound. See `@bind thread_safe` in the plan.
15311unsafe impl Send for PhysicsMeshBvhNode {}
15312
15313impl core::fmt::Debug for PhysicsMeshBvhNode {
15314    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
15315        f.debug_struct("PhysicsMeshBvhNode").finish_non_exhaustive()
15316    }
15317}
15318
15319impl PhysicsMeshBvhNode {
15320    /// # Panics
15321    /// Panics if the native allocation fails.
15322    pub fn new() -> Self {
15323        // SAFETY: the native constructor returns a live handle; a null here
15324        // means the library is unusable.
15325        unsafe {
15326            let raw = ffi::whiteout_m3_M3PhysicsMeshBvhNode_new();
15327            Self::from_raw(raw).expect("native PhysicsMeshBvhNode allocation failed")
15328        }
15329    }
15330}
15331
15332impl Default for PhysicsMeshBvhNode {
15333    fn default() -> Self {
15334        Self::new()
15335    }
15336}
15337
15338/// DMMT — Physics mesh triangle (v0, 28 bytes)
15339pub struct PhysicsMeshTriangle {
15340    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3PhysicsMeshTriangle>,
15341}
15342
15343impl Drop for PhysicsMeshTriangle {
15344    fn drop(&mut self) {
15345        // SAFETY: `raw` came from a native constructor and Drop runs once.
15346        unsafe { ffi::whiteout_m3_M3PhysicsMeshTriangle_delete(self.raw.as_ptr()) }
15347    }
15348}
15349
15350impl PhysicsMeshTriangle {
15351    /// # Safety
15352    /// `raw` must be a live handle this value takes ownership of.
15353    #[allow(dead_code)] // used by whichever methods return this type
15354    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3PhysicsMeshTriangle) -> Option<Self> {
15355        core::ptr::NonNull::new(raw).map(|raw| PhysicsMeshTriangle { raw })
15356    }
15357}
15358
15359// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
15360// is deliberately NOT implemented — the C++ types make no documented
15361// guarantee about concurrent use, and claiming one we haven't verified
15362// would be unsound. See `@bind thread_safe` in the plan.
15363unsafe impl Send for PhysicsMeshTriangle {}
15364
15365impl core::fmt::Debug for PhysicsMeshTriangle {
15366    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
15367        f.debug_struct("PhysicsMeshTriangle")
15368            .finish_non_exhaustive()
15369    }
15370}
15371
15372impl PhysicsMeshTriangle {
15373    /// # Panics
15374    /// Panics if the native allocation fails.
15375    pub fn new() -> Self {
15376        // SAFETY: the native constructor returns a live handle; a null here
15377        // means the library is unusable.
15378        unsafe {
15379            let raw = ffi::whiteout_m3_M3PhysicsMeshTriangle_new();
15380            Self::from_raw(raw).expect("native PhysicsMeshTriangle allocation failed")
15381        }
15382    }
15383
15384    /// First vertex index
15385    pub fn vertex_index_0(&self) -> u32 {
15386        // SAFETY: plain scalar read through a live handle.
15387        unsafe { ffi::whiteout_m3_M3PhysicsMeshTriangle_get_vertexIndex0(self.raw.as_ptr()) }
15388    }
15389
15390    pub fn set_vertex_index_0(&mut self, value: u32) {
15391        // SAFETY: plain scalar write through a live handle.
15392        unsafe { ffi::whiteout_m3_M3PhysicsMeshTriangle_set_vertexIndex0(self.raw.as_ptr(), value) }
15393    }
15394
15395    /// Second vertex index
15396    pub fn vertex_index_1(&self) -> u32 {
15397        // SAFETY: plain scalar read through a live handle.
15398        unsafe { ffi::whiteout_m3_M3PhysicsMeshTriangle_get_vertexIndex1(self.raw.as_ptr()) }
15399    }
15400
15401    pub fn set_vertex_index_1(&mut self, value: u32) {
15402        // SAFETY: plain scalar write through a live handle.
15403        unsafe { ffi::whiteout_m3_M3PhysicsMeshTriangle_set_vertexIndex1(self.raw.as_ptr(), value) }
15404    }
15405
15406    /// Third vertex index
15407    pub fn vertex_index_2(&self) -> u32 {
15408        // SAFETY: plain scalar read through a live handle.
15409        unsafe { ffi::whiteout_m3_M3PhysicsMeshTriangle_get_vertexIndex2(self.raw.as_ptr()) }
15410    }
15411
15412    pub fn set_vertex_index_2(&mut self, value: u32) {
15413        // SAFETY: plain scalar write through a live handle.
15414        unsafe { ffi::whiteout_m3_M3PhysicsMeshTriangle_set_vertexIndex2(self.raw.as_ptr(), value) }
15415    }
15416
15417    /// First edge index
15418    pub fn edge_index_0(&self) -> u32 {
15419        // SAFETY: plain scalar read through a live handle.
15420        unsafe { ffi::whiteout_m3_M3PhysicsMeshTriangle_get_edgeIndex0(self.raw.as_ptr()) }
15421    }
15422
15423    pub fn set_edge_index_0(&mut self, value: u32) {
15424        // SAFETY: plain scalar write through a live handle.
15425        unsafe { ffi::whiteout_m3_M3PhysicsMeshTriangle_set_edgeIndex0(self.raw.as_ptr(), value) }
15426    }
15427
15428    /// Second edge index
15429    pub fn edge_index_1(&self) -> u32 {
15430        // SAFETY: plain scalar read through a live handle.
15431        unsafe { ffi::whiteout_m3_M3PhysicsMeshTriangle_get_edgeIndex1(self.raw.as_ptr()) }
15432    }
15433
15434    pub fn set_edge_index_1(&mut self, value: u32) {
15435        // SAFETY: plain scalar write through a live handle.
15436        unsafe { ffi::whiteout_m3_M3PhysicsMeshTriangle_set_edgeIndex1(self.raw.as_ptr(), value) }
15437    }
15438
15439    /// Third edge index
15440    pub fn edge_index_2(&self) -> u32 {
15441        // SAFETY: plain scalar read through a live handle.
15442        unsafe { ffi::whiteout_m3_M3PhysicsMeshTriangle_get_edgeIndex2(self.raw.as_ptr()) }
15443    }
15444
15445    pub fn set_edge_index_2(&mut self, value: u32) {
15446        // SAFETY: plain scalar write through a live handle.
15447        unsafe { ffi::whiteout_m3_M3PhysicsMeshTriangle_set_edgeIndex2(self.raw.as_ptr(), value) }
15448    }
15449
15450    /// Reserved
15451    pub fn reserved(&self) -> u16 {
15452        // SAFETY: plain scalar read through a live handle.
15453        unsafe { ffi::whiteout_m3_M3PhysicsMeshTriangle_get_reserved(self.raw.as_ptr()) }
15454    }
15455
15456    pub fn set_reserved(&mut self, value: u16) {
15457        // SAFETY: plain scalar write through a live handle.
15458        unsafe { ffi::whiteout_m3_M3PhysicsMeshTriangle_set_reserved(self.raw.as_ptr(), value) }
15459    }
15460
15461    /// Triangle flags
15462    pub fn flags(&self) -> u16 {
15463        // SAFETY: plain scalar read through a live handle.
15464        unsafe { ffi::whiteout_m3_M3PhysicsMeshTriangle_get_flags(self.raw.as_ptr()) }
15465    }
15466
15467    pub fn set_flags(&mut self, value: u16) {
15468        // SAFETY: plain scalar write through a live handle.
15469        unsafe { ffi::whiteout_m3_M3PhysicsMeshTriangle_set_flags(self.raw.as_ptr(), value) }
15470    }
15471}
15472
15473impl Default for PhysicsMeshTriangle {
15474    fn default() -> Self {
15475        Self::new()
15476    }
15477}
15478
15479/// DMME — Physics mesh edge (v0, 20 bytes)
15480pub struct PhysicsMeshEdge {
15481    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3PhysicsMeshEdge>,
15482}
15483
15484impl Drop for PhysicsMeshEdge {
15485    fn drop(&mut self) {
15486        // SAFETY: `raw` came from a native constructor and Drop runs once.
15487        unsafe { ffi::whiteout_m3_M3PhysicsMeshEdge_delete(self.raw.as_ptr()) }
15488    }
15489}
15490
15491impl PhysicsMeshEdge {
15492    /// # Safety
15493    /// `raw` must be a live handle this value takes ownership of.
15494    #[allow(dead_code)] // used by whichever methods return this type
15495    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3PhysicsMeshEdge) -> Option<Self> {
15496        core::ptr::NonNull::new(raw).map(|raw| PhysicsMeshEdge { raw })
15497    }
15498}
15499
15500// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
15501// is deliberately NOT implemented — the C++ types make no documented
15502// guarantee about concurrent use, and claiming one we haven't verified
15503// would be unsound. See `@bind thread_safe` in the plan.
15504unsafe impl Send for PhysicsMeshEdge {}
15505
15506impl core::fmt::Debug for PhysicsMeshEdge {
15507    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
15508        f.debug_struct("PhysicsMeshEdge").finish_non_exhaustive()
15509    }
15510}
15511
15512impl PhysicsMeshEdge {
15513    /// # Panics
15514    /// Panics if the native allocation fails.
15515    pub fn new() -> Self {
15516        // SAFETY: the native constructor returns a live handle; a null here
15517        // means the library is unusable.
15518        unsafe {
15519            let raw = ffi::whiteout_m3_M3PhysicsMeshEdge_new();
15520            Self::from_raw(raw).expect("native PhysicsMeshEdge allocation failed")
15521        }
15522    }
15523
15524    /// Edge type
15525    pub fn edge_type(&self) -> u32 {
15526        // SAFETY: plain scalar read through a live handle.
15527        unsafe { ffi::whiteout_m3_M3PhysicsMeshEdge_get_edgeType(self.raw.as_ptr()) }
15528    }
15529
15530    pub fn set_edge_type(&mut self, value: u32) {
15531        // SAFETY: plain scalar write through a live handle.
15532        unsafe { ffi::whiteout_m3_M3PhysicsMeshEdge_set_edgeType(self.raw.as_ptr(), value) }
15533    }
15534
15535    /// First vertex index
15536    pub fn vertex_a(&self) -> u32 {
15537        // SAFETY: plain scalar read through a live handle.
15538        unsafe { ffi::whiteout_m3_M3PhysicsMeshEdge_get_vertexA(self.raw.as_ptr()) }
15539    }
15540
15541    pub fn set_vertex_a(&mut self, value: u32) {
15542        // SAFETY: plain scalar write through a live handle.
15543        unsafe { ffi::whiteout_m3_M3PhysicsMeshEdge_set_vertexA(self.raw.as_ptr(), value) }
15544    }
15545
15546    /// Second vertex index
15547    pub fn vertex_b(&self) -> u32 {
15548        // SAFETY: plain scalar read through a live handle.
15549        unsafe { ffi::whiteout_m3_M3PhysicsMeshEdge_get_vertexB(self.raw.as_ptr()) }
15550    }
15551
15552    pub fn set_vertex_b(&mut self, value: u32) {
15553        // SAFETY: plain scalar write through a live handle.
15554        unsafe { ffi::whiteout_m3_M3PhysicsMeshEdge_set_vertexB(self.raw.as_ptr(), value) }
15555    }
15556
15557    /// First adjacent face
15558    pub fn face_a(&self) -> u32 {
15559        // SAFETY: plain scalar read through a live handle.
15560        unsafe { ffi::whiteout_m3_M3PhysicsMeshEdge_get_faceA(self.raw.as_ptr()) }
15561    }
15562
15563    pub fn set_face_a(&mut self, value: u32) {
15564        // SAFETY: plain scalar write through a live handle.
15565        unsafe { ffi::whiteout_m3_M3PhysicsMeshEdge_set_faceA(self.raw.as_ptr(), value) }
15566    }
15567
15568    /// Second adjacent face
15569    pub fn face_b(&self) -> u32 {
15570        // SAFETY: plain scalar read through a live handle.
15571        unsafe { ffi::whiteout_m3_M3PhysicsMeshEdge_get_faceB(self.raw.as_ptr()) }
15572    }
15573
15574    pub fn set_face_b(&mut self, value: u32) {
15575        // SAFETY: plain scalar write through a live handle.
15576        unsafe { ffi::whiteout_m3_M3PhysicsMeshEdge_set_faceB(self.raw.as_ptr(), value) }
15577    }
15578}
15579
15580impl Default for PhysicsMeshEdge {
15581    fn default() -> Self {
15582        Self::new()
15583    }
15584}
15585
15586/// PHSH — Physics shape (v0–v3, 132–300 bytes)
15587///
15588/// 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).
15589pub struct PhysicsShape {
15590    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3PhysicsShape>,
15591}
15592
15593impl Drop for PhysicsShape {
15594    fn drop(&mut self) {
15595        // SAFETY: `raw` came from a native constructor and Drop runs once.
15596        unsafe { ffi::whiteout_m3_M3PhysicsShape_delete(self.raw.as_ptr()) }
15597    }
15598}
15599
15600impl PhysicsShape {
15601    /// # Safety
15602    /// `raw` must be a live handle this value takes ownership of.
15603    #[allow(dead_code)] // used by whichever methods return this type
15604    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3PhysicsShape) -> Option<Self> {
15605        core::ptr::NonNull::new(raw).map(|raw| PhysicsShape { raw })
15606    }
15607}
15608
15609// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
15610// is deliberately NOT implemented — the C++ types make no documented
15611// guarantee about concurrent use, and claiming one we haven't verified
15612// would be unsound. See `@bind thread_safe` in the plan.
15613unsafe impl Send for PhysicsShape {}
15614
15615impl core::fmt::Debug for PhysicsShape {
15616    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
15617        f.debug_struct("PhysicsShape").finish_non_exhaustive()
15618    }
15619}
15620
15621impl PhysicsShape {
15622    /// # Panics
15623    /// Panics if the native allocation fails.
15624    pub fn new() -> Self {
15625        // SAFETY: the native constructor returns a live handle; a null here
15626        // means the library is unusable.
15627        unsafe {
15628            let raw = ffi::whiteout_m3_M3PhysicsShape_new();
15629            Self::from_raw(raw).expect("native PhysicsShape allocation failed")
15630        }
15631    }
15632
15633    /// Havok convex radius (v1 only, ≈ 0.019685)
15634    pub fn collision_margin(&self) -> f32 {
15635        // SAFETY: plain scalar read through a live handle.
15636        unsafe { ffi::whiteout_m3_M3PhysicsShape_get_collisionMargin(self.raw.as_ptr()) }
15637    }
15638
15639    pub fn set_collision_margin(&mut self, value: f32) {
15640        // SAFETY: plain scalar write through a live handle.
15641        unsafe { ffi::whiteout_m3_M3PhysicsShape_set_collisionMargin(self.raw.as_ptr(), value) }
15642    }
15643
15644    /// Shape type (box/sphere/capsule/cylinder/hull/mesh)
15645    pub fn shape_type(&self) -> PhysicsShapeType {
15646        // SAFETY: scalar read; the discriminant is validated below.
15647        unsafe { ffi::whiteout_m3_M3PhysicsShape_get_shapeType(self.raw.as_ptr()) }
15648            .try_into()
15649            .expect("unknown enum discriminant from the native library")
15650    }
15651
15652    pub fn set_shape_type(&mut self, value: PhysicsShapeType) {
15653        // SAFETY: scalar write through a live handle.
15654        unsafe { ffi::whiteout_m3_M3PhysicsShape_set_shapeType(self.raw.as_ptr(), value as i32) }
15655    }
15656
15657    /// Legacy sizes (v1 only, zero for shapeType 4–5)
15658    pub fn old_sizes(&self) -> crate::math::Vector3f {
15659        // SAFETY: the getter returns an interior pointer to a
15660        // layout-identical POD; we copy it out immediately.
15661        unsafe {
15662            *(ffi::whiteout_m3_M3PhysicsShape_get_oldSizes(self.raw.as_ptr())
15663                as *const crate::math::Vector3f)
15664        }
15665    }
15666
15667    pub fn set_old_sizes(&mut self, value: crate::math::Vector3f) {
15668        // SAFETY: as above, in the other direction.
15669        unsafe {
15670            ffi::whiteout_m3_M3PhysicsShape_set_oldSizes(
15671                self.raw.as_ptr(),
15672                &value as *const crate::math::Vector3f as *const _,
15673            )
15674        }
15675    }
15676
15677    /// Shape dimensions (v2+, zero for complex shapes)
15678    pub fn shape_dimensions(&self) -> crate::math::Vector3f {
15679        // SAFETY: the getter returns an interior pointer to a
15680        // layout-identical POD; we copy it out immediately.
15681        unsafe {
15682            *(ffi::whiteout_m3_M3PhysicsShape_get_shapeDimensions(self.raw.as_ptr())
15683                as *const crate::math::Vector3f)
15684        }
15685    }
15686
15687    pub fn set_shape_dimensions(&mut self, value: crate::math::Vector3f) {
15688        // SAFETY: as above, in the other direction.
15689        unsafe {
15690            ffi::whiteout_m3_M3PhysicsShape_set_shapeDimensions(
15691                self.raw.as_ptr(),
15692                &value as *const crate::math::Vector3f as *const _,
15693            )
15694        }
15695    }
15696
15697    /// Per-face unit normals (VEC3)
15698    /// Zero-copy view of the underlying `std::vector`.
15699    pub fn hull_face_normals(&self) -> &[crate::math::Vector3f] {
15700        // SAFETY: `_data`/`_count` describe one contiguous C++
15701        // allocation, borrowed for as long as `self` is.
15702        unsafe {
15703            let n = ffi::whiteout_m3_M3PhysicsShape_get_hullFaceNormals_count(self.raw.as_ptr());
15704            let p = ffi::whiteout_m3_M3PhysicsShape_get_hullFaceNormals_data(self.raw.as_ptr())
15705                as *const crate::math::Vector3f;
15706            if p.is_null() || n == 0 {
15707                &[]
15708            } else {
15709                core::slice::from_raw_parts(p, n)
15710            }
15711        }
15712    }
15713
15714    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
15715    pub fn hull_face_normals_mut(&mut self) -> &mut [crate::math::Vector3f] {
15716        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
15717        unsafe {
15718            let n = ffi::whiteout_m3_M3PhysicsShape_get_hullFaceNormals_count(self.raw.as_ptr());
15719            let p = ffi::whiteout_m3_M3PhysicsShape_get_hullFaceNormals_data(self.raw.as_ptr())
15720                as *const crate::math::Vector3f as *mut crate::math::Vector3f;
15721            if p.is_null() || n == 0 {
15722                &mut []
15723            } else {
15724                core::slice::from_raw_parts_mut(p, n)
15725            }
15726        }
15727    }
15728
15729    pub fn set_hull_face_normals(&mut self, values: &[crate::math::Vector3f]) {
15730        // SAFETY: the native side copies `values` before returning.
15731        unsafe {
15732            ffi::whiteout_m3_M3PhysicsShape_assign_hullFaceNormals(
15733                self.raw.as_ptr(),
15734                values.as_ptr() as *const _,
15735                values.len(),
15736            )
15737        }
15738    }
15739
15740    pub fn resize_hull_face_normals(&mut self, count: usize) {
15741        // SAFETY: reallocation is safe here precisely because
15742        // `&mut self` means no slice borrow is outstanding.
15743        unsafe { ffi::whiteout_m3_M3PhysicsShape_resize_hullFaceNormals(self.raw.as_ptr(), count) }
15744    }
15745
15746    /// Vertex positions, w=0 (VEC4)
15747    /// Zero-copy view of the underlying `std::vector`.
15748    pub fn hull_vertex_positions(&self) -> &[crate::math::Vector4f] {
15749        // SAFETY: `_data`/`_count` describe one contiguous C++
15750        // allocation, borrowed for as long as `self` is.
15751        unsafe {
15752            let n =
15753                ffi::whiteout_m3_M3PhysicsShape_get_hullVertexPositions_count(self.raw.as_ptr());
15754            let p = ffi::whiteout_m3_M3PhysicsShape_get_hullVertexPositions_data(self.raw.as_ptr())
15755                as *const crate::math::Vector4f;
15756            if p.is_null() || n == 0 {
15757                &[]
15758            } else {
15759                core::slice::from_raw_parts(p, n)
15760            }
15761        }
15762    }
15763
15764    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
15765    pub fn hull_vertex_positions_mut(&mut self) -> &mut [crate::math::Vector4f] {
15766        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
15767        unsafe {
15768            let n =
15769                ffi::whiteout_m3_M3PhysicsShape_get_hullVertexPositions_count(self.raw.as_ptr());
15770            let p = ffi::whiteout_m3_M3PhysicsShape_get_hullVertexPositions_data(self.raw.as_ptr())
15771                as *const crate::math::Vector4f as *mut crate::math::Vector4f;
15772            if p.is_null() || n == 0 {
15773                &mut []
15774            } else {
15775                core::slice::from_raw_parts_mut(p, n)
15776            }
15777        }
15778    }
15779
15780    pub fn set_hull_vertex_positions(&mut self, values: &[crate::math::Vector4f]) {
15781        // SAFETY: the native side copies `values` before returning.
15782        unsafe {
15783            ffi::whiteout_m3_M3PhysicsShape_assign_hullVertexPositions(
15784                self.raw.as_ptr(),
15785                values.as_ptr() as *const _,
15786                values.len(),
15787            )
15788        }
15789    }
15790
15791    pub fn resize_hull_vertex_positions(&mut self, count: usize) {
15792        // SAFETY: reallocation is safe here precisely because
15793        // `&mut self` means no slice borrow is outstanding.
15794        unsafe {
15795            ffi::whiteout_m3_M3PhysicsShape_resize_hullVertexPositions(self.raw.as_ptr(), count)
15796        }
15797    }
15798
15799    /// Half-edge table (DMSE)
15800    pub fn hull_half_edges_len(&self) -> usize {
15801        // SAFETY: scalar read through a live handle.
15802        unsafe { ffi::whiteout_m3_M3PhysicsShape_get_hullHalfEdges_count(self.raw.as_ptr()) }
15803    }
15804
15805    /// Borrows element `index` in place. `None` when out of range.
15806    pub fn hull_half_edges(
15807        &self,
15808        index: usize,
15809    ) -> Option<crate::support::Ref<'_, ConvexHullHalfEdge>> {
15810        if index >= self.hull_half_edges_len() {
15811            return None;
15812        }
15813        // SAFETY: index checked above; the pointer is interior to `self`.
15814        unsafe {
15815            Some(crate::support::Ref::new(ConvexHullHalfEdge {
15816                raw: core::ptr::NonNull::new_unchecked(
15817                    ffi::whiteout_m3_M3PhysicsShape_get_hullHalfEdges_at(self.raw.as_ptr(), index),
15818                ),
15819            }))
15820        }
15821    }
15822
15823    pub fn hull_half_edges_mut(
15824        &mut self,
15825        index: usize,
15826    ) -> Option<crate::support::RefMut<'_, ConvexHullHalfEdge>> {
15827        if index >= self.hull_half_edges_len() {
15828            return None;
15829        }
15830        // SAFETY: as above; `&mut self` guarantees exclusivity.
15831        unsafe {
15832            Some(crate::support::RefMut::new(ConvexHullHalfEdge {
15833                raw: core::ptr::NonNull::new_unchecked(
15834                    ffi::whiteout_m3_M3PhysicsShape_get_hullHalfEdges_at(self.raw.as_ptr(), index),
15835                ),
15836            }))
15837        }
15838    }
15839
15840    /// Iterate the elements, borrowing each in turn.
15841    pub fn hull_half_edges_iter(
15842        &self,
15843    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, ConvexHullHalfEdge>> {
15844        (0..self.hull_half_edges_len())
15845            .map(move |i| self.hull_half_edges(i).expect("index below len"))
15846    }
15847
15848    pub fn resize_hull_half_edges(&mut self, count: usize) {
15849        // SAFETY: exclusive access, so no borrow is outstanding.
15850        unsafe { ffi::whiteout_m3_M3PhysicsShape_resize_hullHalfEdges(self.raw.as_ptr(), count) }
15851    }
15852
15853    /// One face index per vertex (U8__)
15854    /// Zero-copy view of the underlying `std::vector`.
15855    pub fn hull_vertex_face_indices(&self) -> &[u8] {
15856        // SAFETY: `_data`/`_count` describe one contiguous C++
15857        // allocation, borrowed for as long as `self` is.
15858        unsafe {
15859            let n =
15860                ffi::whiteout_m3_M3PhysicsShape_get_hullVertexFaceIndices_count(self.raw.as_ptr());
15861            let p =
15862                ffi::whiteout_m3_M3PhysicsShape_get_hullVertexFaceIndices_data(self.raw.as_ptr());
15863            if p.is_null() || n == 0 {
15864                &[]
15865            } else {
15866                core::slice::from_raw_parts(p, n)
15867            }
15868        }
15869    }
15870
15871    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
15872    pub fn hull_vertex_face_indices_mut(&mut self) -> &mut [u8] {
15873        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
15874        unsafe {
15875            let n =
15876                ffi::whiteout_m3_M3PhysicsShape_get_hullVertexFaceIndices_count(self.raw.as_ptr());
15877            let p =
15878                ffi::whiteout_m3_M3PhysicsShape_get_hullVertexFaceIndices_data(self.raw.as_ptr())
15879                    as *mut u8;
15880            if p.is_null() || n == 0 {
15881                &mut []
15882            } else {
15883                core::slice::from_raw_parts_mut(p, n)
15884            }
15885        }
15886    }
15887
15888    pub fn set_hull_vertex_face_indices(&mut self, values: &[u8]) {
15889        // SAFETY: the native side copies `values` before returning.
15890        unsafe {
15891            ffi::whiteout_m3_M3PhysicsShape_assign_hullVertexFaceIndices(
15892                self.raw.as_ptr(),
15893                values.as_ptr() as *const _,
15894                values.len(),
15895            )
15896        }
15897    }
15898
15899    pub fn resize_hull_vertex_face_indices(&mut self, count: usize) {
15900        // SAFETY: reallocation is safe here precisely because
15901        // `&mut self` means no slice borrow is outstanding.
15902        unsafe {
15903            ffi::whiteout_m3_M3PhysicsShape_resize_hullVertexFaceIndices(self.raw.as_ptr(), count)
15904        }
15905    }
15906
15907    /// Hull centroid
15908    pub fn hull_center(&self) -> crate::math::Vector3f {
15909        // SAFETY: the getter returns an interior pointer to a
15910        // layout-identical POD; we copy it out immediately.
15911        unsafe {
15912            *(ffi::whiteout_m3_M3PhysicsShape_get_hullCenter(self.raw.as_ptr())
15913                as *const crate::math::Vector3f)
15914        }
15915    }
15916
15917    pub fn set_hull_center(&mut self, value: crate::math::Vector3f) {
15918        // SAFETY: as above, in the other direction.
15919        unsafe {
15920            ffi::whiteout_m3_M3PhysicsShape_set_hullCenter(
15921                self.raw.as_ptr(),
15922                &value as *const crate::math::Vector3f as *const _,
15923            )
15924        }
15925    }
15926
15927    /// Number of face normals
15928    pub fn hull_face_normal_count(&self) -> u32 {
15929        // SAFETY: plain scalar read through a live handle.
15930        unsafe { ffi::whiteout_m3_M3PhysicsShape_get_hullFaceNormalCount(self.raw.as_ptr()) }
15931    }
15932
15933    pub fn set_hull_face_normal_count(&mut self, value: u32) {
15934        // SAFETY: plain scalar write through a live handle.
15935        unsafe { ffi::whiteout_m3_M3PhysicsShape_set_hullFaceNormalCount(self.raw.as_ptr(), value) }
15936    }
15937
15938    /// Number of vertices
15939    pub fn hull_vertex_count(&self) -> u32 {
15940        // SAFETY: plain scalar read through a live handle.
15941        unsafe { ffi::whiteout_m3_M3PhysicsShape_get_hullVertexCount(self.raw.as_ptr()) }
15942    }
15943
15944    pub fn set_hull_vertex_count(&mut self, value: u32) {
15945        // SAFETY: plain scalar write through a live handle.
15946        unsafe { ffi::whiteout_m3_M3PhysicsShape_set_hullVertexCount(self.raw.as_ptr(), value) }
15947    }
15948
15949    /// Number of half-edges
15950    pub fn hull_half_edge_count(&self) -> u32 {
15951        // SAFETY: plain scalar read through a live handle.
15952        unsafe { ffi::whiteout_m3_M3PhysicsShape_get_hullHalfEdgeCount(self.raw.as_ptr()) }
15953    }
15954
15955    pub fn set_hull_half_edge_count(&mut self, value: u32) {
15956        // SAFETY: plain scalar write through a live handle.
15957        unsafe { ffi::whiteout_m3_M3PhysicsShape_set_hullHalfEdgeCount(self.raw.as_ptr(), value) }
15958    }
15959
15960    /// Unknown hull parameter 0
15961    pub fn hull_unknown_0(&self) -> f32 {
15962        // SAFETY: plain scalar read through a live handle.
15963        unsafe { ffi::whiteout_m3_M3PhysicsShape_get_hullUnknown0(self.raw.as_ptr()) }
15964    }
15965
15966    pub fn set_hull_unknown_0(&mut self, value: f32) {
15967        // SAFETY: plain scalar write through a live handle.
15968        unsafe { ffi::whiteout_m3_M3PhysicsShape_set_hullUnknown0(self.raw.as_ptr(), value) }
15969    }
15970
15971    /// Unknown hull parameter 1
15972    pub fn hull_unknown_1(&self) -> f32 {
15973        // SAFETY: plain scalar read through a live handle.
15974        unsafe { ffi::whiteout_m3_M3PhysicsShape_get_hullUnknown1(self.raw.as_ptr()) }
15975    }
15976
15977    pub fn set_hull_unknown_1(&mut self, value: f32) {
15978        // SAFETY: plain scalar write through a live handle.
15979        unsafe { ffi::whiteout_m3_M3PhysicsShape_set_hullUnknown1(self.raw.as_ptr(), value) }
15980    }
15981
15982    /// BVH tree nodes (DMMN)
15983    pub fn mesh_bvh_nodes_len(&self) -> usize {
15984        // SAFETY: scalar read through a live handle.
15985        unsafe { ffi::whiteout_m3_M3PhysicsShape_get_meshBvhNodes_count(self.raw.as_ptr()) }
15986    }
15987
15988    /// Borrows element `index` in place. `None` when out of range.
15989    pub fn mesh_bvh_nodes(
15990        &self,
15991        index: usize,
15992    ) -> Option<crate::support::Ref<'_, PhysicsMeshBvhNode>> {
15993        if index >= self.mesh_bvh_nodes_len() {
15994            return None;
15995        }
15996        // SAFETY: index checked above; the pointer is interior to `self`.
15997        unsafe {
15998            Some(crate::support::Ref::new(PhysicsMeshBvhNode {
15999                raw: core::ptr::NonNull::new_unchecked(
16000                    ffi::whiteout_m3_M3PhysicsShape_get_meshBvhNodes_at(self.raw.as_ptr(), index),
16001                ),
16002            }))
16003        }
16004    }
16005
16006    pub fn mesh_bvh_nodes_mut(
16007        &mut self,
16008        index: usize,
16009    ) -> Option<crate::support::RefMut<'_, PhysicsMeshBvhNode>> {
16010        if index >= self.mesh_bvh_nodes_len() {
16011            return None;
16012        }
16013        // SAFETY: as above; `&mut self` guarantees exclusivity.
16014        unsafe {
16015            Some(crate::support::RefMut::new(PhysicsMeshBvhNode {
16016                raw: core::ptr::NonNull::new_unchecked(
16017                    ffi::whiteout_m3_M3PhysicsShape_get_meshBvhNodes_at(self.raw.as_ptr(), index),
16018                ),
16019            }))
16020        }
16021    }
16022
16023    /// Iterate the elements, borrowing each in turn.
16024    pub fn mesh_bvh_nodes_iter(
16025        &self,
16026    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, PhysicsMeshBvhNode>> {
16027        (0..self.mesh_bvh_nodes_len())
16028            .map(move |i| self.mesh_bvh_nodes(i).expect("index below len"))
16029    }
16030
16031    pub fn resize_mesh_bvh_nodes(&mut self, count: usize) {
16032        // SAFETY: exclusive access, so no borrow is outstanding.
16033        unsafe { ffi::whiteout_m3_M3PhysicsShape_resize_meshBvhNodes(self.raw.as_ptr(), count) }
16034    }
16035
16036    /// Vertex positions, w=0 (VEC4)
16037    /// Zero-copy view of the underlying `std::vector`.
16038    pub fn mesh_vertex_positions(&self) -> &[crate::math::Vector4f] {
16039        // SAFETY: `_data`/`_count` describe one contiguous C++
16040        // allocation, borrowed for as long as `self` is.
16041        unsafe {
16042            let n =
16043                ffi::whiteout_m3_M3PhysicsShape_get_meshVertexPositions_count(self.raw.as_ptr());
16044            let p = ffi::whiteout_m3_M3PhysicsShape_get_meshVertexPositions_data(self.raw.as_ptr())
16045                as *const crate::math::Vector4f;
16046            if p.is_null() || n == 0 {
16047                &[]
16048            } else {
16049                core::slice::from_raw_parts(p, n)
16050            }
16051        }
16052    }
16053
16054    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
16055    pub fn mesh_vertex_positions_mut(&mut self) -> &mut [crate::math::Vector4f] {
16056        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
16057        unsafe {
16058            let n =
16059                ffi::whiteout_m3_M3PhysicsShape_get_meshVertexPositions_count(self.raw.as_ptr());
16060            let p = ffi::whiteout_m3_M3PhysicsShape_get_meshVertexPositions_data(self.raw.as_ptr())
16061                as *const crate::math::Vector4f as *mut crate::math::Vector4f;
16062            if p.is_null() || n == 0 {
16063                &mut []
16064            } else {
16065                core::slice::from_raw_parts_mut(p, n)
16066            }
16067        }
16068    }
16069
16070    pub fn set_mesh_vertex_positions(&mut self, values: &[crate::math::Vector4f]) {
16071        // SAFETY: the native side copies `values` before returning.
16072        unsafe {
16073            ffi::whiteout_m3_M3PhysicsShape_assign_meshVertexPositions(
16074                self.raw.as_ptr(),
16075                values.as_ptr() as *const _,
16076                values.len(),
16077            )
16078        }
16079    }
16080
16081    pub fn resize_mesh_vertex_positions(&mut self, count: usize) {
16082        // SAFETY: reallocation is safe here precisely because
16083        // `&mut self` means no slice borrow is outstanding.
16084        unsafe {
16085            ffi::whiteout_m3_M3PhysicsShape_resize_meshVertexPositions(self.raw.as_ptr(), count)
16086        }
16087    }
16088
16089    /// AABB center in model space (quantization grid origin)
16090    pub fn mesh_bounds_center(&self) -> crate::math::Vector3f {
16091        // SAFETY: the getter returns an interior pointer to a
16092        // layout-identical POD; we copy it out immediately.
16093        unsafe {
16094            *(ffi::whiteout_m3_M3PhysicsShape_get_meshBoundsCenter(self.raw.as_ptr())
16095                as *const crate::math::Vector3f)
16096        }
16097    }
16098
16099    pub fn set_mesh_bounds_center(&mut self, value: crate::math::Vector3f) {
16100        // SAFETY: as above, in the other direction.
16101        unsafe {
16102            ffi::whiteout_m3_M3PhysicsShape_set_meshBoundsCenter(
16103                self.raw.as_ptr(),
16104                &value as *const crate::math::Vector3f as *const _,
16105            )
16106        }
16107    }
16108
16109    /// AABB half-extents (quantization range: tolerance = extent / 32767)
16110    pub fn mesh_bounds_extent(&self) -> crate::math::Vector3f {
16111        // SAFETY: the getter returns an interior pointer to a
16112        // layout-identical POD; we copy it out immediately.
16113        unsafe {
16114            *(ffi::whiteout_m3_M3PhysicsShape_get_meshBoundsExtent(self.raw.as_ptr())
16115                as *const crate::math::Vector3f)
16116        }
16117    }
16118
16119    pub fn set_mesh_bounds_extent(&mut self, value: crate::math::Vector3f) {
16120        // SAFETY: as above, in the other direction.
16121        unsafe {
16122            ffi::whiteout_m3_M3PhysicsShape_set_meshBoundsExtent(
16123                self.raw.as_ptr(),
16124                &value as *const crate::math::Vector3f as *const _,
16125            )
16126        }
16127    }
16128
16129    /// Per-axis quantization step (= extent / 32767)
16130    pub fn mesh_tolerance(&self) -> crate::math::Vector3f {
16131        // SAFETY: the getter returns an interior pointer to a
16132        // layout-identical POD; we copy it out immediately.
16133        unsafe {
16134            *(ffi::whiteout_m3_M3PhysicsShape_get_meshTolerance(self.raw.as_ptr())
16135                as *const crate::math::Vector3f)
16136        }
16137    }
16138
16139    pub fn set_mesh_tolerance(&mut self, value: crate::math::Vector3f) {
16140        // SAFETY: as above, in the other direction.
16141        unsafe {
16142            ffi::whiteout_m3_M3PhysicsShape_set_meshTolerance(
16143                self.raw.as_ptr(),
16144                &value as *const crate::math::Vector3f as *const _,
16145            )
16146        }
16147    }
16148
16149    /// Number of mesh normals
16150    pub fn mesh_normal_count(&self) -> u32 {
16151        // SAFETY: plain scalar read through a live handle.
16152        unsafe { ffi::whiteout_m3_M3PhysicsShape_get_meshNormalCount(self.raw.as_ptr()) }
16153    }
16154
16155    pub fn set_mesh_normal_count(&mut self, value: u32) {
16156        // SAFETY: plain scalar write through a live handle.
16157        unsafe { ffi::whiteout_m3_M3PhysicsShape_set_meshNormalCount(self.raw.as_ptr(), value) }
16158    }
16159
16160    /// Number of mesh vertices
16161    pub fn mesh_vertex_count(&self) -> u32 {
16162        // SAFETY: plain scalar read through a live handle.
16163        unsafe { ffi::whiteout_m3_M3PhysicsShape_get_meshVertexCount(self.raw.as_ptr()) }
16164    }
16165
16166    pub fn set_mesh_vertex_count(&mut self, value: u32) {
16167        // SAFETY: plain scalar write through a live handle.
16168        unsafe { ffi::whiteout_m3_M3PhysicsShape_set_meshVertexCount(self.raw.as_ptr(), value) }
16169    }
16170
16171    /// MT16 face count (0 when MT32)
16172    pub fn mesh_face_index_16_count(&self) -> u32 {
16173        // SAFETY: plain scalar read through a live handle.
16174        unsafe { ffi::whiteout_m3_M3PhysicsShape_get_meshFaceIndex16Count(self.raw.as_ptr()) }
16175    }
16176
16177    pub fn set_mesh_face_index_16_count(&mut self, value: u32) {
16178        // SAFETY: plain scalar write through a live handle.
16179        unsafe {
16180            ffi::whiteout_m3_M3PhysicsShape_set_meshFaceIndex16Count(self.raw.as_ptr(), value)
16181        }
16182    }
16183
16184    /// MT32 face count (0 when MT16)
16185    pub fn mesh_face_index_32_count(&self) -> u32 {
16186        // SAFETY: plain scalar read through a live handle.
16187        unsafe { ffi::whiteout_m3_M3PhysicsShape_get_meshFaceIndex32Count(self.raw.as_ptr()) }
16188    }
16189
16190    pub fn set_mesh_face_index_32_count(&mut self, value: u32) {
16191        // SAFETY: plain scalar write through a live handle.
16192        unsafe {
16193            ffi::whiteout_m3_M3PhysicsShape_set_meshFaceIndex32Count(self.raw.as_ptr(), value)
16194        }
16195    }
16196
16197    /// Unknown mesh parameter
16198    pub fn mesh_unknown_1(&self) -> u32 {
16199        // SAFETY: plain scalar read through a live handle.
16200        unsafe { ffi::whiteout_m3_M3PhysicsShape_get_meshUnknown1(self.raw.as_ptr()) }
16201    }
16202
16203    pub fn set_mesh_unknown_1(&mut self, value: u32) {
16204        // SAFETY: plain scalar write through a live handle.
16205        unsafe { ffi::whiteout_m3_M3PhysicsShape_set_meshUnknown1(self.raw.as_ptr(), value) }
16206    }
16207
16208    /// Reserved (always 0)
16209    pub fn mesh_reserved(&self) -> u32 {
16210        // SAFETY: plain scalar read through a live handle.
16211        unsafe { ffi::whiteout_m3_M3PhysicsShape_get_meshReserved(self.raw.as_ptr()) }
16212    }
16213
16214    pub fn set_mesh_reserved(&mut self, value: u32) {
16215        // SAFETY: plain scalar write through a live handle.
16216        unsafe { ffi::whiteout_m3_M3PhysicsShape_set_meshReserved(self.raw.as_ptr(), value) }
16217    }
16218
16219    /// BVH tree height (root-to-leaf path length, 1–12)
16220    pub fn mesh_tree_depth(&self) -> u32 {
16221        // SAFETY: plain scalar read through a live handle.
16222        unsafe { ffi::whiteout_m3_M3PhysicsShape_get_meshTreeDepth(self.raw.as_ptr()) }
16223    }
16224
16225    pub fn set_mesh_tree_depth(&mut self, value: u32) {
16226        // SAFETY: plain scalar write through a live handle.
16227        unsafe { ffi::whiteout_m3_M3PhysicsShape_set_meshTreeDepth(self.raw.as_ptr(), value) }
16228    }
16229
16230    /// Collision margin (MT16: small float; MT32: 0.0)
16231    pub fn mesh_collision_margin(&self) -> f32 {
16232        // SAFETY: plain scalar read through a live handle.
16233        unsafe { ffi::whiteout_m3_M3PhysicsShape_get_meshCollisionMargin(self.raw.as_ptr()) }
16234    }
16235
16236    pub fn set_mesh_collision_margin(&mut self, value: f32) {
16237        // SAFETY: plain scalar write through a live handle.
16238        unsafe { ffi::whiteout_m3_M3PhysicsShape_set_meshCollisionMargin(self.raw.as_ptr(), value) }
16239    }
16240}
16241
16242impl Default for PhysicsShape {
16243    fn default() -> Self {
16244        Self::new()
16245    }
16246}
16247
16248/// PHRB — Rigid body (v2–v4, 56–104 bytes)
16249///
16250/// Havok rigid body with density, friction, restitution, damping, gravity scale, and collision shape references.
16251pub struct RigidBody {
16252    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3RigidBody>,
16253}
16254
16255impl Drop for RigidBody {
16256    fn drop(&mut self) {
16257        // SAFETY: `raw` came from a native constructor and Drop runs once.
16258        unsafe { ffi::whiteout_m3_M3RigidBody_delete(self.raw.as_ptr()) }
16259    }
16260}
16261
16262impl RigidBody {
16263    /// # Safety
16264    /// `raw` must be a live handle this value takes ownership of.
16265    #[allow(dead_code)] // used by whichever methods return this type
16266    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3RigidBody) -> Option<Self> {
16267        core::ptr::NonNull::new(raw).map(|raw| RigidBody { raw })
16268    }
16269}
16270
16271// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
16272// is deliberately NOT implemented — the C++ types make no documented
16273// guarantee about concurrent use, and claiming one we haven't verified
16274// would be unsound. See `@bind thread_safe` in the plan.
16275unsafe impl Send for RigidBody {}
16276
16277impl core::fmt::Debug for RigidBody {
16278    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
16279        f.debug_struct("RigidBody").finish_non_exhaustive()
16280    }
16281}
16282
16283impl RigidBody {
16284    /// # Panics
16285    /// Panics if the native allocation fails.
16286    pub fn new() -> Self {
16287        // SAFETY: the native constructor returns a live handle; a null here
16288        // means the library is unusable.
16289        unsafe {
16290            let raw = ffi::whiteout_m3_M3RigidBody_new();
16291            Self::from_raw(raw).expect("native RigidBody allocation failed")
16292        }
16293    }
16294
16295    /// Simulation mode (v3+)
16296    pub fn simulation_type(&self) -> u16 {
16297        // SAFETY: plain scalar read through a live handle.
16298        unsafe { ffi::whiteout_m3_M3RigidBody_get_simulationType(self.raw.as_ptr()) }
16299    }
16300
16301    pub fn set_simulation_type(&mut self, value: u16) {
16302        // SAFETY: plain scalar write through a live handle.
16303        unsafe { ffi::whiteout_m3_M3RigidBody_set_simulationType(self.raw.as_ptr(), value) }
16304    }
16305
16306    /// Parent bone index
16307    pub fn parent_bone_index(&self) -> u16 {
16308        // SAFETY: plain scalar read through a live handle.
16309        unsafe { ffi::whiteout_m3_M3RigidBody_get_parentBoneIndex(self.raw.as_ptr()) }
16310    }
16311
16312    pub fn set_parent_bone_index(&mut self, value: u16) {
16313        // SAFETY: plain scalar write through a live handle.
16314        unsafe { ffi::whiteout_m3_M3RigidBody_set_parentBoneIndex(self.raw.as_ptr(), value) }
16315    }
16316
16317    /// Engine-specific body type (v3+)
16318    pub fn physics_type(&self) -> u32 {
16319        // SAFETY: plain scalar read through a live handle.
16320        unsafe { ffi::whiteout_m3_M3RigidBody_get_physicsType(self.raw.as_ptr()) }
16321    }
16322
16323    pub fn set_physics_type(&mut self, value: u32) {
16324        // SAFETY: plain scalar write through a live handle.
16325        unsafe { ffi::whiteout_m3_M3RigidBody_set_physicsType(self.raw.as_ptr(), value) }
16326    }
16327
16328    /// Body density
16329    pub fn density(&self) -> f32 {
16330        // SAFETY: plain scalar read through a live handle.
16331        unsafe { ffi::whiteout_m3_M3RigidBody_get_density(self.raw.as_ptr()) }
16332    }
16333
16334    pub fn set_density(&mut self, value: f32) {
16335        // SAFETY: plain scalar write through a live handle.
16336        unsafe { ffi::whiteout_m3_M3RigidBody_set_density(self.raw.as_ptr(), value) }
16337    }
16338
16339    /// Surface friction
16340    pub fn friction(&self) -> f32 {
16341        // SAFETY: plain scalar read through a live handle.
16342        unsafe { ffi::whiteout_m3_M3RigidBody_get_friction(self.raw.as_ptr()) }
16343    }
16344
16345    pub fn set_friction(&mut self, value: f32) {
16346        // SAFETY: plain scalar write through a live handle.
16347        unsafe { ffi::whiteout_m3_M3RigidBody_set_friction(self.raw.as_ptr(), value) }
16348    }
16349
16350    /// Elasticity / bounciness
16351    pub fn restitution(&self) -> f32 {
16352        // SAFETY: plain scalar read through a live handle.
16353        unsafe { ffi::whiteout_m3_M3RigidBody_get_restitution(self.raw.as_ptr()) }
16354    }
16355
16356    pub fn set_restitution(&mut self, value: f32) {
16357        // SAFETY: plain scalar write through a live handle.
16358        unsafe { ffi::whiteout_m3_M3RigidBody_set_restitution(self.raw.as_ptr(), value) }
16359    }
16360
16361    /// Linear velocity damping
16362    pub fn linear_damping(&self) -> f32 {
16363        // SAFETY: plain scalar read through a live handle.
16364        unsafe { ffi::whiteout_m3_M3RigidBody_get_linearDamping(self.raw.as_ptr()) }
16365    }
16366
16367    pub fn set_linear_damping(&mut self, value: f32) {
16368        // SAFETY: plain scalar write through a live handle.
16369        unsafe { ffi::whiteout_m3_M3RigidBody_set_linearDamping(self.raw.as_ptr(), value) }
16370    }
16371
16372    /// Angular velocity damping
16373    pub fn angular_damping(&self) -> f32 {
16374        // SAFETY: plain scalar read through a live handle.
16375        unsafe { ffi::whiteout_m3_M3RigidBody_get_angularDamping(self.raw.as_ptr()) }
16376    }
16377
16378    pub fn set_angular_damping(&mut self, value: f32) {
16379        // SAFETY: plain scalar write through a live handle.
16380        unsafe { ffi::whiteout_m3_M3RigidBody_set_angularDamping(self.raw.as_ptr(), value) }
16381    }
16382
16383    /// Gravity influence scale
16384    pub fn gravity_scale(&self) -> f32 {
16385        // SAFETY: plain scalar read through a live handle.
16386        unsafe { ffi::whiteout_m3_M3RigidBody_get_gravityScale(self.raw.as_ptr()) }
16387    }
16388
16389    pub fn set_gravity_scale(&mut self, value: f32) {
16390        // SAFETY: plain scalar write through a live handle.
16391        unsafe { ffi::whiteout_m3_M3RigidBody_set_gravityScale(self.raw.as_ptr(), value) }
16392    }
16393
16394    /// Animated dynamic state (v4+)
16395    /// Borrows the field in place — no copy, no allocation.
16396    pub fn dynamic_state(&self) -> crate::support::Ref<'_, AnimRefU32> {
16397        // SAFETY: an interior pointer into `self`, valid for this
16398        // borrow and never freed by the `Ref`.
16399        unsafe {
16400            crate::support::Ref::new(AnimRefU32 {
16401                raw: core::ptr::NonNull::new_unchecked(
16402                    ffi::whiteout_m3_M3RigidBody_get_dynamicState(self.raw.as_ptr()),
16403                ),
16404            })
16405        }
16406    }
16407
16408    pub fn dynamic_state_mut(&mut self) -> crate::support::RefMut<'_, AnimRefU32> {
16409        // SAFETY: as above; `&mut self` guarantees exclusivity.
16410        unsafe {
16411            crate::support::RefMut::new(AnimRefU32 {
16412                raw: core::ptr::NonNull::new_unchecked(
16413                    ffi::whiteout_m3_M3RigidBody_get_dynamicState(self.raw.as_ptr()),
16414                ),
16415            })
16416        }
16417    }
16418
16419    /// Dynamic blend-out duration (v4+)
16420    pub fn dynamic_blend_out(&self) -> f32 {
16421        // SAFETY: plain scalar read through a live handle.
16422        unsafe { ffi::whiteout_m3_M3RigidBody_get_dynamicBlendOut(self.raw.as_ptr()) }
16423    }
16424
16425    pub fn set_dynamic_blend_out(&mut self, value: f32) {
16426        // SAFETY: plain scalar write through a live handle.
16427        unsafe { ffi::whiteout_m3_M3RigidBody_set_dynamicBlendOut(self.raw.as_ptr(), value) }
16428    }
16429
16430    /// Collision shapes (PHSH)
16431    pub fn rigid_body_shape_len(&self) -> usize {
16432        // SAFETY: scalar read through a live handle.
16433        unsafe { ffi::whiteout_m3_M3RigidBody_get_rigidBodyShape_count(self.raw.as_ptr()) }
16434    }
16435
16436    /// Borrows element `index` in place. `None` when out of range.
16437    pub fn rigid_body_shape(&self, index: usize) -> Option<crate::support::Ref<'_, PhysicsShape>> {
16438        if index >= self.rigid_body_shape_len() {
16439            return None;
16440        }
16441        // SAFETY: index checked above; the pointer is interior to `self`.
16442        unsafe {
16443            Some(crate::support::Ref::new(PhysicsShape {
16444                raw: core::ptr::NonNull::new_unchecked(
16445                    ffi::whiteout_m3_M3RigidBody_get_rigidBodyShape_at(self.raw.as_ptr(), index),
16446                ),
16447            }))
16448        }
16449    }
16450
16451    pub fn rigid_body_shape_mut(
16452        &mut self,
16453        index: usize,
16454    ) -> Option<crate::support::RefMut<'_, PhysicsShape>> {
16455        if index >= self.rigid_body_shape_len() {
16456            return None;
16457        }
16458        // SAFETY: as above; `&mut self` guarantees exclusivity.
16459        unsafe {
16460            Some(crate::support::RefMut::new(PhysicsShape {
16461                raw: core::ptr::NonNull::new_unchecked(
16462                    ffi::whiteout_m3_M3RigidBody_get_rigidBodyShape_at(self.raw.as_ptr(), index),
16463                ),
16464            }))
16465        }
16466    }
16467
16468    /// Iterate the elements, borrowing each in turn.
16469    pub fn rigid_body_shape_iter(
16470        &self,
16471    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, PhysicsShape>> {
16472        (0..self.rigid_body_shape_len())
16473            .map(move |i| self.rigid_body_shape(i).expect("index below len"))
16474    }
16475
16476    pub fn resize_rigid_body_shape(&mut self, count: usize) {
16477        // SAFETY: exclusive access, so no borrow is outstanding.
16478        unsafe { ffi::whiteout_m3_M3RigidBody_resize_rigidBodyShape(self.raw.as_ptr(), count) }
16479    }
16480
16481    /// Rigid body flags
16482    pub fn flags(&self) -> RigidBodyFlag {
16483        // SAFETY: scalar read; a flag set accepts any bits.
16484        RigidBodyFlag(unsafe { ffi::whiteout_m3_M3RigidBody_get_flags(self.raw.as_ptr()) })
16485    }
16486
16487    pub fn set_flags(&mut self, value: RigidBodyFlag) {
16488        // SAFETY: scalar write through a live handle.
16489        unsafe { ffi::whiteout_m3_M3RigidBody_set_flags(self.raw.as_ptr(), value.0) }
16490    }
16491
16492    /// Local force channel bitmask
16493    pub fn local_forces(&self) -> u16 {
16494        // SAFETY: plain scalar read through a live handle.
16495        unsafe { ffi::whiteout_m3_M3RigidBody_get_localForces(self.raw.as_ptr()) }
16496    }
16497
16498    pub fn set_local_forces(&mut self, value: u16) {
16499        // SAFETY: plain scalar write through a live handle.
16500        unsafe { ffi::whiteout_m3_M3RigidBody_set_localForces(self.raw.as_ptr(), value) }
16501    }
16502
16503    /// World force channel bitmask
16504    pub fn world_forces(&self) -> u16 {
16505        // SAFETY: plain scalar read through a live handle.
16506        unsafe { ffi::whiteout_m3_M3RigidBody_get_worldForces(self.raw.as_ptr()) }
16507    }
16508
16509    pub fn set_world_forces(&mut self, value: u16) {
16510        // SAFETY: plain scalar write through a live handle.
16511        unsafe { ffi::whiteout_m3_M3RigidBody_set_worldForces(self.raw.as_ptr(), value) }
16512    }
16513
16514    /// Simulation priority
16515    pub fn priority(&self) -> u32 {
16516        // SAFETY: plain scalar read through a live handle.
16517        unsafe { ffi::whiteout_m3_M3RigidBody_get_priority(self.raw.as_ptr()) }
16518    }
16519
16520    pub fn set_priority(&mut self, value: u32) {
16521        // SAFETY: plain scalar write through a live handle.
16522        unsafe { ffi::whiteout_m3_M3RigidBody_set_priority(self.raw.as_ptr(), value) }
16523    }
16524}
16525
16526impl Default for RigidBody {
16527    fn default() -> Self {
16528        Self::new()
16529    }
16530}
16531
16532/// PHYJ — Physics joint (v0, 180 bytes)
16533///
16534/// Connects two rigid bodies with limit, friction, and break-threshold parameters.
16535pub struct PhysicsJoint {
16536    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3PhysicsJoint>,
16537}
16538
16539impl Drop for PhysicsJoint {
16540    fn drop(&mut self) {
16541        // SAFETY: `raw` came from a native constructor and Drop runs once.
16542        unsafe { ffi::whiteout_m3_M3PhysicsJoint_delete(self.raw.as_ptr()) }
16543    }
16544}
16545
16546impl PhysicsJoint {
16547    /// # Safety
16548    /// `raw` must be a live handle this value takes ownership of.
16549    #[allow(dead_code)] // used by whichever methods return this type
16550    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3PhysicsJoint) -> Option<Self> {
16551        core::ptr::NonNull::new(raw).map(|raw| PhysicsJoint { raw })
16552    }
16553}
16554
16555// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
16556// is deliberately NOT implemented — the C++ types make no documented
16557// guarantee about concurrent use, and claiming one we haven't verified
16558// would be unsound. See `@bind thread_safe` in the plan.
16559unsafe impl Send for PhysicsJoint {}
16560
16561impl core::fmt::Debug for PhysicsJoint {
16562    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
16563        f.debug_struct("PhysicsJoint").finish_non_exhaustive()
16564    }
16565}
16566
16567impl PhysicsJoint {
16568    /// # Panics
16569    /// Panics if the native allocation fails.
16570    pub fn new() -> Self {
16571        // SAFETY: the native constructor returns a live handle; a null here
16572        // means the library is unusable.
16573        unsafe {
16574            let raw = ffi::whiteout_m3_M3PhysicsJoint_new();
16575            Self::from_raw(raw).expect("native PhysicsJoint allocation failed")
16576        }
16577    }
16578
16579    /// Joint type
16580    pub fn joint_type(&self) -> u32 {
16581        // SAFETY: plain scalar read through a live handle.
16582        unsafe { ffi::whiteout_m3_M3PhysicsJoint_get_jointType(self.raw.as_ptr()) }
16583    }
16584
16585    pub fn set_joint_type(&mut self, value: u32) {
16586        // SAFETY: plain scalar write through a live handle.
16587        unsafe { ffi::whiteout_m3_M3PhysicsJoint_set_jointType(self.raw.as_ptr(), value) }
16588    }
16589
16590    /// First bone index
16591    pub fn bone_index_1(&self) -> u32 {
16592        // SAFETY: plain scalar read through a live handle.
16593        unsafe { ffi::whiteout_m3_M3PhysicsJoint_get_boneIndex1(self.raw.as_ptr()) }
16594    }
16595
16596    pub fn set_bone_index_1(&mut self, value: u32) {
16597        // SAFETY: plain scalar write through a live handle.
16598        unsafe { ffi::whiteout_m3_M3PhysicsJoint_set_boneIndex1(self.raw.as_ptr(), value) }
16599    }
16600
16601    /// Second bone index
16602    pub fn bone_index_2(&self) -> u32 {
16603        // SAFETY: plain scalar read through a live handle.
16604        unsafe { ffi::whiteout_m3_M3PhysicsJoint_get_boneIndex2(self.raw.as_ptr()) }
16605    }
16606
16607    pub fn set_bone_index_2(&mut self, value: u32) {
16608        // SAFETY: plain scalar write through a live handle.
16609        unsafe { ffi::whiteout_m3_M3PhysicsJoint_set_boneIndex2(self.raw.as_ptr(), value) }
16610    }
16611
16612    /// Enable angular limits
16613    pub fn enable_limits(&self) -> u32 {
16614        // SAFETY: plain scalar read through a live handle.
16615        unsafe { ffi::whiteout_m3_M3PhysicsJoint_get_enableLimits(self.raw.as_ptr()) }
16616    }
16617
16618    pub fn set_enable_limits(&mut self, value: u32) {
16619        // SAFETY: plain scalar write through a live handle.
16620        unsafe { ffi::whiteout_m3_M3PhysicsJoint_set_enableLimits(self.raw.as_ptr(), value) }
16621    }
16622
16623    /// Minimum limit angle
16624    pub fn limit_min(&self) -> f32 {
16625        // SAFETY: plain scalar read through a live handle.
16626        unsafe { ffi::whiteout_m3_M3PhysicsJoint_get_limitMin(self.raw.as_ptr()) }
16627    }
16628
16629    pub fn set_limit_min(&mut self, value: f32) {
16630        // SAFETY: plain scalar write through a live handle.
16631        unsafe { ffi::whiteout_m3_M3PhysicsJoint_set_limitMin(self.raw.as_ptr(), value) }
16632    }
16633
16634    /// Maximum limit angle
16635    pub fn limit_max(&self) -> f32 {
16636        // SAFETY: plain scalar read through a live handle.
16637        unsafe { ffi::whiteout_m3_M3PhysicsJoint_get_limitMax(self.raw.as_ptr()) }
16638    }
16639
16640    pub fn set_limit_max(&mut self, value: f32) {
16641        // SAFETY: plain scalar write through a live handle.
16642        unsafe { ffi::whiteout_m3_M3PhysicsJoint_set_limitMax(self.raw.as_ptr(), value) }
16643    }
16644
16645    /// Cone constraint angle
16646    pub fn cone_angle(&self) -> f32 {
16647        // SAFETY: plain scalar read through a live handle.
16648        unsafe { ffi::whiteout_m3_M3PhysicsJoint_get_coneAngle(self.raw.as_ptr()) }
16649    }
16650
16651    pub fn set_cone_angle(&mut self, value: f32) {
16652        // SAFETY: plain scalar write through a live handle.
16653        unsafe { ffi::whiteout_m3_M3PhysicsJoint_set_coneAngle(self.raw.as_ptr(), value) }
16654    }
16655
16656    /// Enable joint friction
16657    pub fn enable_friction(&self) -> u32 {
16658        // SAFETY: plain scalar read through a live handle.
16659        unsafe { ffi::whiteout_m3_M3PhysicsJoint_get_enableFriction(self.raw.as_ptr()) }
16660    }
16661
16662    pub fn set_enable_friction(&mut self, value: u32) {
16663        // SAFETY: plain scalar write through a live handle.
16664        unsafe { ffi::whiteout_m3_M3PhysicsJoint_set_enableFriction(self.raw.as_ptr(), value) }
16665    }
16666
16667    /// Friction coefficient
16668    pub fn friction(&self) -> f32 {
16669        // SAFETY: plain scalar read through a live handle.
16670        unsafe { ffi::whiteout_m3_M3PhysicsJoint_get_friction(self.raw.as_ptr()) }
16671    }
16672
16673    pub fn set_friction(&mut self, value: f32) {
16674        // SAFETY: plain scalar write through a live handle.
16675        unsafe { ffi::whiteout_m3_M3PhysicsJoint_set_friction(self.raw.as_ptr(), value) }
16676    }
16677
16678    /// Damping ratio
16679    pub fn damping_ratio(&self) -> f32 {
16680        // SAFETY: plain scalar read through a live handle.
16681        unsafe { ffi::whiteout_m3_M3PhysicsJoint_get_dampingRatio(self.raw.as_ptr()) }
16682    }
16683
16684    pub fn set_damping_ratio(&mut self, value: f32) {
16685        // SAFETY: plain scalar write through a live handle.
16686        unsafe { ffi::whiteout_m3_M3PhysicsJoint_set_dampingRatio(self.raw.as_ptr(), value) }
16687    }
16688
16689    /// Angular frequency
16690    pub fn angular_frequency(&self) -> f32 {
16691        // SAFETY: plain scalar read through a live handle.
16692        unsafe { ffi::whiteout_m3_M3PhysicsJoint_get_angularFrequency(self.raw.as_ptr()) }
16693    }
16694
16695    pub fn set_angular_frequency(&mut self, value: f32) {
16696        // SAFETY: plain scalar write through a live handle.
16697        unsafe { ffi::whiteout_m3_M3PhysicsJoint_set_angularFrequency(self.raw.as_ptr(), value) }
16698    }
16699
16700    /// Force threshold to break joint
16701    pub fn break_threshold(&self) -> f32 {
16702        // SAFETY: plain scalar read through a live handle.
16703        unsafe { ffi::whiteout_m3_M3PhysicsJoint_get_breakThreshold(self.raw.as_ptr()) }
16704    }
16705
16706    pub fn set_break_threshold(&mut self, value: f32) {
16707        // SAFETY: plain scalar write through a live handle.
16708        unsafe { ffi::whiteout_m3_M3PhysicsJoint_set_breakThreshold(self.raw.as_ptr(), value) }
16709    }
16710
16711    /// Enable shape constraint
16712    pub fn enable_shape(&self) -> u8 {
16713        // SAFETY: plain scalar read through a live handle.
16714        unsafe { ffi::whiteout_m3_M3PhysicsJoint_get_enableShape(self.raw.as_ptr()) }
16715    }
16716
16717    pub fn set_enable_shape(&mut self, value: u8) {
16718        // SAFETY: plain scalar write through a live handle.
16719        unsafe { ffi::whiteout_m3_M3PhysicsJoint_set_enableShape(self.raw.as_ptr(), value) }
16720    }
16721}
16722
16723impl Default for PhysicsJoint {
16724    fn default() -> Self {
16725        Self::new()
16726    }
16727}
16728
16729/// PHCT — Physics constraint (v0, 24 bytes)
16730///
16731/// Constrains two rigid bodies with break-force threshold.
16732pub struct PhysicsConstraint {
16733    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3PhysicsConstraint>,
16734}
16735
16736impl Drop for PhysicsConstraint {
16737    fn drop(&mut self) {
16738        // SAFETY: `raw` came from a native constructor and Drop runs once.
16739        unsafe { ffi::whiteout_m3_M3PhysicsConstraint_delete(self.raw.as_ptr()) }
16740    }
16741}
16742
16743impl PhysicsConstraint {
16744    /// # Safety
16745    /// `raw` must be a live handle this value takes ownership of.
16746    #[allow(dead_code)] // used by whichever methods return this type
16747    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3PhysicsConstraint) -> Option<Self> {
16748        core::ptr::NonNull::new(raw).map(|raw| PhysicsConstraint { raw })
16749    }
16750}
16751
16752// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
16753// is deliberately NOT implemented — the C++ types make no documented
16754// guarantee about concurrent use, and claiming one we haven't verified
16755// would be unsound. See `@bind thread_safe` in the plan.
16756unsafe impl Send for PhysicsConstraint {}
16757
16758impl core::fmt::Debug for PhysicsConstraint {
16759    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
16760        f.debug_struct("PhysicsConstraint").finish_non_exhaustive()
16761    }
16762}
16763
16764impl PhysicsConstraint {
16765    /// # Panics
16766    /// Panics if the native allocation fails.
16767    pub fn new() -> Self {
16768        // SAFETY: the native constructor returns a live handle; a null here
16769        // means the library is unusable.
16770        unsafe {
16771            let raw = ffi::whiteout_m3_M3PhysicsConstraint_new();
16772            Self::from_raw(raw).expect("native PhysicsConstraint allocation failed")
16773        }
16774    }
16775
16776    /// Dependent bone indices (U16_)
16777    /// Zero-copy view of the underlying `std::vector`.
16778    pub fn dependents(&self) -> &[u16] {
16779        // SAFETY: `_data`/`_count` describe one contiguous C++
16780        // allocation, borrowed for as long as `self` is.
16781        unsafe {
16782            let n = ffi::whiteout_m3_M3PhysicsConstraint_get_dependents_count(self.raw.as_ptr());
16783            let p = ffi::whiteout_m3_M3PhysicsConstraint_get_dependents_data(self.raw.as_ptr());
16784            if p.is_null() || n == 0 {
16785                &[]
16786            } else {
16787                core::slice::from_raw_parts(p, n)
16788            }
16789        }
16790    }
16791
16792    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
16793    pub fn dependents_mut(&mut self) -> &mut [u16] {
16794        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
16795        unsafe {
16796            let n = ffi::whiteout_m3_M3PhysicsConstraint_get_dependents_count(self.raw.as_ptr());
16797            let p = ffi::whiteout_m3_M3PhysicsConstraint_get_dependents_data(self.raw.as_ptr())
16798                as *mut u16;
16799            if p.is_null() || n == 0 {
16800                &mut []
16801            } else {
16802                core::slice::from_raw_parts_mut(p, n)
16803            }
16804        }
16805    }
16806
16807    pub fn set_dependents(&mut self, values: &[u16]) {
16808        // SAFETY: the native side copies `values` before returning.
16809        unsafe {
16810            ffi::whiteout_m3_M3PhysicsConstraint_assign_dependents(
16811                self.raw.as_ptr(),
16812                values.as_ptr() as *const _,
16813                values.len(),
16814            )
16815        }
16816    }
16817
16818    pub fn resize_dependents(&mut self, count: usize) {
16819        // SAFETY: reallocation is safe here precisely because
16820        // `&mut self` means no slice borrow is outstanding.
16821        unsafe { ffi::whiteout_m3_M3PhysicsConstraint_resize_dependents(self.raw.as_ptr(), count) }
16822    }
16823
16824    /// First rigid body index
16825    pub fn rigid_body_1(&self) -> u16 {
16826        // SAFETY: plain scalar read through a live handle.
16827        unsafe { ffi::whiteout_m3_M3PhysicsConstraint_get_rigidBody1(self.raw.as_ptr()) }
16828    }
16829
16830    pub fn set_rigid_body_1(&mut self, value: u16) {
16831        // SAFETY: plain scalar write through a live handle.
16832        unsafe { ffi::whiteout_m3_M3PhysicsConstraint_set_rigidBody1(self.raw.as_ptr(), value) }
16833    }
16834
16835    /// Second rigid body index
16836    pub fn rigid_body_2(&self) -> u16 {
16837        // SAFETY: plain scalar read through a live handle.
16838        unsafe { ffi::whiteout_m3_M3PhysicsConstraint_get_rigidBody2(self.raw.as_ptr()) }
16839    }
16840
16841    pub fn set_rigid_body_2(&mut self, value: u16) {
16842        // SAFETY: plain scalar write through a live handle.
16843        unsafe { ffi::whiteout_m3_M3PhysicsConstraint_set_rigidBody2(self.raw.as_ptr(), value) }
16844    }
16845
16846    /// Force required to break constraint
16847    pub fn break_force(&self) -> f32 {
16848        // SAFETY: plain scalar read through a live handle.
16849        unsafe { ffi::whiteout_m3_M3PhysicsConstraint_get_breakForce(self.raw.as_ptr()) }
16850    }
16851
16852    pub fn set_break_force(&mut self, value: f32) {
16853        // SAFETY: plain scalar write through a live handle.
16854        unsafe { ffi::whiteout_m3_M3PhysicsConstraint_set_breakForce(self.raw.as_ptr(), value) }
16855    }
16856}
16857
16858impl Default for PhysicsConstraint {
16859    fn default() -> Self {
16860        Self::new()
16861    }
16862}
16863
16864/// PHCC — Cloth collider (v0, 76 bytes)
16865///
16866/// Capsule-shaped collider used by cloth simulation.
16867pub struct ClothCollider {
16868    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3ClothCollider>,
16869}
16870
16871impl Drop for ClothCollider {
16872    fn drop(&mut self) {
16873        // SAFETY: `raw` came from a native constructor and Drop runs once.
16874        unsafe { ffi::whiteout_m3_M3ClothCollider_delete(self.raw.as_ptr()) }
16875    }
16876}
16877
16878impl ClothCollider {
16879    /// # Safety
16880    /// `raw` must be a live handle this value takes ownership of.
16881    #[allow(dead_code)] // used by whichever methods return this type
16882    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3ClothCollider) -> Option<Self> {
16883        core::ptr::NonNull::new(raw).map(|raw| ClothCollider { raw })
16884    }
16885}
16886
16887// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
16888// is deliberately NOT implemented — the C++ types make no documented
16889// guarantee about concurrent use, and claiming one we haven't verified
16890// would be unsound. See `@bind thread_safe` in the plan.
16891unsafe impl Send for ClothCollider {}
16892
16893impl core::fmt::Debug for ClothCollider {
16894    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
16895        f.debug_struct("ClothCollider").finish_non_exhaustive()
16896    }
16897}
16898
16899impl ClothCollider {
16900    /// # Panics
16901    /// Panics if the native allocation fails.
16902    pub fn new() -> Self {
16903        // SAFETY: the native constructor returns a live handle; a null here
16904        // means the library is unusable.
16905        unsafe {
16906            let raw = ffi::whiteout_m3_M3ClothCollider_new();
16907            Self::from_raw(raw).expect("native ClothCollider allocation failed")
16908        }
16909    }
16910
16911    /// Capsule radius
16912    pub fn radius(&self) -> f32 {
16913        // SAFETY: plain scalar read through a live handle.
16914        unsafe { ffi::whiteout_m3_M3ClothCollider_get_radius(self.raw.as_ptr()) }
16915    }
16916
16917    pub fn set_radius(&mut self, value: f32) {
16918        // SAFETY: plain scalar write through a live handle.
16919        unsafe { ffi::whiteout_m3_M3ClothCollider_set_radius(self.raw.as_ptr(), value) }
16920    }
16921
16922    /// Capsule height
16923    pub fn height(&self) -> f32 {
16924        // SAFETY: plain scalar read through a live handle.
16925        unsafe { ffi::whiteout_m3_M3ClothCollider_get_height(self.raw.as_ptr()) }
16926    }
16927
16928    pub fn set_height(&mut self, value: f32) {
16929        // SAFETY: plain scalar write through a live handle.
16930        unsafe { ffi::whiteout_m3_M3ClothCollider_set_height(self.raw.as_ptr(), value) }
16931    }
16932
16933    /// Alignment padding
16934    pub fn padding(&self) -> u32 {
16935        // SAFETY: plain scalar read through a live handle.
16936        unsafe { ffi::whiteout_m3_M3ClothCollider_get_padding(self.raw.as_ptr()) }
16937    }
16938
16939    pub fn set_padding(&mut self, value: u32) {
16940        // SAFETY: plain scalar write through a live handle.
16941        unsafe { ffi::whiteout_m3_M3ClothCollider_set_padding(self.raw.as_ptr(), value) }
16942    }
16943}
16944
16945impl Default for ClothCollider {
16946    fn default() -> Self {
16947        Self::new()
16948    }
16949}
16950
16951/// PHAC — Cloth proxy (v0, 32 bytes)
16952///
16953/// Maps cloth vertices to proxy geometry for collision.
16954pub struct ClothProxy {
16955    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3ClothProxy>,
16956}
16957
16958impl Drop for ClothProxy {
16959    fn drop(&mut self) {
16960        // SAFETY: `raw` came from a native constructor and Drop runs once.
16961        unsafe { ffi::whiteout_m3_M3ClothProxy_delete(self.raw.as_ptr()) }
16962    }
16963}
16964
16965impl ClothProxy {
16966    /// # Safety
16967    /// `raw` must be a live handle this value takes ownership of.
16968    #[allow(dead_code)] // used by whichever methods return this type
16969    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3ClothProxy) -> Option<Self> {
16970        core::ptr::NonNull::new(raw).map(|raw| ClothProxy { raw })
16971    }
16972}
16973
16974// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
16975// is deliberately NOT implemented — the C++ types make no documented
16976// guarantee about concurrent use, and claiming one we haven't verified
16977// would be unsound. See `@bind thread_safe` in the plan.
16978unsafe impl Send for ClothProxy {}
16979
16980impl core::fmt::Debug for ClothProxy {
16981    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
16982        f.debug_struct("ClothProxy").finish_non_exhaustive()
16983    }
16984}
16985
16986impl ClothProxy {
16987    /// # Panics
16988    /// Panics if the native allocation fails.
16989    pub fn new() -> Self {
16990        // SAFETY: the native constructor returns a live handle; a null here
16991        // means the library is unusable.
16992        unsafe {
16993            let raw = ffi::whiteout_m3_M3ClothProxy_new();
16994            Self::from_raw(raw).expect("native ClothProxy allocation failed")
16995        }
16996    }
16997
16998    /// Proxy mesh index
16999    pub fn proxy_index(&self) -> u32 {
17000        // SAFETY: plain scalar read through a live handle.
17001        unsafe { ffi::whiteout_m3_M3ClothProxy_get_proxyIndex(self.raw.as_ptr()) }
17002    }
17003
17004    pub fn set_proxy_index(&mut self, value: u32) {
17005        // SAFETY: plain scalar write through a live handle.
17006        unsafe { ffi::whiteout_m3_M3ClothProxy_set_proxyIndex(self.raw.as_ptr(), value) }
17007    }
17008
17009    /// Cloth mesh index
17010    pub fn cloth_index(&self) -> u32 {
17011        // SAFETY: plain scalar read through a live handle.
17012        unsafe { ffi::whiteout_m3_M3ClothProxy_get_clothIndex(self.raw.as_ptr()) }
17013    }
17014
17015    pub fn set_cloth_index(&mut self, value: u32) {
17016        // SAFETY: plain scalar write through a live handle.
17017        unsafe { ffi::whiteout_m3_M3ClothProxy_set_clothIndex(self.raw.as_ptr(), value) }
17018    }
17019
17020    /// Proxy vertex data (U64_)
17021    /// Zero-copy view of the underlying `std::vector`.
17022    pub fn proxy_vertices(&self) -> &[u64] {
17023        // SAFETY: `_data`/`_count` describe one contiguous C++
17024        // allocation, borrowed for as long as `self` is.
17025        unsafe {
17026            let n = ffi::whiteout_m3_M3ClothProxy_get_proxyVertices_count(self.raw.as_ptr());
17027            let p = ffi::whiteout_m3_M3ClothProxy_get_proxyVertices_data(self.raw.as_ptr());
17028            if p.is_null() || n == 0 {
17029                &[]
17030            } else {
17031                core::slice::from_raw_parts(p, n)
17032            }
17033        }
17034    }
17035
17036    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
17037    pub fn proxy_vertices_mut(&mut self) -> &mut [u64] {
17038        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
17039        unsafe {
17040            let n = ffi::whiteout_m3_M3ClothProxy_get_proxyVertices_count(self.raw.as_ptr());
17041            let p =
17042                ffi::whiteout_m3_M3ClothProxy_get_proxyVertices_data(self.raw.as_ptr()) as *mut u64;
17043            if p.is_null() || n == 0 {
17044                &mut []
17045            } else {
17046                core::slice::from_raw_parts_mut(p, n)
17047            }
17048        }
17049    }
17050
17051    pub fn set_proxy_vertices(&mut self, values: &[u64]) {
17052        // SAFETY: the native side copies `values` before returning.
17053        unsafe {
17054            ffi::whiteout_m3_M3ClothProxy_assign_proxyVertices(
17055                self.raw.as_ptr(),
17056                values.as_ptr() as *const _,
17057                values.len(),
17058            )
17059        }
17060    }
17061
17062    pub fn resize_proxy_vertices(&mut self, count: usize) {
17063        // SAFETY: reallocation is safe here precisely because
17064        // `&mut self` means no slice borrow is outstanding.
17065        unsafe { ffi::whiteout_m3_M3ClothProxy_resize_proxyVertices(self.raw.as_ptr(), count) }
17066    }
17067
17068    /// Proxy blend weights (U32_)
17069    /// Zero-copy view of the underlying `std::vector`.
17070    pub fn proxy_weights(&self) -> &[u32] {
17071        // SAFETY: `_data`/`_count` describe one contiguous C++
17072        // allocation, borrowed for as long as `self` is.
17073        unsafe {
17074            let n = ffi::whiteout_m3_M3ClothProxy_get_proxyWeights_count(self.raw.as_ptr());
17075            let p = ffi::whiteout_m3_M3ClothProxy_get_proxyWeights_data(self.raw.as_ptr());
17076            if p.is_null() || n == 0 {
17077                &[]
17078            } else {
17079                core::slice::from_raw_parts(p, n)
17080            }
17081        }
17082    }
17083
17084    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
17085    pub fn proxy_weights_mut(&mut self) -> &mut [u32] {
17086        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
17087        unsafe {
17088            let n = ffi::whiteout_m3_M3ClothProxy_get_proxyWeights_count(self.raw.as_ptr());
17089            let p =
17090                ffi::whiteout_m3_M3ClothProxy_get_proxyWeights_data(self.raw.as_ptr()) as *mut u32;
17091            if p.is_null() || n == 0 {
17092                &mut []
17093            } else {
17094                core::slice::from_raw_parts_mut(p, n)
17095            }
17096        }
17097    }
17098
17099    pub fn set_proxy_weights(&mut self, values: &[u32]) {
17100        // SAFETY: the native side copies `values` before returning.
17101        unsafe {
17102            ffi::whiteout_m3_M3ClothProxy_assign_proxyWeights(
17103                self.raw.as_ptr(),
17104                values.as_ptr() as *const _,
17105                values.len(),
17106            )
17107        }
17108    }
17109
17110    pub fn resize_proxy_weights(&mut self, count: usize) {
17111        // SAFETY: reallocation is safe here precisely because
17112        // `&mut self` means no slice borrow is outstanding.
17113        unsafe { ffi::whiteout_m3_M3ClothProxy_resize_proxyWeights(self.raw.as_ptr(), count) }
17114    }
17115}
17116
17117impl Default for ClothProxy {
17118    fn default() -> Self {
17119        Self::new()
17120    }
17121}
17122
17123/// PHCL — Cloth physics (v0–v4, 192 bytes)
17124///
17125/// Full cloth simulation configuration: skin bone binding, stiffness parameters, damping, wind/explosion/gravity scales, colliders, and proxies. Added in MODL v28.
17126pub struct ClothPhysics {
17127    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3ClothPhysics>,
17128}
17129
17130impl Drop for ClothPhysics {
17131    fn drop(&mut self) {
17132        // SAFETY: `raw` came from a native constructor and Drop runs once.
17133        unsafe { ffi::whiteout_m3_M3ClothPhysics_delete(self.raw.as_ptr()) }
17134    }
17135}
17136
17137impl ClothPhysics {
17138    /// # Safety
17139    /// `raw` must be a live handle this value takes ownership of.
17140    #[allow(dead_code)] // used by whichever methods return this type
17141    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3ClothPhysics) -> Option<Self> {
17142        core::ptr::NonNull::new(raw).map(|raw| ClothPhysics { raw })
17143    }
17144}
17145
17146// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
17147// is deliberately NOT implemented — the C++ types make no documented
17148// guarantee about concurrent use, and claiming one we haven't verified
17149// would be unsound. See `@bind thread_safe` in the plan.
17150unsafe impl Send for ClothPhysics {}
17151
17152impl core::fmt::Debug for ClothPhysics {
17153    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
17154        f.debug_struct("ClothPhysics").finish_non_exhaustive()
17155    }
17156}
17157
17158impl ClothPhysics {
17159    /// # Panics
17160    /// Panics if the native allocation fails.
17161    pub fn new() -> Self {
17162        // SAFETY: the native constructor returns a live handle; a null here
17163        // means the library is unusable.
17164        unsafe {
17165            let raw = ffi::whiteout_m3_M3ClothPhysics_new();
17166            Self::from_raw(raw).expect("native ClothPhysics allocation failed")
17167        }
17168    }
17169
17170    /// Number of cloth mesh sections
17171    pub fn cloth_mesh_count(&self) -> u32 {
17172        // SAFETY: plain scalar read through a live handle.
17173        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_clothMeshCount(self.raw.as_ptr()) }
17174    }
17175
17176    pub fn set_cloth_mesh_count(&mut self, value: u32) {
17177        // SAFETY: plain scalar write through a live handle.
17178        unsafe { ffi::whiteout_m3_M3ClothPhysics_set_clothMeshCount(self.raw.as_ptr(), value) }
17179    }
17180
17181    /// Number of skin bones
17182    pub fn skin_bone_count(&self) -> u32 {
17183        // SAFETY: plain scalar read through a live handle.
17184        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_skinBoneCount(self.raw.as_ptr()) }
17185    }
17186
17187    pub fn set_skin_bone_count(&mut self, value: u32) {
17188        // SAFETY: plain scalar write through a live handle.
17189        unsafe { ffi::whiteout_m3_M3ClothPhysics_set_skinBoneCount(self.raw.as_ptr(), value) }
17190    }
17191
17192    /// Skin bone indices (U16_)
17193    /// Zero-copy view of the underlying `std::vector`.
17194    pub fn skin_bones(&self) -> &[u16] {
17195        // SAFETY: `_data`/`_count` describe one contiguous C++
17196        // allocation, borrowed for as long as `self` is.
17197        unsafe {
17198            let n = ffi::whiteout_m3_M3ClothPhysics_get_skinBones_count(self.raw.as_ptr());
17199            let p = ffi::whiteout_m3_M3ClothPhysics_get_skinBones_data(self.raw.as_ptr());
17200            if p.is_null() || n == 0 {
17201                &[]
17202            } else {
17203                core::slice::from_raw_parts(p, n)
17204            }
17205        }
17206    }
17207
17208    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
17209    pub fn skin_bones_mut(&mut self) -> &mut [u16] {
17210        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
17211        unsafe {
17212            let n = ffi::whiteout_m3_M3ClothPhysics_get_skinBones_count(self.raw.as_ptr());
17213            let p =
17214                ffi::whiteout_m3_M3ClothPhysics_get_skinBones_data(self.raw.as_ptr()) as *mut u16;
17215            if p.is_null() || n == 0 {
17216                &mut []
17217            } else {
17218                core::slice::from_raw_parts_mut(p, n)
17219            }
17220        }
17221    }
17222
17223    pub fn set_skin_bones(&mut self, values: &[u16]) {
17224        // SAFETY: the native side copies `values` before returning.
17225        unsafe {
17226            ffi::whiteout_m3_M3ClothPhysics_assign_skinBones(
17227                self.raw.as_ptr(),
17228                values.as_ptr() as *const _,
17229                values.len(),
17230            )
17231        }
17232    }
17233
17234    pub fn resize_skin_bones(&mut self, count: usize) {
17235        // SAFETY: reallocation is safe here precisely because
17236        // `&mut self` means no slice borrow is outstanding.
17237        unsafe { ffi::whiteout_m3_M3ClothPhysics_resize_skinBones(self.raw.as_ptr(), count) }
17238    }
17239
17240    /// Per-vertex simulation enable flags (U8__)
17241    /// Zero-copy view of the underlying `std::vector`.
17242    pub fn sim_enabled(&self) -> &[u8] {
17243        // SAFETY: `_data`/`_count` describe one contiguous C++
17244        // allocation, borrowed for as long as `self` is.
17245        unsafe {
17246            let n = ffi::whiteout_m3_M3ClothPhysics_get_simEnabled_count(self.raw.as_ptr());
17247            let p = ffi::whiteout_m3_M3ClothPhysics_get_simEnabled_data(self.raw.as_ptr());
17248            if p.is_null() || n == 0 {
17249                &[]
17250            } else {
17251                core::slice::from_raw_parts(p, n)
17252            }
17253        }
17254    }
17255
17256    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
17257    pub fn sim_enabled_mut(&mut self) -> &mut [u8] {
17258        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
17259        unsafe {
17260            let n = ffi::whiteout_m3_M3ClothPhysics_get_simEnabled_count(self.raw.as_ptr());
17261            let p =
17262                ffi::whiteout_m3_M3ClothPhysics_get_simEnabled_data(self.raw.as_ptr()) as *mut u8;
17263            if p.is_null() || n == 0 {
17264                &mut []
17265            } else {
17266                core::slice::from_raw_parts_mut(p, n)
17267            }
17268        }
17269    }
17270
17271    pub fn set_sim_enabled(&mut self, values: &[u8]) {
17272        // SAFETY: the native side copies `values` before returning.
17273        unsafe {
17274            ffi::whiteout_m3_M3ClothPhysics_assign_simEnabled(
17275                self.raw.as_ptr(),
17276                values.as_ptr() as *const _,
17277                values.len(),
17278            )
17279        }
17280    }
17281
17282    pub fn resize_sim_enabled(&mut self, count: usize) {
17283        // SAFETY: reallocation is safe here precisely because
17284        // `&mut self` means no slice borrow is outstanding.
17285        unsafe { ffi::whiteout_m3_M3ClothPhysics_resize_simEnabled(self.raw.as_ptr(), count) }
17286    }
17287
17288    /// Per-vertex bone indices (U32_)
17289    /// Zero-copy view of the underlying `std::vector`.
17290    pub fn vertex_bones(&self) -> &[u32] {
17291        // SAFETY: `_data`/`_count` describe one contiguous C++
17292        // allocation, borrowed for as long as `self` is.
17293        unsafe {
17294            let n = ffi::whiteout_m3_M3ClothPhysics_get_vertexBones_count(self.raw.as_ptr());
17295            let p = ffi::whiteout_m3_M3ClothPhysics_get_vertexBones_data(self.raw.as_ptr());
17296            if p.is_null() || n == 0 {
17297                &[]
17298            } else {
17299                core::slice::from_raw_parts(p, n)
17300            }
17301        }
17302    }
17303
17304    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
17305    pub fn vertex_bones_mut(&mut self) -> &mut [u32] {
17306        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
17307        unsafe {
17308            let n = ffi::whiteout_m3_M3ClothPhysics_get_vertexBones_count(self.raw.as_ptr());
17309            let p =
17310                ffi::whiteout_m3_M3ClothPhysics_get_vertexBones_data(self.raw.as_ptr()) as *mut u32;
17311            if p.is_null() || n == 0 {
17312                &mut []
17313            } else {
17314                core::slice::from_raw_parts_mut(p, n)
17315            }
17316        }
17317    }
17318
17319    pub fn set_vertex_bones(&mut self, values: &[u32]) {
17320        // SAFETY: the native side copies `values` before returning.
17321        unsafe {
17322            ffi::whiteout_m3_M3ClothPhysics_assign_vertexBones(
17323                self.raw.as_ptr(),
17324                values.as_ptr() as *const _,
17325                values.len(),
17326            )
17327        }
17328    }
17329
17330    pub fn resize_vertex_bones(&mut self, count: usize) {
17331        // SAFETY: reallocation is safe here precisely because
17332        // `&mut self` means no slice borrow is outstanding.
17333        unsafe { ffi::whiteout_m3_M3ClothPhysics_resize_vertexBones(self.raw.as_ptr(), count) }
17334    }
17335
17336    /// Per-vertex bone weights (U32_)
17337    /// Zero-copy view of the underlying `std::vector`.
17338    pub fn vertex_weights(&self) -> &[u32] {
17339        // SAFETY: `_data`/`_count` describe one contiguous C++
17340        // allocation, borrowed for as long as `self` is.
17341        unsafe {
17342            let n = ffi::whiteout_m3_M3ClothPhysics_get_vertexWeights_count(self.raw.as_ptr());
17343            let p = ffi::whiteout_m3_M3ClothPhysics_get_vertexWeights_data(self.raw.as_ptr());
17344            if p.is_null() || n == 0 {
17345                &[]
17346            } else {
17347                core::slice::from_raw_parts(p, n)
17348            }
17349        }
17350    }
17351
17352    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
17353    pub fn vertex_weights_mut(&mut self) -> &mut [u32] {
17354        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
17355        unsafe {
17356            let n = ffi::whiteout_m3_M3ClothPhysics_get_vertexWeights_count(self.raw.as_ptr());
17357            let p = ffi::whiteout_m3_M3ClothPhysics_get_vertexWeights_data(self.raw.as_ptr())
17358                as *mut u32;
17359            if p.is_null() || n == 0 {
17360                &mut []
17361            } else {
17362                core::slice::from_raw_parts_mut(p, n)
17363            }
17364        }
17365    }
17366
17367    pub fn set_vertex_weights(&mut self, values: &[u32]) {
17368        // SAFETY: the native side copies `values` before returning.
17369        unsafe {
17370            ffi::whiteout_m3_M3ClothPhysics_assign_vertexWeights(
17371                self.raw.as_ptr(),
17372                values.as_ptr() as *const _,
17373                values.len(),
17374            )
17375        }
17376    }
17377
17378    pub fn resize_vertex_weights(&mut self, count: usize) {
17379        // SAFETY: reallocation is safe here precisely because
17380        // `&mut self` means no slice borrow is outstanding.
17381        unsafe { ffi::whiteout_m3_M3ClothPhysics_resize_vertexWeights(self.raw.as_ptr(), count) }
17382    }
17383
17384    /// Cloth colliders (PHCC)
17385    pub fn colliders_len(&self) -> usize {
17386        // SAFETY: scalar read through a live handle.
17387        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_colliders_count(self.raw.as_ptr()) }
17388    }
17389
17390    /// Borrows element `index` in place. `None` when out of range.
17391    pub fn colliders(&self, index: usize) -> Option<crate::support::Ref<'_, ClothCollider>> {
17392        if index >= self.colliders_len() {
17393            return None;
17394        }
17395        // SAFETY: index checked above; the pointer is interior to `self`.
17396        unsafe {
17397            Some(crate::support::Ref::new(ClothCollider {
17398                raw: core::ptr::NonNull::new_unchecked(
17399                    ffi::whiteout_m3_M3ClothPhysics_get_colliders_at(self.raw.as_ptr(), index),
17400                ),
17401            }))
17402        }
17403    }
17404
17405    pub fn colliders_mut(
17406        &mut self,
17407        index: usize,
17408    ) -> Option<crate::support::RefMut<'_, ClothCollider>> {
17409        if index >= self.colliders_len() {
17410            return None;
17411        }
17412        // SAFETY: as above; `&mut self` guarantees exclusivity.
17413        unsafe {
17414            Some(crate::support::RefMut::new(ClothCollider {
17415                raw: core::ptr::NonNull::new_unchecked(
17416                    ffi::whiteout_m3_M3ClothPhysics_get_colliders_at(self.raw.as_ptr(), index),
17417                ),
17418            }))
17419        }
17420    }
17421
17422    /// Iterate the elements, borrowing each in turn.
17423    pub fn colliders_iter(
17424        &self,
17425    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, ClothCollider>> {
17426        (0..self.colliders_len()).map(move |i| self.colliders(i).expect("index below len"))
17427    }
17428
17429    pub fn resize_colliders(&mut self, count: usize) {
17430        // SAFETY: exclusive access, so no borrow is outstanding.
17431        unsafe { ffi::whiteout_m3_M3ClothPhysics_resize_colliders(self.raw.as_ptr(), count) }
17432    }
17433
17434    /// Cloth proxies (PHAC)
17435    pub fn proxies_len(&self) -> usize {
17436        // SAFETY: scalar read through a live handle.
17437        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_proxies_count(self.raw.as_ptr()) }
17438    }
17439
17440    /// Borrows element `index` in place. `None` when out of range.
17441    pub fn proxies(&self, index: usize) -> Option<crate::support::Ref<'_, ClothProxy>> {
17442        if index >= self.proxies_len() {
17443            return None;
17444        }
17445        // SAFETY: index checked above; the pointer is interior to `self`.
17446        unsafe {
17447            Some(crate::support::Ref::new(ClothProxy {
17448                raw: core::ptr::NonNull::new_unchecked(
17449                    ffi::whiteout_m3_M3ClothPhysics_get_proxies_at(self.raw.as_ptr(), index),
17450                ),
17451            }))
17452        }
17453    }
17454
17455    pub fn proxies_mut(&mut self, index: usize) -> Option<crate::support::RefMut<'_, ClothProxy>> {
17456        if index >= self.proxies_len() {
17457            return None;
17458        }
17459        // SAFETY: as above; `&mut self` guarantees exclusivity.
17460        unsafe {
17461            Some(crate::support::RefMut::new(ClothProxy {
17462                raw: core::ptr::NonNull::new_unchecked(
17463                    ffi::whiteout_m3_M3ClothPhysics_get_proxies_at(self.raw.as_ptr(), index),
17464                ),
17465            }))
17466        }
17467    }
17468
17469    /// Iterate the elements, borrowing each in turn.
17470    pub fn proxies_iter(
17471        &self,
17472    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, ClothProxy>> {
17473        (0..self.proxies_len()).map(move |i| self.proxies(i).expect("index below len"))
17474    }
17475
17476    pub fn resize_proxies(&mut self, count: usize) {
17477        // SAFETY: exclusive access, so no borrow is outstanding.
17478        unsafe { ffi::whiteout_m3_M3ClothPhysics_resize_proxies(self.raw.as_ptr(), count) }
17479    }
17480
17481    /// Cloth density
17482    pub fn density(&self) -> f32 {
17483        // SAFETY: plain scalar read through a live handle.
17484        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_density(self.raw.as_ptr()) }
17485    }
17486
17487    pub fn set_density(&mut self, value: f32) {
17488        // SAFETY: plain scalar write through a live handle.
17489        unsafe { ffi::whiteout_m3_M3ClothPhysics_set_density(self.raw.as_ptr(), value) }
17490    }
17491
17492    /// Tracking factor
17493    pub fn tracking(&self) -> f32 {
17494        // SAFETY: plain scalar read through a live handle.
17495        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_tracking(self.raw.as_ptr()) }
17496    }
17497
17498    pub fn set_tracking(&mut self, value: f32) {
17499        // SAFETY: plain scalar write through a live handle.
17500        unsafe { ffi::whiteout_m3_M3ClothPhysics_set_tracking(self.raw.as_ptr(), value) }
17501    }
17502
17503    /// Stretch stiffness
17504    pub fn stretch_stiffness(&self) -> f32 {
17505        // SAFETY: plain scalar read through a live handle.
17506        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_stretchStiffness(self.raw.as_ptr()) }
17507    }
17508
17509    pub fn set_stretch_stiffness(&mut self, value: f32) {
17510        // SAFETY: plain scalar write through a live handle.
17511        unsafe { ffi::whiteout_m3_M3ClothPhysics_set_stretchStiffness(self.raw.as_ptr(), value) }
17512    }
17513
17514    /// Horizontal stiffness
17515    pub fn horizontal_stiffness(&self) -> f32 {
17516        // SAFETY: plain scalar read through a live handle.
17517        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_horizontalStiffness(self.raw.as_ptr()) }
17518    }
17519
17520    pub fn set_horizontal_stiffness(&mut self, value: f32) {
17521        // SAFETY: plain scalar write through a live handle.
17522        unsafe { ffi::whiteout_m3_M3ClothPhysics_set_horizontalStiffness(self.raw.as_ptr(), value) }
17523    }
17524
17525    /// Bending stiffness
17526    pub fn bending_stiffness(&self) -> f32 {
17527        // SAFETY: plain scalar read through a live handle.
17528        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_bendingStiffness(self.raw.as_ptr()) }
17529    }
17530
17531    pub fn set_bending_stiffness(&mut self, value: f32) {
17532        // SAFETY: plain scalar write through a live handle.
17533        unsafe { ffi::whiteout_m3_M3ClothPhysics_set_bendingStiffness(self.raw.as_ptr(), value) }
17534    }
17535
17536    /// Damping coefficient
17537    pub fn damping(&self) -> f32 {
17538        // SAFETY: plain scalar read through a live handle.
17539        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_damping(self.raw.as_ptr()) }
17540    }
17541
17542    pub fn set_damping(&mut self, value: f32) {
17543        // SAFETY: plain scalar write through a live handle.
17544        unsafe { ffi::whiteout_m3_M3ClothPhysics_set_damping(self.raw.as_ptr(), value) }
17545    }
17546
17547    /// Friction coefficient
17548    pub fn friction(&self) -> f32 {
17549        // SAFETY: plain scalar read through a live handle.
17550        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_friction(self.raw.as_ptr()) }
17551    }
17552
17553    pub fn set_friction(&mut self, value: f32) {
17554        // SAFETY: plain scalar write through a live handle.
17555        unsafe { ffi::whiteout_m3_M3ClothPhysics_set_friction(self.raw.as_ptr(), value) }
17556    }
17557
17558    /// Gravity influence
17559    pub fn gravity(&self) -> f32 {
17560        // SAFETY: plain scalar read through a live handle.
17561        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_gravity(self.raw.as_ptr()) }
17562    }
17563
17564    pub fn set_gravity(&mut self, value: f32) {
17565        // SAFETY: plain scalar write through a live handle.
17566        unsafe { ffi::whiteout_m3_M3ClothPhysics_set_gravity(self.raw.as_ptr(), value) }
17567    }
17568
17569    /// Explosion force scale
17570    pub fn explosion_scale(&self) -> f32 {
17571        // SAFETY: plain scalar read through a live handle.
17572        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_explosionScale(self.raw.as_ptr()) }
17573    }
17574
17575    pub fn set_explosion_scale(&mut self, value: f32) {
17576        // SAFETY: plain scalar write through a live handle.
17577        unsafe { ffi::whiteout_m3_M3ClothPhysics_set_explosionScale(self.raw.as_ptr(), value) }
17578    }
17579
17580    /// Wind force scale
17581    pub fn wind_scale(&self) -> f32 {
17582        // SAFETY: plain scalar read through a live handle.
17583        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_windScale(self.raw.as_ptr()) }
17584    }
17585
17586    pub fn set_wind_scale(&mut self, value: f32) {
17587        // SAFETY: plain scalar write through a live handle.
17588        unsafe { ffi::whiteout_m3_M3ClothPhysics_set_windScale(self.raw.as_ptr(), value) }
17589    }
17590
17591    /// Shear stiffness
17592    pub fn shear_stiffness(&self) -> f32 {
17593        // SAFETY: plain scalar read through a live handle.
17594        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_shearStiffness(self.raw.as_ptr()) }
17595    }
17596
17597    pub fn set_shear_stiffness(&mut self, value: f32) {
17598        // SAFETY: plain scalar write through a live handle.
17599        unsafe { ffi::whiteout_m3_M3ClothPhysics_set_shearStiffness(self.raw.as_ptr(), value) }
17600    }
17601
17602    /// Drag factor
17603    pub fn drag_factor(&self) -> f32 {
17604        // SAFETY: plain scalar read through a live handle.
17605        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_dragFactor(self.raw.as_ptr()) }
17606    }
17607
17608    pub fn set_drag_factor(&mut self, value: f32) {
17609        // SAFETY: plain scalar write through a live handle.
17610        unsafe { ffi::whiteout_m3_M3ClothPhysics_set_dragFactor(self.raw.as_ptr(), value) }
17611    }
17612
17613    /// Lift factor (v4+)
17614    pub fn lift_factor(&self) -> f32 {
17615        // SAFETY: plain scalar read through a live handle.
17616        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_liftFactor(self.raw.as_ptr()) }
17617    }
17618
17619    pub fn set_lift_factor(&mut self, value: f32) {
17620        // SAFETY: plain scalar write through a live handle.
17621        unsafe { ffi::whiteout_m3_M3ClothPhysics_set_liftFactor(self.raw.as_ptr(), value) }
17622    }
17623
17624    /// Sphere collider stiffness (v4+)
17625    pub fn sphere_stiffness(&self) -> f32 {
17626        // SAFETY: plain scalar read through a live handle.
17627        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_sphereStiffness(self.raw.as_ptr()) }
17628    }
17629
17630    pub fn set_sphere_stiffness(&mut self, value: f32) {
17631        // SAFETY: plain scalar write through a live handle.
17632        unsafe { ffi::whiteout_m3_M3ClothPhysics_set_sphereStiffness(self.raw.as_ptr(), value) }
17633    }
17634
17635    /// Flatten mode (v4+)
17636    pub fn flatten(&self) -> u32 {
17637        // SAFETY: plain scalar read through a live handle.
17638        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_flatten(self.raw.as_ptr()) }
17639    }
17640
17641    pub fn set_flatten(&mut self, value: u32) {
17642        // SAFETY: plain scalar write through a live handle.
17643        unsafe { ffi::whiteout_m3_M3ClothPhysics_set_flatten(self.raw.as_ptr(), value) }
17644    }
17645
17646    /// Animated active state
17647    /// Borrows the field in place — no copy, no allocation.
17648    pub fn active(&self) -> crate::support::Ref<'_, AnimRefU32> {
17649        // SAFETY: an interior pointer into `self`, valid for this
17650        // borrow and never freed by the `Ref`.
17651        unsafe {
17652            crate::support::Ref::new(AnimRefU32 {
17653                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3ClothPhysics_get_active(
17654                    self.raw.as_ptr(),
17655                )),
17656            })
17657        }
17658    }
17659
17660    pub fn active_mut(&mut self) -> crate::support::RefMut<'_, AnimRefU32> {
17661        // SAFETY: as above; `&mut self` guarantees exclusivity.
17662        unsafe {
17663            crate::support::RefMut::new(AnimRefU32 {
17664                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3ClothPhysics_get_active(
17665                    self.raw.as_ptr(),
17666                )),
17667            })
17668        }
17669    }
17670
17671    /// Use skin mesh for collision
17672    pub fn use_skin_collision(&self) -> u32 {
17673        // SAFETY: plain scalar read through a live handle.
17674        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_useSkinCollision(self.raw.as_ptr()) }
17675    }
17676
17677    pub fn set_use_skin_collision(&mut self, value: u32) {
17678        // SAFETY: plain scalar write through a live handle.
17679        unsafe { ffi::whiteout_m3_M3ClothPhysics_set_useSkinCollision(self.raw.as_ptr(), value) }
17680    }
17681
17682    /// Skin collision offset
17683    pub fn skin_offset(&self) -> f32 {
17684        // SAFETY: plain scalar read through a live handle.
17685        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_skinOffset(self.raw.as_ptr()) }
17686    }
17687
17688    pub fn set_skin_offset(&mut self, value: f32) {
17689        // SAFETY: plain scalar write through a live handle.
17690        unsafe { ffi::whiteout_m3_M3ClothPhysics_set_skinOffset(self.raw.as_ptr(), value) }
17691    }
17692
17693    /// Skin collision exponent
17694    pub fn skin_exponent(&self) -> f32 {
17695        // SAFETY: plain scalar read through a live handle.
17696        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_skinExponent(self.raw.as_ptr()) }
17697    }
17698
17699    pub fn set_skin_exponent(&mut self, value: f32) {
17700        // SAFETY: plain scalar write through a live handle.
17701        unsafe { ffi::whiteout_m3_M3ClothPhysics_set_skinExponent(self.raw.as_ptr(), value) }
17702    }
17703
17704    /// Skin collision stiffness
17705    pub fn skin_stiffness(&self) -> f32 {
17706        // SAFETY: plain scalar read through a live handle.
17707        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_skinStiffness(self.raw.as_ptr()) }
17708    }
17709
17710    pub fn set_skin_stiffness(&mut self, value: f32) {
17711        // SAFETY: plain scalar write through a live handle.
17712        unsafe { ffi::whiteout_m3_M3ClothPhysics_set_skinStiffness(self.raw.as_ptr(), value) }
17713    }
17714
17715    /// Local force channel bitmask
17716    pub fn local_channels(&self) -> u32 {
17717        // SAFETY: plain scalar read through a live handle.
17718        unsafe { ffi::whiteout_m3_M3ClothPhysics_get_localChannels(self.raw.as_ptr()) }
17719    }
17720
17721    pub fn set_local_channels(&mut self, value: u32) {
17722        // SAFETY: plain scalar write through a live handle.
17723        unsafe { ffi::whiteout_m3_M3ClothPhysics_set_localChannels(self.raw.as_ptr(), value) }
17724    }
17725
17726    /// Local wind direction and magnitude
17727    pub fn local_wind(&self) -> crate::math::Vector3f {
17728        // SAFETY: the getter returns an interior pointer to a
17729        // layout-identical POD; we copy it out immediately.
17730        unsafe {
17731            *(ffi::whiteout_m3_M3ClothPhysics_get_localWind(self.raw.as_ptr())
17732                as *const crate::math::Vector3f)
17733        }
17734    }
17735
17736    pub fn set_local_wind(&mut self, value: crate::math::Vector3f) {
17737        // SAFETY: as above, in the other direction.
17738        unsafe {
17739            ffi::whiteout_m3_M3ClothPhysics_set_localWind(
17740                self.raw.as_ptr(),
17741                &value as *const crate::math::Vector3f as *const _,
17742            )
17743        }
17744    }
17745}
17746
17747impl Default for ClothPhysics {
17748    fn default() -> Self {
17749        Self::new()
17750    }
17751}
17752
17753/// LITE — Light source (v0–v7, 212 bytes)
17754///
17755/// Omni, spot, or directional light with animated diffuse/specular colors, intensity, decay, attenuation start/end, and spot-light hot-spot/falloff.
17756pub struct Light {
17757    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3Light>,
17758}
17759
17760impl Drop for Light {
17761    fn drop(&mut self) {
17762        // SAFETY: `raw` came from a native constructor and Drop runs once.
17763        unsafe { ffi::whiteout_m3_M3Light_delete(self.raw.as_ptr()) }
17764    }
17765}
17766
17767impl Light {
17768    /// # Safety
17769    /// `raw` must be a live handle this value takes ownership of.
17770    #[allow(dead_code)] // used by whichever methods return this type
17771    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3Light) -> Option<Self> {
17772        core::ptr::NonNull::new(raw).map(|raw| Light { raw })
17773    }
17774}
17775
17776// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
17777// is deliberately NOT implemented — the C++ types make no documented
17778// guarantee about concurrent use, and claiming one we haven't verified
17779// would be unsound. See `@bind thread_safe` in the plan.
17780unsafe impl Send for Light {}
17781
17782impl core::fmt::Debug for Light {
17783    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
17784        f.debug_struct("Light").finish_non_exhaustive()
17785    }
17786}
17787
17788impl Light {
17789    /// # Panics
17790    /// Panics if the native allocation fails.
17791    pub fn new() -> Self {
17792        // SAFETY: the native constructor returns a live handle; a null here
17793        // means the library is unusable.
17794        unsafe {
17795            let raw = ffi::whiteout_m3_M3Light_new();
17796            Self::from_raw(raw).expect("native Light allocation failed")
17797        }
17798    }
17799
17800    /// Light type (omni/spot/directional)
17801    pub fn light_type(&self) -> LightType {
17802        // SAFETY: scalar read; the discriminant is validated below.
17803        unsafe { ffi::whiteout_m3_M3Light_get_lightType(self.raw.as_ptr()) }
17804            .try_into()
17805            .expect("unknown enum discriminant from the native library")
17806    }
17807
17808    pub fn set_light_type(&mut self, value: LightType) {
17809        // SAFETY: scalar write through a live handle.
17810        unsafe { ffi::whiteout_m3_M3Light_set_lightType(self.raw.as_ptr(), value as i32) }
17811    }
17812
17813    /// Index into BONE array
17814    pub fn bone_index(&self) -> u16 {
17815        // SAFETY: plain scalar read through a live handle.
17816        unsafe { ffi::whiteout_m3_M3Light_get_boneIndex(self.raw.as_ptr()) }
17817    }
17818
17819    pub fn set_bone_index(&mut self, value: u16) {
17820        // SAFETY: plain scalar write through a live handle.
17821        unsafe { ffi::whiteout_m3_M3Light_set_boneIndex(self.raw.as_ptr(), value) }
17822    }
17823
17824    /// Light flags (shadows, specular, AO, etc.)
17825    pub fn flags(&self) -> LightFlag {
17826        // SAFETY: scalar read; a flag set accepts any bits.
17827        LightFlag(unsafe { ffi::whiteout_m3_M3Light_get_flags(self.raw.as_ptr()) })
17828    }
17829
17830    pub fn set_flags(&mut self, value: LightFlag) {
17831        // SAFETY: scalar write through a live handle.
17832        unsafe { ffi::whiteout_m3_M3Light_set_flags(self.raw.as_ptr(), value.0) }
17833    }
17834
17835    /// LOD cut-off level
17836    pub fn lod_cut(&self) -> u32 {
17837        // SAFETY: plain scalar read through a live handle.
17838        unsafe { ffi::whiteout_m3_M3Light_get_lodCut(self.raw.as_ptr()) }
17839    }
17840
17841    pub fn set_lod_cut(&mut self, value: u32) {
17842        // SAFETY: plain scalar write through a live handle.
17843        unsafe { ffi::whiteout_m3_M3Light_set_lodCut(self.raw.as_ptr(), value) }
17844    }
17845
17846    /// Shadow LOD cut-off level
17847    pub fn shadow_lod_cut(&self) -> u32 {
17848        // SAFETY: plain scalar read through a live handle.
17849        unsafe { ffi::whiteout_m3_M3Light_get_shadowLodCut(self.raw.as_ptr()) }
17850    }
17851
17852    pub fn set_shadow_lod_cut(&mut self, value: u32) {
17853        // SAFETY: plain scalar write through a live handle.
17854        unsafe { ffi::whiteout_m3_M3Light_set_shadowLodCut(self.raw.as_ptr(), value) }
17855    }
17856
17857    /// Animated diffuse color (RGB)
17858    /// Borrows the field in place — no copy, no allocation.
17859    pub fn diffuse_color(&self) -> crate::support::Ref<'_, AnimRefVector3f> {
17860        // SAFETY: an interior pointer into `self`, valid for this
17861        // borrow and never freed by the `Ref`.
17862        unsafe {
17863            crate::support::Ref::new(AnimRefVector3f {
17864                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Light_get_diffuseColor(
17865                    self.raw.as_ptr(),
17866                )),
17867            })
17868        }
17869    }
17870
17871    pub fn diffuse_color_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector3f> {
17872        // SAFETY: as above; `&mut self` guarantees exclusivity.
17873        unsafe {
17874            crate::support::RefMut::new(AnimRefVector3f {
17875                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Light_get_diffuseColor(
17876                    self.raw.as_ptr(),
17877                )),
17878            })
17879        }
17880    }
17881
17882    /// Animated intensity multiplier
17883    /// Borrows the field in place — no copy, no allocation.
17884    pub fn intensity_multiplier(&self) -> crate::support::Ref<'_, AnimRefF32> {
17885        // SAFETY: an interior pointer into `self`, valid for this
17886        // borrow and never freed by the `Ref`.
17887        unsafe {
17888            crate::support::Ref::new(AnimRefF32 {
17889                raw: core::ptr::NonNull::new_unchecked(
17890                    ffi::whiteout_m3_M3Light_get_intensityMultiplier(self.raw.as_ptr()),
17891                ),
17892            })
17893        }
17894    }
17895
17896    pub fn intensity_multiplier_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
17897        // SAFETY: as above; `&mut self` guarantees exclusivity.
17898        unsafe {
17899            crate::support::RefMut::new(AnimRefF32 {
17900                raw: core::ptr::NonNull::new_unchecked(
17901                    ffi::whiteout_m3_M3Light_get_intensityMultiplier(self.raw.as_ptr()),
17902                ),
17903            })
17904        }
17905    }
17906
17907    /// Animated specular color (RGB)
17908    /// Borrows the field in place — no copy, no allocation.
17909    pub fn specular_color(&self) -> crate::support::Ref<'_, AnimRefVector3f> {
17910        // SAFETY: an interior pointer into `self`, valid for this
17911        // borrow and never freed by the `Ref`.
17912        unsafe {
17913            crate::support::Ref::new(AnimRefVector3f {
17914                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Light_get_specularColor(
17915                    self.raw.as_ptr(),
17916                )),
17917            })
17918        }
17919    }
17920
17921    pub fn specular_color_mut(&mut self) -> crate::support::RefMut<'_, AnimRefVector3f> {
17922        // SAFETY: as above; `&mut self` guarantees exclusivity.
17923        unsafe {
17924            crate::support::RefMut::new(AnimRefVector3f {
17925                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Light_get_specularColor(
17926                    self.raw.as_ptr(),
17927                )),
17928            })
17929        }
17930    }
17931
17932    /// Animated specular multiplier
17933    /// Borrows the field in place — no copy, no allocation.
17934    pub fn specular_multiplier(&self) -> crate::support::Ref<'_, AnimRefF32> {
17935        // SAFETY: an interior pointer into `self`, valid for this
17936        // borrow and never freed by the `Ref`.
17937        unsafe {
17938            crate::support::Ref::new(AnimRefF32 {
17939                raw: core::ptr::NonNull::new_unchecked(
17940                    ffi::whiteout_m3_M3Light_get_specularMultiplier(self.raw.as_ptr()),
17941                ),
17942            })
17943        }
17944    }
17945
17946    pub fn specular_multiplier_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
17947        // SAFETY: as above; `&mut self` guarantees exclusivity.
17948        unsafe {
17949            crate::support::RefMut::new(AnimRefF32 {
17950                raw: core::ptr::NonNull::new_unchecked(
17951                    ffi::whiteout_m3_M3Light_get_specularMultiplier(self.raw.as_ptr()),
17952                ),
17953            })
17954        }
17955    }
17956
17957    /// Animated distance decay exponent
17958    /// Borrows the field in place — no copy, no allocation.
17959    pub fn decay(&self) -> crate::support::Ref<'_, AnimRefF32> {
17960        // SAFETY: an interior pointer into `self`, valid for this
17961        // borrow and never freed by the `Ref`.
17962        unsafe {
17963            crate::support::Ref::new(AnimRefF32 {
17964                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Light_get_decay(
17965                    self.raw.as_ptr(),
17966                )),
17967            })
17968        }
17969    }
17970
17971    pub fn decay_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
17972        // SAFETY: as above; `&mut self` guarantees exclusivity.
17973        unsafe {
17974            crate::support::RefMut::new(AnimRefF32 {
17975                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Light_get_decay(
17976                    self.raw.as_ptr(),
17977                )),
17978            })
17979        }
17980    }
17981
17982    /// Attenuation end distance
17983    pub fn attenuation_end(&self) -> f32 {
17984        // SAFETY: plain scalar read through a live handle.
17985        unsafe { ffi::whiteout_m3_M3Light_get_attenuationEnd(self.raw.as_ptr()) }
17986    }
17987
17988    pub fn set_attenuation_end(&mut self, value: f32) {
17989        // SAFETY: plain scalar write through a live handle.
17990        unsafe { ffi::whiteout_m3_M3Light_set_attenuationEnd(self.raw.as_ptr(), value) }
17991    }
17992
17993    /// Animated attenuation start distance
17994    /// Borrows the field in place — no copy, no allocation.
17995    pub fn attenuation_start(&self) -> crate::support::Ref<'_, AnimRefF32> {
17996        // SAFETY: an interior pointer into `self`, valid for this
17997        // borrow and never freed by the `Ref`.
17998        unsafe {
17999            crate::support::Ref::new(AnimRefF32 {
18000                raw: core::ptr::NonNull::new_unchecked(
18001                    ffi::whiteout_m3_M3Light_get_attenuationStart(self.raw.as_ptr()),
18002                ),
18003            })
18004        }
18005    }
18006
18007    pub fn attenuation_start_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
18008        // SAFETY: as above; `&mut self` guarantees exclusivity.
18009        unsafe {
18010            crate::support::RefMut::new(AnimRefF32 {
18011                raw: core::ptr::NonNull::new_unchecked(
18012                    ffi::whiteout_m3_M3Light_get_attenuationStart(self.raw.as_ptr()),
18013                ),
18014            })
18015        }
18016    }
18017
18018    /// Animated spot inner cone angle
18019    /// Borrows the field in place — no copy, no allocation.
18020    pub fn hot_spot(&self) -> crate::support::Ref<'_, AnimRefF32> {
18021        // SAFETY: an interior pointer into `self`, valid for this
18022        // borrow and never freed by the `Ref`.
18023        unsafe {
18024            crate::support::Ref::new(AnimRefF32 {
18025                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Light_get_hotSpot(
18026                    self.raw.as_ptr(),
18027                )),
18028            })
18029        }
18030    }
18031
18032    pub fn hot_spot_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
18033        // SAFETY: as above; `&mut self` guarantees exclusivity.
18034        unsafe {
18035            crate::support::RefMut::new(AnimRefF32 {
18036                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Light_get_hotSpot(
18037                    self.raw.as_ptr(),
18038                )),
18039            })
18040        }
18041    }
18042
18043    /// Animated spot outer cone falloff
18044    /// Borrows the field in place — no copy, no allocation.
18045    pub fn falloff(&self) -> crate::support::Ref<'_, AnimRefF32> {
18046        // SAFETY: an interior pointer into `self`, valid for this
18047        // borrow and never freed by the `Ref`.
18048        unsafe {
18049            crate::support::Ref::new(AnimRefF32 {
18050                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Light_get_falloff(
18051                    self.raw.as_ptr(),
18052                )),
18053            })
18054        }
18055    }
18056
18057    pub fn falloff_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
18058        // SAFETY: as above; `&mut self` guarantees exclusivity.
18059        unsafe {
18060            crate::support::RefMut::new(AnimRefF32 {
18061                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Light_get_falloff(
18062                    self.raw.as_ptr(),
18063                )),
18064            })
18065        }
18066    }
18067}
18068
18069impl Default for Light {
18070    fn default() -> Self {
18071        Self::new()
18072    }
18073}
18074
18075/// CAM_ — Camera (v2–v5, 144–264 bytes)
18076///
18077/// Bone-attached camera with animated FOV, clip planes, shadow clip distance, depth-of-field parameters, and version-dependent bokeh settings.
18078pub struct Camera {
18079    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3Camera>,
18080}
18081
18082impl Drop for Camera {
18083    fn drop(&mut self) {
18084        // SAFETY: `raw` came from a native constructor and Drop runs once.
18085        unsafe { ffi::whiteout_m3_M3Camera_delete(self.raw.as_ptr()) }
18086    }
18087}
18088
18089impl Camera {
18090    /// # Safety
18091    /// `raw` must be a live handle this value takes ownership of.
18092    #[allow(dead_code)] // used by whichever methods return this type
18093    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3Camera) -> Option<Self> {
18094        core::ptr::NonNull::new(raw).map(|raw| Camera { raw })
18095    }
18096}
18097
18098// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
18099// is deliberately NOT implemented — the C++ types make no documented
18100// guarantee about concurrent use, and claiming one we haven't verified
18101// would be unsound. See `@bind thread_safe` in the plan.
18102unsafe impl Send for Camera {}
18103
18104impl core::fmt::Debug for Camera {
18105    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
18106        f.debug_struct("Camera").finish_non_exhaustive()
18107    }
18108}
18109
18110impl Camera {
18111    /// # Panics
18112    /// Panics if the native allocation fails.
18113    pub fn new() -> Self {
18114        // SAFETY: the native constructor returns a live handle; a null here
18115        // means the library is unusable.
18116        unsafe {
18117            let raw = ffi::whiteout_m3_M3Camera_new();
18118            Self::from_raw(raw).expect("native Camera allocation failed")
18119        }
18120    }
18121
18122    /// Index into BONE array
18123    pub fn bone_index(&self) -> u32 {
18124        // SAFETY: plain scalar read through a live handle.
18125        unsafe { ffi::whiteout_m3_M3Camera_get_boneIndex(self.raw.as_ptr()) }
18126    }
18127
18128    pub fn set_bone_index(&mut self, value: u32) {
18129        // SAFETY: plain scalar write through a live handle.
18130        unsafe { ffi::whiteout_m3_M3Camera_set_boneIndex(self.raw.as_ptr(), value) }
18131    }
18132
18133    /// Camera name (`Ref<CHAR>`)
18134    pub fn name(&self) -> String {
18135        // SAFETY: the native side hands over an owned CString.
18136        unsafe {
18137            crate::support::take_string(ffi::whiteout_m3_M3Camera_get_name(self.raw.as_ptr()))
18138        }
18139    }
18140
18141    pub fn set_name(&mut self, value: &str) {
18142        let value = std::ffi::CString::new(value).unwrap_or_default();
18143        // SAFETY: the pointer outlives the call.
18144        unsafe { ffi::whiteout_m3_M3Camera_set_name(self.raw.as_ptr(), value.as_ptr()) }
18145    }
18146
18147    /// Animated FOV in radians (v2+)
18148    /// Borrows the field in place — no copy, no allocation.
18149    pub fn field_of_view(&self) -> crate::support::Ref<'_, AnimRefF32> {
18150        // SAFETY: an interior pointer into `self`, valid for this
18151        // borrow and never freed by the `Ref`.
18152        unsafe {
18153            crate::support::Ref::new(AnimRefF32 {
18154                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Camera_get_fieldOfView(
18155                    self.raw.as_ptr(),
18156                )),
18157            })
18158        }
18159    }
18160
18161    pub fn field_of_view_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
18162        // SAFETY: as above; `&mut self` guarantees exclusivity.
18163        unsafe {
18164            crate::support::RefMut::new(AnimRefF32 {
18165                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Camera_get_fieldOfView(
18166                    self.raw.as_ptr(),
18167                )),
18168            })
18169        }
18170    }
18171
18172    /// Use vertical FOV (0 or 1, v2+)
18173    pub fn use_vertical_fov(&self) -> u32 {
18174        // SAFETY: plain scalar read through a live handle.
18175        unsafe { ffi::whiteout_m3_M3Camera_get_useVerticalFOV(self.raw.as_ptr()) }
18176    }
18177
18178    pub fn set_use_vertical_fov(&mut self, value: u32) {
18179        // SAFETY: plain scalar write through a live handle.
18180        unsafe { ffi::whiteout_m3_M3Camera_set_useVerticalFOV(self.raw.as_ptr(), value) }
18181    }
18182
18183    /// DOF type (v5 only, default 3)
18184    pub fn dof_type(&self) -> u32 {
18185        // SAFETY: plain scalar read through a live handle.
18186        unsafe { ffi::whiteout_m3_M3Camera_get_dofType(self.raw.as_ptr()) }
18187    }
18188
18189    pub fn set_dof_type(&mut self, value: u32) {
18190        // SAFETY: plain scalar write through a live handle.
18191        unsafe { ffi::whiteout_m3_M3Camera_set_dofType(self.raw.as_ptr(), value) }
18192    }
18193
18194    /// Animated far clip plane (v3+)
18195    /// Borrows the field in place — no copy, no allocation.
18196    pub fn far_clip(&self) -> crate::support::Ref<'_, AnimRefF32> {
18197        // SAFETY: an interior pointer into `self`, valid for this
18198        // borrow and never freed by the `Ref`.
18199        unsafe {
18200            crate::support::Ref::new(AnimRefF32 {
18201                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Camera_get_farClip(
18202                    self.raw.as_ptr(),
18203                )),
18204            })
18205        }
18206    }
18207
18208    pub fn far_clip_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
18209        // SAFETY: as above; `&mut self` guarantees exclusivity.
18210        unsafe {
18211            crate::support::RefMut::new(AnimRefF32 {
18212                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Camera_get_farClip(
18213                    self.raw.as_ptr(),
18214                )),
18215            })
18216        }
18217    }
18218
18219    /// Animated near clip plane (v3+)
18220    /// Borrows the field in place — no copy, no allocation.
18221    pub fn near_clip(&self) -> crate::support::Ref<'_, AnimRefF32> {
18222        // SAFETY: an interior pointer into `self`, valid for this
18223        // borrow and never freed by the `Ref`.
18224        unsafe {
18225            crate::support::Ref::new(AnimRefF32 {
18226                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Camera_get_nearClip(
18227                    self.raw.as_ptr(),
18228                )),
18229            })
18230        }
18231    }
18232
18233    pub fn near_clip_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
18234        // SAFETY: as above; `&mut self` guarantees exclusivity.
18235        unsafe {
18236            crate::support::RefMut::new(AnimRefF32 {
18237                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Camera_get_nearClip(
18238                    self.raw.as_ptr(),
18239                )),
18240            })
18241        }
18242    }
18243
18244    /// Animated shadow clip distance (v2+)
18245    /// Borrows the field in place — no copy, no allocation.
18246    pub fn shadow_clip_distance(&self) -> crate::support::Ref<'_, AnimRefF32> {
18247        // SAFETY: an interior pointer into `self`, valid for this
18248        // borrow and never freed by the `Ref`.
18249        unsafe {
18250            crate::support::Ref::new(AnimRefF32 {
18251                raw: core::ptr::NonNull::new_unchecked(
18252                    ffi::whiteout_m3_M3Camera_get_shadowClipDistance(self.raw.as_ptr()),
18253                ),
18254            })
18255        }
18256    }
18257
18258    pub fn shadow_clip_distance_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
18259        // SAFETY: as above; `&mut self` guarantees exclusivity.
18260        unsafe {
18261            crate::support::RefMut::new(AnimRefF32 {
18262                raw: core::ptr::NonNull::new_unchecked(
18263                    ffi::whiteout_m3_M3Camera_get_shadowClipDistance(self.raw.as_ptr()),
18264                ),
18265            })
18266        }
18267    }
18268
18269    /// Animated DOF focal point distance (v2+)
18270    /// Borrows the field in place — no copy, no allocation.
18271    pub fn focus_distance(&self) -> crate::support::Ref<'_, AnimRefF32> {
18272        // SAFETY: an interior pointer into `self`, valid for this
18273        // borrow and never freed by the `Ref`.
18274        unsafe {
18275            crate::support::Ref::new(AnimRefF32 {
18276                raw: core::ptr::NonNull::new_unchecked(
18277                    ffi::whiteout_m3_M3Camera_get_focusDistance(self.raw.as_ptr()),
18278                ),
18279            })
18280        }
18281    }
18282
18283    pub fn focus_distance_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
18284        // SAFETY: as above; `&mut self` guarantees exclusivity.
18285        unsafe {
18286            crate::support::RefMut::new(AnimRefF32 {
18287                raw: core::ptr::NonNull::new_unchecked(
18288                    ffi::whiteout_m3_M3Camera_get_focusDistance(self.raw.as_ptr()),
18289                ),
18290            })
18291        }
18292    }
18293
18294    /// Animated DOF far focus range (v2+)
18295    /// Borrows the field in place — no copy, no allocation.
18296    pub fn far_focus_range(&self) -> crate::support::Ref<'_, AnimRefF32> {
18297        // SAFETY: an interior pointer into `self`, valid for this
18298        // borrow and never freed by the `Ref`.
18299        unsafe {
18300            crate::support::Ref::new(AnimRefF32 {
18301                raw: core::ptr::NonNull::new_unchecked(
18302                    ffi::whiteout_m3_M3Camera_get_farFocusRange(self.raw.as_ptr()),
18303                ),
18304            })
18305        }
18306    }
18307
18308    pub fn far_focus_range_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
18309        // SAFETY: as above; `&mut self` guarantees exclusivity.
18310        unsafe {
18311            crate::support::RefMut::new(AnimRefF32 {
18312                raw: core::ptr::NonNull::new_unchecked(
18313                    ffi::whiteout_m3_M3Camera_get_farFocusRange(self.raw.as_ptr()),
18314                ),
18315            })
18316        }
18317    }
18318
18319    /// Animated DOF near focus range (v2+)
18320    /// Borrows the field in place — no copy, no allocation.
18321    pub fn near_focus_range(&self) -> crate::support::Ref<'_, AnimRefF32> {
18322        // SAFETY: an interior pointer into `self`, valid for this
18323        // borrow and never freed by the `Ref`.
18324        unsafe {
18325            crate::support::Ref::new(AnimRefF32 {
18326                raw: core::ptr::NonNull::new_unchecked(
18327                    ffi::whiteout_m3_M3Camera_get_nearFocusRange(self.raw.as_ptr()),
18328                ),
18329            })
18330        }
18331    }
18332
18333    pub fn near_focus_range_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
18334        // SAFETY: as above; `&mut self` guarantees exclusivity.
18335        unsafe {
18336            crate::support::RefMut::new(AnimRefF32 {
18337                raw: core::ptr::NonNull::new_unchecked(
18338                    ffi::whiteout_m3_M3Camera_get_nearFocusRange(self.raw.as_ptr()),
18339                ),
18340            })
18341        }
18342    }
18343
18344    /// Animated near falloff start (v4+)
18345    /// Borrows the field in place — no copy, no allocation.
18346    pub fn near_falloff_start(&self) -> crate::support::Ref<'_, AnimRefF32> {
18347        // SAFETY: an interior pointer into `self`, valid for this
18348        // borrow and never freed by the `Ref`.
18349        unsafe {
18350            crate::support::Ref::new(AnimRefF32 {
18351                raw: core::ptr::NonNull::new_unchecked(
18352                    ffi::whiteout_m3_M3Camera_get_nearFalloffStart(self.raw.as_ptr()),
18353                ),
18354            })
18355        }
18356    }
18357
18358    pub fn near_falloff_start_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
18359        // SAFETY: as above; `&mut self` guarantees exclusivity.
18360        unsafe {
18361            crate::support::RefMut::new(AnimRefF32 {
18362                raw: core::ptr::NonNull::new_unchecked(
18363                    ffi::whiteout_m3_M3Camera_get_nearFalloffStart(self.raw.as_ptr()),
18364                ),
18365            })
18366        }
18367    }
18368
18369    /// Animated near falloff end (v4+)
18370    /// Borrows the field in place — no copy, no allocation.
18371    pub fn near_falloff_end(&self) -> crate::support::Ref<'_, AnimRefF32> {
18372        // SAFETY: an interior pointer into `self`, valid for this
18373        // borrow and never freed by the `Ref`.
18374        unsafe {
18375            crate::support::Ref::new(AnimRefF32 {
18376                raw: core::ptr::NonNull::new_unchecked(
18377                    ffi::whiteout_m3_M3Camera_get_nearFalloffEnd(self.raw.as_ptr()),
18378                ),
18379            })
18380        }
18381    }
18382
18383    pub fn near_falloff_end_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
18384        // SAFETY: as above; `&mut self` guarantees exclusivity.
18385        unsafe {
18386            crate::support::RefMut::new(AnimRefF32 {
18387                raw: core::ptr::NonNull::new_unchecked(
18388                    ffi::whiteout_m3_M3Camera_get_nearFalloffEnd(self.raw.as_ptr()),
18389                ),
18390            })
18391        }
18392    }
18393
18394    /// Animated DOF strength (v2+)
18395    /// Borrows the field in place — no copy, no allocation.
18396    pub fn dof_amount(&self) -> crate::support::Ref<'_, AnimRefF32> {
18397        // SAFETY: an interior pointer into `self`, valid for this
18398        // borrow and never freed by the `Ref`.
18399        unsafe {
18400            crate::support::Ref::new(AnimRefF32 {
18401                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Camera_get_dofAmount(
18402                    self.raw.as_ptr(),
18403                )),
18404            })
18405        }
18406    }
18407
18408    pub fn dof_amount_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
18409        // SAFETY: as above; `&mut self` guarantees exclusivity.
18410        unsafe {
18411            crate::support::RefMut::new(AnimRefF32 {
18412                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Camera_get_dofAmount(
18413                    self.raw.as_ptr(),
18414                )),
18415            })
18416        }
18417    }
18418
18419    /// Animated bokeh f-stop (v5+)
18420    /// Borrows the field in place — no copy, no allocation.
18421    pub fn bokeh_f_stop(&self) -> crate::support::Ref<'_, AnimRefF32> {
18422        // SAFETY: an interior pointer into `self`, valid for this
18423        // borrow and never freed by the `Ref`.
18424        unsafe {
18425            crate::support::Ref::new(AnimRefF32 {
18426                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Camera_get_bokehFStop(
18427                    self.raw.as_ptr(),
18428                )),
18429            })
18430        }
18431    }
18432
18433    pub fn bokeh_f_stop_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
18434        // SAFETY: as above; `&mut self` guarantees exclusivity.
18435        unsafe {
18436            crate::support::RefMut::new(AnimRefF32 {
18437                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Camera_get_bokehFStop(
18438                    self.raw.as_ptr(),
18439                )),
18440            })
18441        }
18442    }
18443
18444    /// Animated bokeh max CoC diameter (v5+)
18445    /// Borrows the field in place — no copy, no allocation.
18446    pub fn bokeh_max_co_c_diameter(&self) -> crate::support::Ref<'_, AnimRefF32> {
18447        // SAFETY: an interior pointer into `self`, valid for this
18448        // borrow and never freed by the `Ref`.
18449        unsafe {
18450            crate::support::Ref::new(AnimRefF32 {
18451                raw: core::ptr::NonNull::new_unchecked(
18452                    ffi::whiteout_m3_M3Camera_get_bokehMaxCoCDiameter(self.raw.as_ptr()),
18453                ),
18454            })
18455        }
18456    }
18457
18458    pub fn bokeh_max_co_c_diameter_mut(&mut self) -> crate::support::RefMut<'_, AnimRefF32> {
18459        // SAFETY: as above; `&mut self` guarantees exclusivity.
18460        unsafe {
18461            crate::support::RefMut::new(AnimRefF32 {
18462                raw: core::ptr::NonNull::new_unchecked(
18463                    ffi::whiteout_m3_M3Camera_get_bokehMaxCoCDiameter(self.raw.as_ptr()),
18464                ),
18465            })
18466        }
18467    }
18468}
18469
18470impl Default for Camera {
18471    fn default() -> Self {
18472        Self::new()
18473    }
18474}
18475
18476/// MODL — Model root chunk (v23–v30, 784–868 bytes)
18477///
18478/// 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+.
18479///
18480/// 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
18481pub struct Model {
18482    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3Model>,
18483}
18484
18485impl Drop for Model {
18486    fn drop(&mut self) {
18487        // SAFETY: `raw` came from a native constructor and Drop runs once.
18488        unsafe { ffi::whiteout_m3_M3Model_delete(self.raw.as_ptr()) }
18489    }
18490}
18491
18492impl Model {
18493    /// # Safety
18494    /// `raw` must be a live handle this value takes ownership of.
18495    #[allow(dead_code)] // used by whichever methods return this type
18496    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3Model) -> Option<Self> {
18497        core::ptr::NonNull::new(raw).map(|raw| Model { raw })
18498    }
18499}
18500
18501// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
18502// is deliberately NOT implemented — the C++ types make no documented
18503// guarantee about concurrent use, and claiming one we haven't verified
18504// would be unsound. See `@bind thread_safe` in the plan.
18505unsafe impl Send for Model {}
18506
18507impl core::fmt::Debug for Model {
18508    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
18509        f.debug_struct("Model").finish_non_exhaustive()
18510    }
18511}
18512
18513impl Model {
18514    /// # Panics
18515    /// Panics if the native allocation fails.
18516    pub fn new() -> Self {
18517        // SAFETY: the native constructor returns a live handle; a null here
18518        // means the library is unusable.
18519        unsafe {
18520            let raw = ffi::whiteout_m3_M3Model_new();
18521            Self::from_raw(raw).expect("native Model allocation failed")
18522        }
18523    }
18524
18525    /// Model file path (`Ref<CHAR>`)
18526    pub fn name(&self) -> String {
18527        // SAFETY: the native side hands over an owned CString.
18528        unsafe { crate::support::take_string(ffi::whiteout_m3_M3Model_get_name(self.raw.as_ptr())) }
18529    }
18530
18531    pub fn set_name(&mut self, value: &str) {
18532        let value = std::ffi::CString::new(value).unwrap_or_default();
18533        // SAFETY: the pointer outlives the call.
18534        unsafe { ffi::whiteout_m3_M3Model_set_name(self.raw.as_ptr(), value.as_ptr()) }
18535    }
18536
18537    /// Model flags (tangents, FOW, instancing, etc.)
18538    pub fn flags(&self) -> ModelFlag {
18539        // SAFETY: scalar read; a flag set accepts any bits.
18540        ModelFlag(unsafe { ffi::whiteout_m3_M3Model_get_flags(self.raw.as_ptr()) })
18541    }
18542
18543    pub fn set_flags(&mut self, value: ModelFlag) {
18544        // SAFETY: scalar write through a live handle.
18545        unsafe { ffi::whiteout_m3_M3Model_set_flags(self.raw.as_ptr(), value.0) }
18546    }
18547
18548    /// Animation sequences (SEQS)
18549    pub fn sequences_len(&self) -> usize {
18550        // SAFETY: scalar read through a live handle.
18551        unsafe { ffi::whiteout_m3_M3Model_get_sequences_count(self.raw.as_ptr()) }
18552    }
18553
18554    /// Borrows element `index` in place. `None` when out of range.
18555    pub fn sequences(&self, index: usize) -> Option<crate::support::Ref<'_, Sequence>> {
18556        if index >= self.sequences_len() {
18557            return None;
18558        }
18559        // SAFETY: index checked above; the pointer is interior to `self`.
18560        unsafe {
18561            Some(crate::support::Ref::new(Sequence {
18562                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Model_get_sequences_at(
18563                    self.raw.as_ptr(),
18564                    index,
18565                )),
18566            }))
18567        }
18568    }
18569
18570    pub fn sequences_mut(&mut self, index: usize) -> Option<crate::support::RefMut<'_, Sequence>> {
18571        if index >= self.sequences_len() {
18572            return None;
18573        }
18574        // SAFETY: as above; `&mut self` guarantees exclusivity.
18575        unsafe {
18576            Some(crate::support::RefMut::new(Sequence {
18577                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Model_get_sequences_at(
18578                    self.raw.as_ptr(),
18579                    index,
18580                )),
18581            }))
18582        }
18583    }
18584
18585    /// Iterate the elements, borrowing each in turn.
18586    pub fn sequences_iter(
18587        &self,
18588    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, Sequence>> {
18589        (0..self.sequences_len()).map(move |i| self.sequences(i).expect("index below len"))
18590    }
18591
18592    pub fn resize_sequences(&mut self, count: usize) {
18593        // SAFETY: exclusive access, so no borrow is outstanding.
18594        unsafe { ffi::whiteout_m3_M3Model_resize_sequences(self.raw.as_ptr(), count) }
18595    }
18596
18597    /// Sub-track containers (STC_) with keyframe refs
18598    pub fn sub_track_collections_len(&self) -> usize {
18599        // SAFETY: scalar read through a live handle.
18600        unsafe { ffi::whiteout_m3_M3Model_get_subTrackCollections_count(self.raw.as_ptr()) }
18601    }
18602
18603    /// Borrows element `index` in place. `None` when out of range.
18604    pub fn sub_track_collections(
18605        &self,
18606        index: usize,
18607    ) -> Option<crate::support::Ref<'_, SubTrackContainer>> {
18608        if index >= self.sub_track_collections_len() {
18609            return None;
18610        }
18611        // SAFETY: index checked above; the pointer is interior to `self`.
18612        unsafe {
18613            Some(crate::support::Ref::new(SubTrackContainer {
18614                raw: core::ptr::NonNull::new_unchecked(
18615                    ffi::whiteout_m3_M3Model_get_subTrackCollections_at(self.raw.as_ptr(), index),
18616                ),
18617            }))
18618        }
18619    }
18620
18621    pub fn sub_track_collections_mut(
18622        &mut self,
18623        index: usize,
18624    ) -> Option<crate::support::RefMut<'_, SubTrackContainer>> {
18625        if index >= self.sub_track_collections_len() {
18626            return None;
18627        }
18628        // SAFETY: as above; `&mut self` guarantees exclusivity.
18629        unsafe {
18630            Some(crate::support::RefMut::new(SubTrackContainer {
18631                raw: core::ptr::NonNull::new_unchecked(
18632                    ffi::whiteout_m3_M3Model_get_subTrackCollections_at(self.raw.as_ptr(), index),
18633                ),
18634            }))
18635        }
18636    }
18637
18638    /// Iterate the elements, borrowing each in turn.
18639    pub fn sub_track_collections_iter(
18640        &self,
18641    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, SubTrackContainer>> {
18642        (0..self.sub_track_collections_len())
18643            .map(move |i| self.sub_track_collections(i).expect("index below len"))
18644    }
18645
18646    pub fn resize_sub_track_collections(&mut self, count: usize) {
18647        // SAFETY: exclusive access, so no borrow is outstanding.
18648        unsafe { ffi::whiteout_m3_M3Model_resize_subTrackCollections(self.raw.as_ptr(), count) }
18649    }
18650
18651    /// Animation groups (STG_)
18652    pub fn animation_groups_len(&self) -> usize {
18653        // SAFETY: scalar read through a live handle.
18654        unsafe { ffi::whiteout_m3_M3Model_get_animationGroups_count(self.raw.as_ptr()) }
18655    }
18656
18657    /// Borrows element `index` in place. `None` when out of range.
18658    pub fn animation_groups(
18659        &self,
18660        index: usize,
18661    ) -> Option<crate::support::Ref<'_, AnimationGroup>> {
18662        if index >= self.animation_groups_len() {
18663            return None;
18664        }
18665        // SAFETY: index checked above; the pointer is interior to `self`.
18666        unsafe {
18667            Some(crate::support::Ref::new(AnimationGroup {
18668                raw: core::ptr::NonNull::new_unchecked(
18669                    ffi::whiteout_m3_M3Model_get_animationGroups_at(self.raw.as_ptr(), index),
18670                ),
18671            }))
18672        }
18673    }
18674
18675    pub fn animation_groups_mut(
18676        &mut self,
18677        index: usize,
18678    ) -> Option<crate::support::RefMut<'_, AnimationGroup>> {
18679        if index >= self.animation_groups_len() {
18680            return None;
18681        }
18682        // SAFETY: as above; `&mut self` guarantees exclusivity.
18683        unsafe {
18684            Some(crate::support::RefMut::new(AnimationGroup {
18685                raw: core::ptr::NonNull::new_unchecked(
18686                    ffi::whiteout_m3_M3Model_get_animationGroups_at(self.raw.as_ptr(), index),
18687                ),
18688            }))
18689        }
18690    }
18691
18692    /// Iterate the elements, borrowing each in turn.
18693    pub fn animation_groups_iter(
18694        &self,
18695    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, AnimationGroup>> {
18696        (0..self.animation_groups_len())
18697            .map(move |i| self.animation_groups(i).expect("index below len"))
18698    }
18699
18700    pub fn resize_animation_groups(&mut self, count: usize) {
18701        // SAFETY: exclusive access, so no borrow is outstanding.
18702        unsafe { ffi::whiteout_m3_M3Model_resize_animationGroups(self.raw.as_ptr(), count) }
18703    }
18704
18705    /// Bone animation sets (BSET, always null)
18706    pub fn bone_animation_sets_len(&self) -> usize {
18707        // SAFETY: scalar read through a live handle.
18708        unsafe { ffi::whiteout_m3_M3Model_get_boneAnimationSets_count(self.raw.as_ptr()) }
18709    }
18710
18711    /// Borrows element `index` in place. `None` when out of range.
18712    pub fn bone_animation_sets(
18713        &self,
18714        index: usize,
18715    ) -> Option<crate::support::Ref<'_, BoneAnimationSet>> {
18716        if index >= self.bone_animation_sets_len() {
18717            return None;
18718        }
18719        // SAFETY: index checked above; the pointer is interior to `self`.
18720        unsafe {
18721            Some(crate::support::Ref::new(BoneAnimationSet {
18722                raw: core::ptr::NonNull::new_unchecked(
18723                    ffi::whiteout_m3_M3Model_get_boneAnimationSets_at(self.raw.as_ptr(), index),
18724                ),
18725            }))
18726        }
18727    }
18728
18729    pub fn bone_animation_sets_mut(
18730        &mut self,
18731        index: usize,
18732    ) -> Option<crate::support::RefMut<'_, BoneAnimationSet>> {
18733        if index >= self.bone_animation_sets_len() {
18734            return None;
18735        }
18736        // SAFETY: as above; `&mut self` guarantees exclusivity.
18737        unsafe {
18738            Some(crate::support::RefMut::new(BoneAnimationSet {
18739                raw: core::ptr::NonNull::new_unchecked(
18740                    ffi::whiteout_m3_M3Model_get_boneAnimationSets_at(self.raw.as_ptr(), index),
18741                ),
18742            }))
18743        }
18744    }
18745
18746    /// Iterate the elements, borrowing each in turn.
18747    pub fn bone_animation_sets_iter(
18748        &self,
18749    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, BoneAnimationSet>> {
18750        (0..self.bone_animation_sets_len())
18751            .map(move |i| self.bone_animation_sets(i).expect("index below len"))
18752    }
18753
18754    pub fn resize_bone_animation_sets(&mut self, count: usize) {
18755        // SAFETY: exclusive access, so no borrow is outstanding.
18756        unsafe { ffi::whiteout_m3_M3Model_resize_boneAnimationSets(self.raw.as_ptr(), count) }
18757    }
18758
18759    /// Always 0
18760    pub fn animation_split_count(&self) -> u32 {
18761        // SAFETY: plain scalar read through a live handle.
18762        unsafe { ffi::whiteout_m3_M3Model_get_animationSplitCount(self.raw.as_ptr()) }
18763    }
18764
18765    pub fn set_animation_split_count(&mut self, value: u32) {
18766        // SAFETY: plain scalar write through a live handle.
18767        unsafe { ffi::whiteout_m3_M3Model_set_animationSplitCount(self.raw.as_ptr(), value) }
18768    }
18769
18770    /// Animation states (STS_)
18771    pub fn animation_states_len(&self) -> usize {
18772        // SAFETY: scalar read through a live handle.
18773        unsafe { ffi::whiteout_m3_M3Model_get_animationStates_count(self.raw.as_ptr()) }
18774    }
18775
18776    /// Borrows element `index` in place. `None` when out of range.
18777    pub fn animation_states(
18778        &self,
18779        index: usize,
18780    ) -> Option<crate::support::Ref<'_, AnimationState>> {
18781        if index >= self.animation_states_len() {
18782            return None;
18783        }
18784        // SAFETY: index checked above; the pointer is interior to `self`.
18785        unsafe {
18786            Some(crate::support::Ref::new(AnimationState {
18787                raw: core::ptr::NonNull::new_unchecked(
18788                    ffi::whiteout_m3_M3Model_get_animationStates_at(self.raw.as_ptr(), index),
18789                ),
18790            }))
18791        }
18792    }
18793
18794    pub fn animation_states_mut(
18795        &mut self,
18796        index: usize,
18797    ) -> Option<crate::support::RefMut<'_, AnimationState>> {
18798        if index >= self.animation_states_len() {
18799            return None;
18800        }
18801        // SAFETY: as above; `&mut self` guarantees exclusivity.
18802        unsafe {
18803            Some(crate::support::RefMut::new(AnimationState {
18804                raw: core::ptr::NonNull::new_unchecked(
18805                    ffi::whiteout_m3_M3Model_get_animationStates_at(self.raw.as_ptr(), index),
18806                ),
18807            }))
18808        }
18809    }
18810
18811    /// Iterate the elements, borrowing each in turn.
18812    pub fn animation_states_iter(
18813        &self,
18814    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, AnimationState>> {
18815        (0..self.animation_states_len())
18816            .map(move |i| self.animation_states(i).expect("index below len"))
18817    }
18818
18819    pub fn resize_animation_states(&mut self, count: usize) {
18820        // SAFETY: exclusive access, so no borrow is outstanding.
18821        unsafe { ffi::whiteout_m3_M3Model_resize_animationStates(self.raw.as_ptr(), count) }
18822    }
18823
18824    /// Skeleton bones (BONE)
18825    pub fn bones_len(&self) -> usize {
18826        // SAFETY: scalar read through a live handle.
18827        unsafe { ffi::whiteout_m3_M3Model_get_bones_count(self.raw.as_ptr()) }
18828    }
18829
18830    /// Borrows element `index` in place. `None` when out of range.
18831    pub fn bones(&self, index: usize) -> Option<crate::support::Ref<'_, Bone>> {
18832        if index >= self.bones_len() {
18833            return None;
18834        }
18835        // SAFETY: index checked above; the pointer is interior to `self`.
18836        unsafe {
18837            Some(crate::support::Ref::new(Bone {
18838                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Model_get_bones_at(
18839                    self.raw.as_ptr(),
18840                    index,
18841                )),
18842            }))
18843        }
18844    }
18845
18846    pub fn bones_mut(&mut self, index: usize) -> Option<crate::support::RefMut<'_, Bone>> {
18847        if index >= self.bones_len() {
18848            return None;
18849        }
18850        // SAFETY: as above; `&mut self` guarantees exclusivity.
18851        unsafe {
18852            Some(crate::support::RefMut::new(Bone {
18853                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Model_get_bones_at(
18854                    self.raw.as_ptr(),
18855                    index,
18856                )),
18857            }))
18858        }
18859    }
18860
18861    /// Iterate the elements, borrowing each in turn.
18862    pub fn bones_iter(&self) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, Bone>> {
18863        (0..self.bones_len()).map(move |i| self.bones(i).expect("index below len"))
18864    }
18865
18866    pub fn resize_bones(&mut self, count: usize) {
18867        // SAFETY: exclusive access, so no borrow is outstanding.
18868        unsafe { ffi::whiteout_m3_M3Model_resize_bones(self.raw.as_ptr(), count) }
18869    }
18870
18871    /// Number of bones affecting skin
18872    pub fn skin_bone_count(&self) -> u32 {
18873        // SAFETY: plain scalar read through a live handle.
18874        unsafe { ffi::whiteout_m3_M3Model_get_skinBoneCount(self.raw.as_ptr()) }
18875    }
18876
18877    pub fn set_skin_bone_count(&mut self, value: u32) {
18878        // SAFETY: plain scalar write through a live handle.
18879        unsafe { ffi::whiteout_m3_M3Model_set_skinBoneCount(self.raw.as_ptr(), value) }
18880    }
18881
18882    /// Mesh divisions (DIV_: faces, regions, batches)
18883    pub fn divisions_len(&self) -> usize {
18884        // SAFETY: scalar read through a live handle.
18885        unsafe { ffi::whiteout_m3_M3Model_get_divisions_count(self.raw.as_ptr()) }
18886    }
18887
18888    /// Borrows element `index` in place. `None` when out of range.
18889    pub fn divisions(&self, index: usize) -> Option<crate::support::Ref<'_, MeshDivision>> {
18890        if index >= self.divisions_len() {
18891            return None;
18892        }
18893        // SAFETY: index checked above; the pointer is interior to `self`.
18894        unsafe {
18895            Some(crate::support::Ref::new(MeshDivision {
18896                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Model_get_divisions_at(
18897                    self.raw.as_ptr(),
18898                    index,
18899                )),
18900            }))
18901        }
18902    }
18903
18904    pub fn divisions_mut(
18905        &mut self,
18906        index: usize,
18907    ) -> Option<crate::support::RefMut<'_, MeshDivision>> {
18908        if index >= self.divisions_len() {
18909            return None;
18910        }
18911        // SAFETY: as above; `&mut self` guarantees exclusivity.
18912        unsafe {
18913            Some(crate::support::RefMut::new(MeshDivision {
18914                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Model_get_divisions_at(
18915                    self.raw.as_ptr(),
18916                    index,
18917                )),
18918            }))
18919        }
18920    }
18921
18922    /// Iterate the elements, borrowing each in turn.
18923    pub fn divisions_iter(
18924        &self,
18925    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, MeshDivision>> {
18926        (0..self.divisions_len()).map(move |i| self.divisions(i).expect("index below len"))
18927    }
18928
18929    pub fn resize_divisions(&mut self, count: usize) {
18930        // SAFETY: exclusive access, so no borrow is outstanding.
18931        unsafe { ffi::whiteout_m3_M3Model_resize_divisions(self.raw.as_ptr(), count) }
18932    }
18933
18934    /// Bone index remap table (U16_)
18935    /// Zero-copy view of the underlying `std::vector`.
18936    pub fn bone_lookup(&self) -> &[u16] {
18937        // SAFETY: `_data`/`_count` describe one contiguous C++
18938        // allocation, borrowed for as long as `self` is.
18939        unsafe {
18940            let n = ffi::whiteout_m3_M3Model_get_boneLookup_count(self.raw.as_ptr());
18941            let p = ffi::whiteout_m3_M3Model_get_boneLookup_data(self.raw.as_ptr());
18942            if p.is_null() || n == 0 {
18943                &[]
18944            } else {
18945                core::slice::from_raw_parts(p, n)
18946            }
18947        }
18948    }
18949
18950    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
18951    pub fn bone_lookup_mut(&mut self) -> &mut [u16] {
18952        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
18953        unsafe {
18954            let n = ffi::whiteout_m3_M3Model_get_boneLookup_count(self.raw.as_ptr());
18955            let p = ffi::whiteout_m3_M3Model_get_boneLookup_data(self.raw.as_ptr()) as *mut u16;
18956            if p.is_null() || n == 0 {
18957                &mut []
18958            } else {
18959                core::slice::from_raw_parts_mut(p, n)
18960            }
18961        }
18962    }
18963
18964    pub fn set_bone_lookup(&mut self, values: &[u16]) {
18965        // SAFETY: the native side copies `values` before returning.
18966        unsafe {
18967            ffi::whiteout_m3_M3Model_assign_boneLookup(
18968                self.raw.as_ptr(),
18969                values.as_ptr() as *const _,
18970                values.len(),
18971            )
18972        }
18973    }
18974
18975    pub fn resize_bone_lookup(&mut self, count: usize) {
18976        // SAFETY: reallocation is safe here precisely because
18977        // `&mut self` means no slice borrow is outstanding.
18978        unsafe { ffi::whiteout_m3_M3Model_resize_boneLookup(self.raw.as_ptr(), count) }
18979    }
18980
18981    /// Model bounding volume
18982    /// Borrows the field in place — no copy, no allocation.
18983    pub fn bounds(&self) -> crate::support::Ref<'_, Extent> {
18984        // SAFETY: an interior pointer into `self`, valid for this
18985        // borrow and never freed by the `Ref`.
18986        unsafe {
18987            crate::support::Ref::new(Extent {
18988                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Model_get_bounds(
18989                    self.raw.as_ptr(),
18990                )),
18991            })
18992        }
18993    }
18994
18995    pub fn bounds_mut(&mut self) -> crate::support::RefMut<'_, Extent> {
18996        // SAFETY: as above; `&mut self` guarantees exclusivity.
18997        unsafe {
18998            crate::support::RefMut::new(Extent {
18999                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Model_get_bounds(
19000                    self.raw.as_ptr(),
19001                )),
19002            })
19003        }
19004    }
19005
19006    /// Collision bounding volume
19007    /// Borrows the field in place — no copy, no allocation.
19008    pub fn collision_bounds(&self) -> crate::support::Ref<'_, Extent> {
19009        // SAFETY: an interior pointer into `self`, valid for this
19010        // borrow and never freed by the `Ref`.
19011        unsafe {
19012            crate::support::Ref::new(Extent {
19013                raw: core::ptr::NonNull::new_unchecked(
19014                    ffi::whiteout_m3_M3Model_get_collisionBounds(self.raw.as_ptr()),
19015                ),
19016            })
19017        }
19018    }
19019
19020    pub fn collision_bounds_mut(&mut self) -> crate::support::RefMut<'_, Extent> {
19021        // SAFETY: as above; `&mut self` guarantees exclusivity.
19022        unsafe {
19023            crate::support::RefMut::new(Extent {
19024                raw: core::ptr::NonNull::new_unchecked(
19025                    ffi::whiteout_m3_M3Model_get_collisionBounds(self.raw.as_ptr()),
19026                ),
19027            })
19028        }
19029    }
19030
19031    /// Collision triangle indices (U16_)
19032    /// Zero-copy view of the underlying `std::vector`.
19033    pub fn collision_faces(&self) -> &[u16] {
19034        // SAFETY: `_data`/`_count` describe one contiguous C++
19035        // allocation, borrowed for as long as `self` is.
19036        unsafe {
19037            let n = ffi::whiteout_m3_M3Model_get_collisionFaces_count(self.raw.as_ptr());
19038            let p = ffi::whiteout_m3_M3Model_get_collisionFaces_data(self.raw.as_ptr());
19039            if p.is_null() || n == 0 {
19040                &[]
19041            } else {
19042                core::slice::from_raw_parts(p, n)
19043            }
19044        }
19045    }
19046
19047    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
19048    pub fn collision_faces_mut(&mut self) -> &mut [u16] {
19049        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
19050        unsafe {
19051            let n = ffi::whiteout_m3_M3Model_get_collisionFaces_count(self.raw.as_ptr());
19052            let p = ffi::whiteout_m3_M3Model_get_collisionFaces_data(self.raw.as_ptr()) as *mut u16;
19053            if p.is_null() || n == 0 {
19054                &mut []
19055            } else {
19056                core::slice::from_raw_parts_mut(p, n)
19057            }
19058        }
19059    }
19060
19061    pub fn set_collision_faces(&mut self, values: &[u16]) {
19062        // SAFETY: the native side copies `values` before returning.
19063        unsafe {
19064            ffi::whiteout_m3_M3Model_assign_collisionFaces(
19065                self.raw.as_ptr(),
19066                values.as_ptr() as *const _,
19067                values.len(),
19068            )
19069        }
19070    }
19071
19072    pub fn resize_collision_faces(&mut self, count: usize) {
19073        // SAFETY: reallocation is safe here precisely because
19074        // `&mut self` means no slice borrow is outstanding.
19075        unsafe { ffi::whiteout_m3_M3Model_resize_collisionFaces(self.raw.as_ptr(), count) }
19076    }
19077
19078    /// Collision vertex positions (VEC3)
19079    /// Zero-copy view of the underlying `std::vector`.
19080    pub fn collision_verts(&self) -> &[crate::math::Vector3f] {
19081        // SAFETY: `_data`/`_count` describe one contiguous C++
19082        // allocation, borrowed for as long as `self` is.
19083        unsafe {
19084            let n = ffi::whiteout_m3_M3Model_get_collisionVerts_count(self.raw.as_ptr());
19085            let p = ffi::whiteout_m3_M3Model_get_collisionVerts_data(self.raw.as_ptr())
19086                as *const crate::math::Vector3f;
19087            if p.is_null() || n == 0 {
19088                &[]
19089            } else {
19090                core::slice::from_raw_parts(p, n)
19091            }
19092        }
19093    }
19094
19095    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
19096    pub fn collision_verts_mut(&mut self) -> &mut [crate::math::Vector3f] {
19097        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
19098        unsafe {
19099            let n = ffi::whiteout_m3_M3Model_get_collisionVerts_count(self.raw.as_ptr());
19100            let p = ffi::whiteout_m3_M3Model_get_collisionVerts_data(self.raw.as_ptr())
19101                as *const crate::math::Vector3f as *mut crate::math::Vector3f;
19102            if p.is_null() || n == 0 {
19103                &mut []
19104            } else {
19105                core::slice::from_raw_parts_mut(p, n)
19106            }
19107        }
19108    }
19109
19110    pub fn set_collision_verts(&mut self, values: &[crate::math::Vector3f]) {
19111        // SAFETY: the native side copies `values` before returning.
19112        unsafe {
19113            ffi::whiteout_m3_M3Model_assign_collisionVerts(
19114                self.raw.as_ptr(),
19115                values.as_ptr() as *const _,
19116                values.len(),
19117            )
19118        }
19119    }
19120
19121    pub fn resize_collision_verts(&mut self, count: usize) {
19122        // SAFETY: reallocation is safe here precisely because
19123        // `&mut self` means no slice borrow is outstanding.
19124        unsafe { ffi::whiteout_m3_M3Model_resize_collisionVerts(self.raw.as_ptr(), count) }
19125    }
19126
19127    /// Collision face normals (VEC3)
19128    /// Zero-copy view of the underlying `std::vector`.
19129    pub fn collision_normals(&self) -> &[crate::math::Vector3f] {
19130        // SAFETY: `_data`/`_count` describe one contiguous C++
19131        // allocation, borrowed for as long as `self` is.
19132        unsafe {
19133            let n = ffi::whiteout_m3_M3Model_get_collisionNormals_count(self.raw.as_ptr());
19134            let p = ffi::whiteout_m3_M3Model_get_collisionNormals_data(self.raw.as_ptr())
19135                as *const crate::math::Vector3f;
19136            if p.is_null() || n == 0 {
19137                &[]
19138            } else {
19139                core::slice::from_raw_parts(p, n)
19140            }
19141        }
19142    }
19143
19144    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
19145    pub fn collision_normals_mut(&mut self) -> &mut [crate::math::Vector3f] {
19146        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
19147        unsafe {
19148            let n = ffi::whiteout_m3_M3Model_get_collisionNormals_count(self.raw.as_ptr());
19149            let p = ffi::whiteout_m3_M3Model_get_collisionNormals_data(self.raw.as_ptr())
19150                as *const crate::math::Vector3f as *mut crate::math::Vector3f;
19151            if p.is_null() || n == 0 {
19152                &mut []
19153            } else {
19154                core::slice::from_raw_parts_mut(p, n)
19155            }
19156        }
19157    }
19158
19159    pub fn set_collision_normals(&mut self, values: &[crate::math::Vector3f]) {
19160        // SAFETY: the native side copies `values` before returning.
19161        unsafe {
19162            ffi::whiteout_m3_M3Model_assign_collisionNormals(
19163                self.raw.as_ptr(),
19164                values.as_ptr() as *const _,
19165                values.len(),
19166            )
19167        }
19168    }
19169
19170    pub fn resize_collision_normals(&mut self, count: usize) {
19171        // SAFETY: reallocation is safe here precisely because
19172        // `&mut self` means no slice borrow is outstanding.
19173        unsafe { ffi::whiteout_m3_M3Model_resize_collisionNormals(self.raw.as_ptr(), count) }
19174    }
19175
19176    /// Named bone locations (ATT_)
19177    pub fn attachment_points_len(&self) -> usize {
19178        // SAFETY: scalar read through a live handle.
19179        unsafe { ffi::whiteout_m3_M3Model_get_attachmentPoints_count(self.raw.as_ptr()) }
19180    }
19181
19182    /// Borrows element `index` in place. `None` when out of range.
19183    pub fn attachment_points(
19184        &self,
19185        index: usize,
19186    ) -> Option<crate::support::Ref<'_, AttachmentPoint>> {
19187        if index >= self.attachment_points_len() {
19188            return None;
19189        }
19190        // SAFETY: index checked above; the pointer is interior to `self`.
19191        unsafe {
19192            Some(crate::support::Ref::new(AttachmentPoint {
19193                raw: core::ptr::NonNull::new_unchecked(
19194                    ffi::whiteout_m3_M3Model_get_attachmentPoints_at(self.raw.as_ptr(), index),
19195                ),
19196            }))
19197        }
19198    }
19199
19200    pub fn attachment_points_mut(
19201        &mut self,
19202        index: usize,
19203    ) -> Option<crate::support::RefMut<'_, AttachmentPoint>> {
19204        if index >= self.attachment_points_len() {
19205            return None;
19206        }
19207        // SAFETY: as above; `&mut self` guarantees exclusivity.
19208        unsafe {
19209            Some(crate::support::RefMut::new(AttachmentPoint {
19210                raw: core::ptr::NonNull::new_unchecked(
19211                    ffi::whiteout_m3_M3Model_get_attachmentPoints_at(self.raw.as_ptr(), index),
19212                ),
19213            }))
19214        }
19215    }
19216
19217    /// Iterate the elements, borrowing each in turn.
19218    pub fn attachment_points_iter(
19219        &self,
19220    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, AttachmentPoint>> {
19221        (0..self.attachment_points_len())
19222            .map(move |i| self.attachment_points(i).expect("index below len"))
19223    }
19224
19225    pub fn resize_attachment_points(&mut self, count: usize) {
19226        // SAFETY: exclusive access, so no borrow is outstanding.
19227        unsafe { ffi::whiteout_m3_M3Model_resize_attachmentPoints(self.raw.as_ptr(), count) }
19228    }
19229
19230    /// Attachment point addon indices (U16_)
19231    /// Zero-copy view of the underlying `std::vector`.
19232    pub fn attachment_point_addons(&self) -> &[u16] {
19233        // SAFETY: `_data`/`_count` describe one contiguous C++
19234        // allocation, borrowed for as long as `self` is.
19235        unsafe {
19236            let n = ffi::whiteout_m3_M3Model_get_attachmentPointAddons_count(self.raw.as_ptr());
19237            let p = ffi::whiteout_m3_M3Model_get_attachmentPointAddons_data(self.raw.as_ptr());
19238            if p.is_null() || n == 0 {
19239                &[]
19240            } else {
19241                core::slice::from_raw_parts(p, n)
19242            }
19243        }
19244    }
19245
19246    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
19247    pub fn attachment_point_addons_mut(&mut self) -> &mut [u16] {
19248        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
19249        unsafe {
19250            let n = ffi::whiteout_m3_M3Model_get_attachmentPointAddons_count(self.raw.as_ptr());
19251            let p = ffi::whiteout_m3_M3Model_get_attachmentPointAddons_data(self.raw.as_ptr())
19252                as *mut u16;
19253            if p.is_null() || n == 0 {
19254                &mut []
19255            } else {
19256                core::slice::from_raw_parts_mut(p, n)
19257            }
19258        }
19259    }
19260
19261    pub fn set_attachment_point_addons(&mut self, values: &[u16]) {
19262        // SAFETY: the native side copies `values` before returning.
19263        unsafe {
19264            ffi::whiteout_m3_M3Model_assign_attachmentPointAddons(
19265                self.raw.as_ptr(),
19266                values.as_ptr() as *const _,
19267                values.len(),
19268            )
19269        }
19270    }
19271
19272    pub fn resize_attachment_point_addons(&mut self, count: usize) {
19273        // SAFETY: reallocation is safe here precisely because
19274        // `&mut self` means no slice borrow is outstanding.
19275        unsafe { ffi::whiteout_m3_M3Model_resize_attachmentPointAddons(self.raw.as_ptr(), count) }
19276    }
19277
19278    /// Lights (LITE)
19279    pub fn lights_len(&self) -> usize {
19280        // SAFETY: scalar read through a live handle.
19281        unsafe { ffi::whiteout_m3_M3Model_get_lights_count(self.raw.as_ptr()) }
19282    }
19283
19284    /// Borrows element `index` in place. `None` when out of range.
19285    pub fn lights(&self, index: usize) -> Option<crate::support::Ref<'_, Light>> {
19286        if index >= self.lights_len() {
19287            return None;
19288        }
19289        // SAFETY: index checked above; the pointer is interior to `self`.
19290        unsafe {
19291            Some(crate::support::Ref::new(Light {
19292                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Model_get_lights_at(
19293                    self.raw.as_ptr(),
19294                    index,
19295                )),
19296            }))
19297        }
19298    }
19299
19300    pub fn lights_mut(&mut self, index: usize) -> Option<crate::support::RefMut<'_, Light>> {
19301        if index >= self.lights_len() {
19302            return None;
19303        }
19304        // SAFETY: as above; `&mut self` guarantees exclusivity.
19305        unsafe {
19306            Some(crate::support::RefMut::new(Light {
19307                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Model_get_lights_at(
19308                    self.raw.as_ptr(),
19309                    index,
19310                )),
19311            }))
19312        }
19313    }
19314
19315    /// Iterate the elements, borrowing each in turn.
19316    pub fn lights_iter(&self) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, Light>> {
19317        (0..self.lights_len()).map(move |i| self.lights(i).expect("index below len"))
19318    }
19319
19320    pub fn resize_lights(&mut self, count: usize) {
19321        // SAFETY: exclusive access, so no borrow is outstanding.
19322        unsafe { ffi::whiteout_m3_M3Model_resize_lights(self.raw.as_ptr(), count) }
19323    }
19324
19325    /// Shadow boxes (SHBX)
19326    pub fn shadow_boxes_len(&self) -> usize {
19327        // SAFETY: scalar read through a live handle.
19328        unsafe { ffi::whiteout_m3_M3Model_get_shadowBoxes_count(self.raw.as_ptr()) }
19329    }
19330
19331    /// Borrows element `index` in place. `None` when out of range.
19332    pub fn shadow_boxes(&self, index: usize) -> Option<crate::support::Ref<'_, ShadowBox>> {
19333        if index >= self.shadow_boxes_len() {
19334            return None;
19335        }
19336        // SAFETY: index checked above; the pointer is interior to `self`.
19337        unsafe {
19338            Some(crate::support::Ref::new(ShadowBox {
19339                raw: core::ptr::NonNull::new_unchecked(
19340                    ffi::whiteout_m3_M3Model_get_shadowBoxes_at(self.raw.as_ptr(), index),
19341                ),
19342            }))
19343        }
19344    }
19345
19346    pub fn shadow_boxes_mut(
19347        &mut self,
19348        index: usize,
19349    ) -> Option<crate::support::RefMut<'_, ShadowBox>> {
19350        if index >= self.shadow_boxes_len() {
19351            return None;
19352        }
19353        // SAFETY: as above; `&mut self` guarantees exclusivity.
19354        unsafe {
19355            Some(crate::support::RefMut::new(ShadowBox {
19356                raw: core::ptr::NonNull::new_unchecked(
19357                    ffi::whiteout_m3_M3Model_get_shadowBoxes_at(self.raw.as_ptr(), index),
19358                ),
19359            }))
19360        }
19361    }
19362
19363    /// Iterate the elements, borrowing each in turn.
19364    pub fn shadow_boxes_iter(
19365        &self,
19366    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, ShadowBox>> {
19367        (0..self.shadow_boxes_len()).map(move |i| self.shadow_boxes(i).expect("index below len"))
19368    }
19369
19370    pub fn resize_shadow_boxes(&mut self, count: usize) {
19371        // SAFETY: exclusive access, so no borrow is outstanding.
19372        unsafe { ffi::whiteout_m3_M3Model_resize_shadowBoxes(self.raw.as_ptr(), count) }
19373    }
19374
19375    /// Cameras (CAM_)
19376    pub fn cameras_len(&self) -> usize {
19377        // SAFETY: scalar read through a live handle.
19378        unsafe { ffi::whiteout_m3_M3Model_get_cameras_count(self.raw.as_ptr()) }
19379    }
19380
19381    /// Borrows element `index` in place. `None` when out of range.
19382    pub fn cameras(&self, index: usize) -> Option<crate::support::Ref<'_, Camera>> {
19383        if index >= self.cameras_len() {
19384            return None;
19385        }
19386        // SAFETY: index checked above; the pointer is interior to `self`.
19387        unsafe {
19388            Some(crate::support::Ref::new(Camera {
19389                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Model_get_cameras_at(
19390                    self.raw.as_ptr(),
19391                    index,
19392                )),
19393            }))
19394        }
19395    }
19396
19397    pub fn cameras_mut(&mut self, index: usize) -> Option<crate::support::RefMut<'_, Camera>> {
19398        if index >= self.cameras_len() {
19399            return None;
19400        }
19401        // SAFETY: as above; `&mut self` guarantees exclusivity.
19402        unsafe {
19403            Some(crate::support::RefMut::new(Camera {
19404                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Model_get_cameras_at(
19405                    self.raw.as_ptr(),
19406                    index,
19407                )),
19408            }))
19409        }
19410    }
19411
19412    /// Iterate the elements, borrowing each in turn.
19413    pub fn cameras_iter(&self) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, Camera>> {
19414        (0..self.cameras_len()).map(move |i| self.cameras(i).expect("index below len"))
19415    }
19416
19417    pub fn resize_cameras(&mut self, count: usize) {
19418        // SAFETY: exclusive access, so no borrow is outstanding.
19419        unsafe { ffi::whiteout_m3_M3Model_resize_cameras(self.raw.as_ptr(), count) }
19420    }
19421
19422    /// Camera addon indices (U16_)
19423    /// Zero-copy view of the underlying `std::vector`.
19424    pub fn cameras_addons(&self) -> &[u16] {
19425        // SAFETY: `_data`/`_count` describe one contiguous C++
19426        // allocation, borrowed for as long as `self` is.
19427        unsafe {
19428            let n = ffi::whiteout_m3_M3Model_get_camerasAddons_count(self.raw.as_ptr());
19429            let p = ffi::whiteout_m3_M3Model_get_camerasAddons_data(self.raw.as_ptr());
19430            if p.is_null() || n == 0 {
19431                &[]
19432            } else {
19433                core::slice::from_raw_parts(p, n)
19434            }
19435        }
19436    }
19437
19438    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
19439    pub fn cameras_addons_mut(&mut self) -> &mut [u16] {
19440        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
19441        unsafe {
19442            let n = ffi::whiteout_m3_M3Model_get_camerasAddons_count(self.raw.as_ptr());
19443            let p = ffi::whiteout_m3_M3Model_get_camerasAddons_data(self.raw.as_ptr()) as *mut u16;
19444            if p.is_null() || n == 0 {
19445                &mut []
19446            } else {
19447                core::slice::from_raw_parts_mut(p, n)
19448            }
19449        }
19450    }
19451
19452    pub fn set_cameras_addons(&mut self, values: &[u16]) {
19453        // SAFETY: the native side copies `values` before returning.
19454        unsafe {
19455            ffi::whiteout_m3_M3Model_assign_camerasAddons(
19456                self.raw.as_ptr(),
19457                values.as_ptr() as *const _,
19458                values.len(),
19459            )
19460        }
19461    }
19462
19463    pub fn resize_cameras_addons(&mut self, count: usize) {
19464        // SAFETY: reallocation is safe here precisely because
19465        // `&mut self` means no slice borrow is outstanding.
19466        unsafe { ffi::whiteout_m3_M3Model_resize_camerasAddons(self.raw.as_ptr(), count) }
19467    }
19468
19469    /// Material type+index maps (MATM)
19470    pub fn material_maps_len(&self) -> usize {
19471        // SAFETY: scalar read through a live handle.
19472        unsafe { ffi::whiteout_m3_M3Model_get_materialMaps_count(self.raw.as_ptr()) }
19473    }
19474
19475    /// Borrows element `index` in place. `None` when out of range.
19476    pub fn material_maps(&self, index: usize) -> Option<crate::support::Ref<'_, MaterialMap>> {
19477        if index >= self.material_maps_len() {
19478            return None;
19479        }
19480        // SAFETY: index checked above; the pointer is interior to `self`.
19481        unsafe {
19482            Some(crate::support::Ref::new(MaterialMap {
19483                raw: core::ptr::NonNull::new_unchecked(
19484                    ffi::whiteout_m3_M3Model_get_materialMaps_at(self.raw.as_ptr(), index),
19485                ),
19486            }))
19487        }
19488    }
19489
19490    pub fn material_maps_mut(
19491        &mut self,
19492        index: usize,
19493    ) -> Option<crate::support::RefMut<'_, MaterialMap>> {
19494        if index >= self.material_maps_len() {
19495            return None;
19496        }
19497        // SAFETY: as above; `&mut self` guarantees exclusivity.
19498        unsafe {
19499            Some(crate::support::RefMut::new(MaterialMap {
19500                raw: core::ptr::NonNull::new_unchecked(
19501                    ffi::whiteout_m3_M3Model_get_materialMaps_at(self.raw.as_ptr(), index),
19502                ),
19503            }))
19504        }
19505    }
19506
19507    /// Iterate the elements, borrowing each in turn.
19508    pub fn material_maps_iter(
19509        &self,
19510    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, MaterialMap>> {
19511        (0..self.material_maps_len()).map(move |i| self.material_maps(i).expect("index below len"))
19512    }
19513
19514    pub fn resize_material_maps(&mut self, count: usize) {
19515        // SAFETY: exclusive access, so no borrow is outstanding.
19516        unsafe { ffi::whiteout_m3_M3Model_resize_materialMaps(self.raw.as_ptr(), count) }
19517    }
19518
19519    /// Standard materials (MAT_)
19520    pub fn standard_materials_len(&self) -> usize {
19521        // SAFETY: scalar read through a live handle.
19522        unsafe { ffi::whiteout_m3_M3Model_get_standardMaterials_count(self.raw.as_ptr()) }
19523    }
19524
19525    /// Borrows element `index` in place. `None` when out of range.
19526    pub fn standard_materials(
19527        &self,
19528        index: usize,
19529    ) -> Option<crate::support::Ref<'_, StandardMaterial>> {
19530        if index >= self.standard_materials_len() {
19531            return None;
19532        }
19533        // SAFETY: index checked above; the pointer is interior to `self`.
19534        unsafe {
19535            Some(crate::support::Ref::new(StandardMaterial {
19536                raw: core::ptr::NonNull::new_unchecked(
19537                    ffi::whiteout_m3_M3Model_get_standardMaterials_at(self.raw.as_ptr(), index),
19538                ),
19539            }))
19540        }
19541    }
19542
19543    pub fn standard_materials_mut(
19544        &mut self,
19545        index: usize,
19546    ) -> Option<crate::support::RefMut<'_, StandardMaterial>> {
19547        if index >= self.standard_materials_len() {
19548            return None;
19549        }
19550        // SAFETY: as above; `&mut self` guarantees exclusivity.
19551        unsafe {
19552            Some(crate::support::RefMut::new(StandardMaterial {
19553                raw: core::ptr::NonNull::new_unchecked(
19554                    ffi::whiteout_m3_M3Model_get_standardMaterials_at(self.raw.as_ptr(), index),
19555                ),
19556            }))
19557        }
19558    }
19559
19560    /// Iterate the elements, borrowing each in turn.
19561    pub fn standard_materials_iter(
19562        &self,
19563    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, StandardMaterial>> {
19564        (0..self.standard_materials_len())
19565            .map(move |i| self.standard_materials(i).expect("index below len"))
19566    }
19567
19568    pub fn resize_standard_materials(&mut self, count: usize) {
19569        // SAFETY: exclusive access, so no borrow is outstanding.
19570        unsafe { ffi::whiteout_m3_M3Model_resize_standardMaterials(self.raw.as_ptr(), count) }
19571    }
19572
19573    /// Displacement materials (DIS_)
19574    pub fn displacement_materials_len(&self) -> usize {
19575        // SAFETY: scalar read through a live handle.
19576        unsafe { ffi::whiteout_m3_M3Model_get_displacementMaterials_count(self.raw.as_ptr()) }
19577    }
19578
19579    /// Borrows element `index` in place. `None` when out of range.
19580    pub fn displacement_materials(
19581        &self,
19582        index: usize,
19583    ) -> Option<crate::support::Ref<'_, DisplacementMaterial>> {
19584        if index >= self.displacement_materials_len() {
19585            return None;
19586        }
19587        // SAFETY: index checked above; the pointer is interior to `self`.
19588        unsafe {
19589            Some(crate::support::Ref::new(DisplacementMaterial {
19590                raw: core::ptr::NonNull::new_unchecked(
19591                    ffi::whiteout_m3_M3Model_get_displacementMaterials_at(self.raw.as_ptr(), index),
19592                ),
19593            }))
19594        }
19595    }
19596
19597    pub fn displacement_materials_mut(
19598        &mut self,
19599        index: usize,
19600    ) -> Option<crate::support::RefMut<'_, DisplacementMaterial>> {
19601        if index >= self.displacement_materials_len() {
19602            return None;
19603        }
19604        // SAFETY: as above; `&mut self` guarantees exclusivity.
19605        unsafe {
19606            Some(crate::support::RefMut::new(DisplacementMaterial {
19607                raw: core::ptr::NonNull::new_unchecked(
19608                    ffi::whiteout_m3_M3Model_get_displacementMaterials_at(self.raw.as_ptr(), index),
19609                ),
19610            }))
19611        }
19612    }
19613
19614    /// Iterate the elements, borrowing each in turn.
19615    pub fn displacement_materials_iter(
19616        &self,
19617    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, DisplacementMaterial>> {
19618        (0..self.displacement_materials_len())
19619            .map(move |i| self.displacement_materials(i).expect("index below len"))
19620    }
19621
19622    pub fn resize_displacement_materials(&mut self, count: usize) {
19623        // SAFETY: exclusive access, so no borrow is outstanding.
19624        unsafe { ffi::whiteout_m3_M3Model_resize_displacementMaterials(self.raw.as_ptr(), count) }
19625    }
19626
19627    /// Composite materials (CMP_)
19628    pub fn composite_materials_len(&self) -> usize {
19629        // SAFETY: scalar read through a live handle.
19630        unsafe { ffi::whiteout_m3_M3Model_get_compositeMaterials_count(self.raw.as_ptr()) }
19631    }
19632
19633    /// Borrows element `index` in place. `None` when out of range.
19634    pub fn composite_materials(
19635        &self,
19636        index: usize,
19637    ) -> Option<crate::support::Ref<'_, CompositeMaterial>> {
19638        if index >= self.composite_materials_len() {
19639            return None;
19640        }
19641        // SAFETY: index checked above; the pointer is interior to `self`.
19642        unsafe {
19643            Some(crate::support::Ref::new(CompositeMaterial {
19644                raw: core::ptr::NonNull::new_unchecked(
19645                    ffi::whiteout_m3_M3Model_get_compositeMaterials_at(self.raw.as_ptr(), index),
19646                ),
19647            }))
19648        }
19649    }
19650
19651    pub fn composite_materials_mut(
19652        &mut self,
19653        index: usize,
19654    ) -> Option<crate::support::RefMut<'_, CompositeMaterial>> {
19655        if index >= self.composite_materials_len() {
19656            return None;
19657        }
19658        // SAFETY: as above; `&mut self` guarantees exclusivity.
19659        unsafe {
19660            Some(crate::support::RefMut::new(CompositeMaterial {
19661                raw: core::ptr::NonNull::new_unchecked(
19662                    ffi::whiteout_m3_M3Model_get_compositeMaterials_at(self.raw.as_ptr(), index),
19663                ),
19664            }))
19665        }
19666    }
19667
19668    /// Iterate the elements, borrowing each in turn.
19669    pub fn composite_materials_iter(
19670        &self,
19671    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, CompositeMaterial>> {
19672        (0..self.composite_materials_len())
19673            .map(move |i| self.composite_materials(i).expect("index below len"))
19674    }
19675
19676    pub fn resize_composite_materials(&mut self, count: usize) {
19677        // SAFETY: exclusive access, so no borrow is outstanding.
19678        unsafe { ffi::whiteout_m3_M3Model_resize_compositeMaterials(self.raw.as_ptr(), count) }
19679    }
19680
19681    /// Terrain materials (TER_)
19682    pub fn terrain_materials_len(&self) -> usize {
19683        // SAFETY: scalar read through a live handle.
19684        unsafe { ffi::whiteout_m3_M3Model_get_terrainMaterials_count(self.raw.as_ptr()) }
19685    }
19686
19687    /// Borrows element `index` in place. `None` when out of range.
19688    pub fn terrain_materials(
19689        &self,
19690        index: usize,
19691    ) -> Option<crate::support::Ref<'_, TerrainMaterial>> {
19692        if index >= self.terrain_materials_len() {
19693            return None;
19694        }
19695        // SAFETY: index checked above; the pointer is interior to `self`.
19696        unsafe {
19697            Some(crate::support::Ref::new(TerrainMaterial {
19698                raw: core::ptr::NonNull::new_unchecked(
19699                    ffi::whiteout_m3_M3Model_get_terrainMaterials_at(self.raw.as_ptr(), index),
19700                ),
19701            }))
19702        }
19703    }
19704
19705    pub fn terrain_materials_mut(
19706        &mut self,
19707        index: usize,
19708    ) -> Option<crate::support::RefMut<'_, TerrainMaterial>> {
19709        if index >= self.terrain_materials_len() {
19710            return None;
19711        }
19712        // SAFETY: as above; `&mut self` guarantees exclusivity.
19713        unsafe {
19714            Some(crate::support::RefMut::new(TerrainMaterial {
19715                raw: core::ptr::NonNull::new_unchecked(
19716                    ffi::whiteout_m3_M3Model_get_terrainMaterials_at(self.raw.as_ptr(), index),
19717                ),
19718            }))
19719        }
19720    }
19721
19722    /// Iterate the elements, borrowing each in turn.
19723    pub fn terrain_materials_iter(
19724        &self,
19725    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, TerrainMaterial>> {
19726        (0..self.terrain_materials_len())
19727            .map(move |i| self.terrain_materials(i).expect("index below len"))
19728    }
19729
19730    pub fn resize_terrain_materials(&mut self, count: usize) {
19731        // SAFETY: exclusive access, so no borrow is outstanding.
19732        unsafe { ffi::whiteout_m3_M3Model_resize_terrainMaterials(self.raw.as_ptr(), count) }
19733    }
19734
19735    /// Volume materials (VOL_)
19736    pub fn volume_materials_len(&self) -> usize {
19737        // SAFETY: scalar read through a live handle.
19738        unsafe { ffi::whiteout_m3_M3Model_get_volumeMaterials_count(self.raw.as_ptr()) }
19739    }
19740
19741    /// Borrows element `index` in place. `None` when out of range.
19742    pub fn volume_materials(
19743        &self,
19744        index: usize,
19745    ) -> Option<crate::support::Ref<'_, VolumeMaterial>> {
19746        if index >= self.volume_materials_len() {
19747            return None;
19748        }
19749        // SAFETY: index checked above; the pointer is interior to `self`.
19750        unsafe {
19751            Some(crate::support::Ref::new(VolumeMaterial {
19752                raw: core::ptr::NonNull::new_unchecked(
19753                    ffi::whiteout_m3_M3Model_get_volumeMaterials_at(self.raw.as_ptr(), index),
19754                ),
19755            }))
19756        }
19757    }
19758
19759    pub fn volume_materials_mut(
19760        &mut self,
19761        index: usize,
19762    ) -> Option<crate::support::RefMut<'_, VolumeMaterial>> {
19763        if index >= self.volume_materials_len() {
19764            return None;
19765        }
19766        // SAFETY: as above; `&mut self` guarantees exclusivity.
19767        unsafe {
19768            Some(crate::support::RefMut::new(VolumeMaterial {
19769                raw: core::ptr::NonNull::new_unchecked(
19770                    ffi::whiteout_m3_M3Model_get_volumeMaterials_at(self.raw.as_ptr(), index),
19771                ),
19772            }))
19773        }
19774    }
19775
19776    /// Iterate the elements, borrowing each in turn.
19777    pub fn volume_materials_iter(
19778        &self,
19779    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, VolumeMaterial>> {
19780        (0..self.volume_materials_len())
19781            .map(move |i| self.volume_materials(i).expect("index below len"))
19782    }
19783
19784    pub fn resize_volume_materials(&mut self, count: usize) {
19785        // SAFETY: exclusive access, so no borrow is outstanding.
19786        unsafe { ffi::whiteout_m3_M3Model_resize_volumeMaterials(self.raw.as_ptr(), count) }
19787    }
19788
19789    /// Hair materials (HAI_, defunct — always null)
19790    pub fn hair_materials_len(&self) -> usize {
19791        // SAFETY: scalar read through a live handle.
19792        unsafe { ffi::whiteout_m3_M3Model_get_hairMaterials_count(self.raw.as_ptr()) }
19793    }
19794
19795    /// Borrows element `index` in place. `None` when out of range.
19796    pub fn hair_materials(&self, index: usize) -> Option<crate::support::Ref<'_, HairMaterial>> {
19797        if index >= self.hair_materials_len() {
19798            return None;
19799        }
19800        // SAFETY: index checked above; the pointer is interior to `self`.
19801        unsafe {
19802            Some(crate::support::Ref::new(HairMaterial {
19803                raw: core::ptr::NonNull::new_unchecked(
19804                    ffi::whiteout_m3_M3Model_get_hairMaterials_at(self.raw.as_ptr(), index),
19805                ),
19806            }))
19807        }
19808    }
19809
19810    pub fn hair_materials_mut(
19811        &mut self,
19812        index: usize,
19813    ) -> Option<crate::support::RefMut<'_, HairMaterial>> {
19814        if index >= self.hair_materials_len() {
19815            return None;
19816        }
19817        // SAFETY: as above; `&mut self` guarantees exclusivity.
19818        unsafe {
19819            Some(crate::support::RefMut::new(HairMaterial {
19820                raw: core::ptr::NonNull::new_unchecked(
19821                    ffi::whiteout_m3_M3Model_get_hairMaterials_at(self.raw.as_ptr(), index),
19822                ),
19823            }))
19824        }
19825    }
19826
19827    /// Iterate the elements, borrowing each in turn.
19828    pub fn hair_materials_iter(
19829        &self,
19830    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, HairMaterial>> {
19831        (0..self.hair_materials_len())
19832            .map(move |i| self.hair_materials(i).expect("index below len"))
19833    }
19834
19835    pub fn resize_hair_materials(&mut self, count: usize) {
19836        // SAFETY: exclusive access, so no borrow is outstanding.
19837        unsafe { ffi::whiteout_m3_M3Model_resize_hairMaterials(self.raw.as_ptr(), count) }
19838    }
19839
19840    /// Creep materials (CREP)
19841    pub fn creep_materials_len(&self) -> usize {
19842        // SAFETY: scalar read through a live handle.
19843        unsafe { ffi::whiteout_m3_M3Model_get_creepMaterials_count(self.raw.as_ptr()) }
19844    }
19845
19846    /// Borrows element `index` in place. `None` when out of range.
19847    pub fn creep_materials(&self, index: usize) -> Option<crate::support::Ref<'_, CreepMaterial>> {
19848        if index >= self.creep_materials_len() {
19849            return None;
19850        }
19851        // SAFETY: index checked above; the pointer is interior to `self`.
19852        unsafe {
19853            Some(crate::support::Ref::new(CreepMaterial {
19854                raw: core::ptr::NonNull::new_unchecked(
19855                    ffi::whiteout_m3_M3Model_get_creepMaterials_at(self.raw.as_ptr(), index),
19856                ),
19857            }))
19858        }
19859    }
19860
19861    pub fn creep_materials_mut(
19862        &mut self,
19863        index: usize,
19864    ) -> Option<crate::support::RefMut<'_, CreepMaterial>> {
19865        if index >= self.creep_materials_len() {
19866            return None;
19867        }
19868        // SAFETY: as above; `&mut self` guarantees exclusivity.
19869        unsafe {
19870            Some(crate::support::RefMut::new(CreepMaterial {
19871                raw: core::ptr::NonNull::new_unchecked(
19872                    ffi::whiteout_m3_M3Model_get_creepMaterials_at(self.raw.as_ptr(), index),
19873                ),
19874            }))
19875        }
19876    }
19877
19878    /// Iterate the elements, borrowing each in turn.
19879    pub fn creep_materials_iter(
19880        &self,
19881    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, CreepMaterial>> {
19882        (0..self.creep_materials_len())
19883            .map(move |i| self.creep_materials(i).expect("index below len"))
19884    }
19885
19886    pub fn resize_creep_materials(&mut self, count: usize) {
19887        // SAFETY: exclusive access, so no borrow is outstanding.
19888        unsafe { ffi::whiteout_m3_M3Model_resize_creepMaterials(self.raw.as_ptr(), count) }
19889    }
19890
19891    /// Volume noise materials (VON_, v25+)
19892    pub fn volume_noise_materials_len(&self) -> usize {
19893        // SAFETY: scalar read through a live handle.
19894        unsafe { ffi::whiteout_m3_M3Model_get_volumeNoiseMaterials_count(self.raw.as_ptr()) }
19895    }
19896
19897    /// Borrows element `index` in place. `None` when out of range.
19898    pub fn volume_noise_materials(
19899        &self,
19900        index: usize,
19901    ) -> Option<crate::support::Ref<'_, VolumeNoiseMaterial>> {
19902        if index >= self.volume_noise_materials_len() {
19903            return None;
19904        }
19905        // SAFETY: index checked above; the pointer is interior to `self`.
19906        unsafe {
19907            Some(crate::support::Ref::new(VolumeNoiseMaterial {
19908                raw: core::ptr::NonNull::new_unchecked(
19909                    ffi::whiteout_m3_M3Model_get_volumeNoiseMaterials_at(self.raw.as_ptr(), index),
19910                ),
19911            }))
19912        }
19913    }
19914
19915    pub fn volume_noise_materials_mut(
19916        &mut self,
19917        index: usize,
19918    ) -> Option<crate::support::RefMut<'_, VolumeNoiseMaterial>> {
19919        if index >= self.volume_noise_materials_len() {
19920            return None;
19921        }
19922        // SAFETY: as above; `&mut self` guarantees exclusivity.
19923        unsafe {
19924            Some(crate::support::RefMut::new(VolumeNoiseMaterial {
19925                raw: core::ptr::NonNull::new_unchecked(
19926                    ffi::whiteout_m3_M3Model_get_volumeNoiseMaterials_at(self.raw.as_ptr(), index),
19927                ),
19928            }))
19929        }
19930    }
19931
19932    /// Iterate the elements, borrowing each in turn.
19933    pub fn volume_noise_materials_iter(
19934        &self,
19935    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, VolumeNoiseMaterial>> {
19936        (0..self.volume_noise_materials_len())
19937            .map(move |i| self.volume_noise_materials(i).expect("index below len"))
19938    }
19939
19940    pub fn resize_volume_noise_materials(&mut self, count: usize) {
19941        // SAFETY: exclusive access, so no borrow is outstanding.
19942        unsafe { ffi::whiteout_m3_M3Model_resize_volumeNoiseMaterials(self.raw.as_ptr(), count) }
19943    }
19944
19945    /// Splat terrain bake materials (STBM, v26+)
19946    pub fn stb_materials_len(&self) -> usize {
19947        // SAFETY: scalar read through a live handle.
19948        unsafe { ffi::whiteout_m3_M3Model_get_stbMaterials_count(self.raw.as_ptr()) }
19949    }
19950
19951    /// Borrows element `index` in place. `None` when out of range.
19952    pub fn stb_materials(&self, index: usize) -> Option<crate::support::Ref<'_, STBMaterial>> {
19953        if index >= self.stb_materials_len() {
19954            return None;
19955        }
19956        // SAFETY: index checked above; the pointer is interior to `self`.
19957        unsafe {
19958            Some(crate::support::Ref::new(STBMaterial {
19959                raw: core::ptr::NonNull::new_unchecked(
19960                    ffi::whiteout_m3_M3Model_get_stbMaterials_at(self.raw.as_ptr(), index),
19961                ),
19962            }))
19963        }
19964    }
19965
19966    pub fn stb_materials_mut(
19967        &mut self,
19968        index: usize,
19969    ) -> Option<crate::support::RefMut<'_, STBMaterial>> {
19970        if index >= self.stb_materials_len() {
19971            return None;
19972        }
19973        // SAFETY: as above; `&mut self` guarantees exclusivity.
19974        unsafe {
19975            Some(crate::support::RefMut::new(STBMaterial {
19976                raw: core::ptr::NonNull::new_unchecked(
19977                    ffi::whiteout_m3_M3Model_get_stbMaterials_at(self.raw.as_ptr(), index),
19978                ),
19979            }))
19980        }
19981    }
19982
19983    /// Iterate the elements, borrowing each in turn.
19984    pub fn stb_materials_iter(
19985        &self,
19986    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, STBMaterial>> {
19987        (0..self.stb_materials_len()).map(move |i| self.stb_materials(i).expect("index below len"))
19988    }
19989
19990    pub fn resize_stb_materials(&mut self, count: usize) {
19991        // SAFETY: exclusive access, so no borrow is outstanding.
19992        unsafe { ffi::whiteout_m3_M3Model_resize_stbMaterials(self.raw.as_ptr(), count) }
19993    }
19994
19995    /// Reflection materials (REF_, v28+)
19996    pub fn reflection_materials_len(&self) -> usize {
19997        // SAFETY: scalar read through a live handle.
19998        unsafe { ffi::whiteout_m3_M3Model_get_reflectionMaterials_count(self.raw.as_ptr()) }
19999    }
20000
20001    /// Borrows element `index` in place. `None` when out of range.
20002    pub fn reflection_materials(
20003        &self,
20004        index: usize,
20005    ) -> Option<crate::support::Ref<'_, ReflectionMaterial>> {
20006        if index >= self.reflection_materials_len() {
20007            return None;
20008        }
20009        // SAFETY: index checked above; the pointer is interior to `self`.
20010        unsafe {
20011            Some(crate::support::Ref::new(ReflectionMaterial {
20012                raw: core::ptr::NonNull::new_unchecked(
20013                    ffi::whiteout_m3_M3Model_get_reflectionMaterials_at(self.raw.as_ptr(), index),
20014                ),
20015            }))
20016        }
20017    }
20018
20019    pub fn reflection_materials_mut(
20020        &mut self,
20021        index: usize,
20022    ) -> Option<crate::support::RefMut<'_, ReflectionMaterial>> {
20023        if index >= self.reflection_materials_len() {
20024            return None;
20025        }
20026        // SAFETY: as above; `&mut self` guarantees exclusivity.
20027        unsafe {
20028            Some(crate::support::RefMut::new(ReflectionMaterial {
20029                raw: core::ptr::NonNull::new_unchecked(
20030                    ffi::whiteout_m3_M3Model_get_reflectionMaterials_at(self.raw.as_ptr(), index),
20031                ),
20032            }))
20033        }
20034    }
20035
20036    /// Iterate the elements, borrowing each in turn.
20037    pub fn reflection_materials_iter(
20038        &self,
20039    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, ReflectionMaterial>> {
20040        (0..self.reflection_materials_len())
20041            .map(move |i| self.reflection_materials(i).expect("index below len"))
20042    }
20043
20044    pub fn resize_reflection_materials(&mut self, count: usize) {
20045        // SAFETY: exclusive access, so no borrow is outstanding.
20046        unsafe { ffi::whiteout_m3_M3Model_resize_reflectionMaterials(self.raw.as_ptr(), count) }
20047    }
20048
20049    /// Lens flare materials (LFLR, v29+)
20050    pub fn lens_flare_materials_len(&self) -> usize {
20051        // SAFETY: scalar read through a live handle.
20052        unsafe { ffi::whiteout_m3_M3Model_get_lensFlareMaterials_count(self.raw.as_ptr()) }
20053    }
20054
20055    /// Borrows element `index` in place. `None` when out of range.
20056    pub fn lens_flare_materials(&self, index: usize) -> Option<crate::support::Ref<'_, LensFlare>> {
20057        if index >= self.lens_flare_materials_len() {
20058            return None;
20059        }
20060        // SAFETY: index checked above; the pointer is interior to `self`.
20061        unsafe {
20062            Some(crate::support::Ref::new(LensFlare {
20063                raw: core::ptr::NonNull::new_unchecked(
20064                    ffi::whiteout_m3_M3Model_get_lensFlareMaterials_at(self.raw.as_ptr(), index),
20065                ),
20066            }))
20067        }
20068    }
20069
20070    pub fn lens_flare_materials_mut(
20071        &mut self,
20072        index: usize,
20073    ) -> Option<crate::support::RefMut<'_, LensFlare>> {
20074        if index >= self.lens_flare_materials_len() {
20075            return None;
20076        }
20077        // SAFETY: as above; `&mut self` guarantees exclusivity.
20078        unsafe {
20079            Some(crate::support::RefMut::new(LensFlare {
20080                raw: core::ptr::NonNull::new_unchecked(
20081                    ffi::whiteout_m3_M3Model_get_lensFlareMaterials_at(self.raw.as_ptr(), index),
20082                ),
20083            }))
20084        }
20085    }
20086
20087    /// Iterate the elements, borrowing each in turn.
20088    pub fn lens_flare_materials_iter(
20089        &self,
20090    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, LensFlare>> {
20091        (0..self.lens_flare_materials_len())
20092            .map(move |i| self.lens_flare_materials(i).expect("index below len"))
20093    }
20094
20095    pub fn resize_lens_flare_materials(&mut self, count: usize) {
20096        // SAFETY: exclusive access, so no borrow is outstanding.
20097        unsafe { ffi::whiteout_m3_M3Model_resize_lensFlareMaterials(self.raw.as_ptr(), count) }
20098    }
20099
20100    /// Buffer material data (MADD, v30+)
20101    pub fn material_add_data_len(&self) -> usize {
20102        // SAFETY: scalar read through a live handle.
20103        unsafe { ffi::whiteout_m3_M3Model_get_materialAddData_count(self.raw.as_ptr()) }
20104    }
20105
20106    /// Borrows element `index` in place. `None` when out of range.
20107    pub fn material_add_data(
20108        &self,
20109        index: usize,
20110    ) -> Option<crate::support::Ref<'_, MaterialAddData>> {
20111        if index >= self.material_add_data_len() {
20112            return None;
20113        }
20114        // SAFETY: index checked above; the pointer is interior to `self`.
20115        unsafe {
20116            Some(crate::support::Ref::new(MaterialAddData {
20117                raw: core::ptr::NonNull::new_unchecked(
20118                    ffi::whiteout_m3_M3Model_get_materialAddData_at(self.raw.as_ptr(), index),
20119                ),
20120            }))
20121        }
20122    }
20123
20124    pub fn material_add_data_mut(
20125        &mut self,
20126        index: usize,
20127    ) -> Option<crate::support::RefMut<'_, MaterialAddData>> {
20128        if index >= self.material_add_data_len() {
20129            return None;
20130        }
20131        // SAFETY: as above; `&mut self` guarantees exclusivity.
20132        unsafe {
20133            Some(crate::support::RefMut::new(MaterialAddData {
20134                raw: core::ptr::NonNull::new_unchecked(
20135                    ffi::whiteout_m3_M3Model_get_materialAddData_at(self.raw.as_ptr(), index),
20136                ),
20137            }))
20138        }
20139    }
20140
20141    /// Iterate the elements, borrowing each in turn.
20142    pub fn material_add_data_iter(
20143        &self,
20144    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, MaterialAddData>> {
20145        (0..self.material_add_data_len())
20146            .map(move |i| self.material_add_data(i).expect("index below len"))
20147    }
20148
20149    pub fn resize_material_add_data(&mut self, count: usize) {
20150        // SAFETY: exclusive access, so no borrow is outstanding.
20151        unsafe { ffi::whiteout_m3_M3Model_resize_materialAddData(self.raw.as_ptr(), count) }
20152    }
20153
20154    /// Particle emitters (PAR_)
20155    pub fn particle_emitters_len(&self) -> usize {
20156        // SAFETY: scalar read through a live handle.
20157        unsafe { ffi::whiteout_m3_M3Model_get_particleEmitters_count(self.raw.as_ptr()) }
20158    }
20159
20160    /// Borrows element `index` in place. `None` when out of range.
20161    pub fn particle_emitters(
20162        &self,
20163        index: usize,
20164    ) -> Option<crate::support::Ref<'_, ParticleEmitter>> {
20165        if index >= self.particle_emitters_len() {
20166            return None;
20167        }
20168        // SAFETY: index checked above; the pointer is interior to `self`.
20169        unsafe {
20170            Some(crate::support::Ref::new(ParticleEmitter {
20171                raw: core::ptr::NonNull::new_unchecked(
20172                    ffi::whiteout_m3_M3Model_get_particleEmitters_at(self.raw.as_ptr(), index),
20173                ),
20174            }))
20175        }
20176    }
20177
20178    pub fn particle_emitters_mut(
20179        &mut self,
20180        index: usize,
20181    ) -> Option<crate::support::RefMut<'_, ParticleEmitter>> {
20182        if index >= self.particle_emitters_len() {
20183            return None;
20184        }
20185        // SAFETY: as above; `&mut self` guarantees exclusivity.
20186        unsafe {
20187            Some(crate::support::RefMut::new(ParticleEmitter {
20188                raw: core::ptr::NonNull::new_unchecked(
20189                    ffi::whiteout_m3_M3Model_get_particleEmitters_at(self.raw.as_ptr(), index),
20190                ),
20191            }))
20192        }
20193    }
20194
20195    /// Iterate the elements, borrowing each in turn.
20196    pub fn particle_emitters_iter(
20197        &self,
20198    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, ParticleEmitter>> {
20199        (0..self.particle_emitters_len())
20200            .map(move |i| self.particle_emitters(i).expect("index below len"))
20201    }
20202
20203    pub fn resize_particle_emitters(&mut self, count: usize) {
20204        // SAFETY: exclusive access, so no borrow is outstanding.
20205        unsafe { ffi::whiteout_m3_M3Model_resize_particleEmitters(self.raw.as_ptr(), count) }
20206    }
20207
20208    /// Particle emitter copies (PARC)
20209    pub fn particle_emitter_copies_len(&self) -> usize {
20210        // SAFETY: scalar read through a live handle.
20211        unsafe { ffi::whiteout_m3_M3Model_get_particleEmitterCopies_count(self.raw.as_ptr()) }
20212    }
20213
20214    /// Borrows element `index` in place. `None` when out of range.
20215    pub fn particle_emitter_copies(
20216        &self,
20217        index: usize,
20218    ) -> Option<crate::support::Ref<'_, ParticleEmitterCopy>> {
20219        if index >= self.particle_emitter_copies_len() {
20220            return None;
20221        }
20222        // SAFETY: index checked above; the pointer is interior to `self`.
20223        unsafe {
20224            Some(crate::support::Ref::new(ParticleEmitterCopy {
20225                raw: core::ptr::NonNull::new_unchecked(
20226                    ffi::whiteout_m3_M3Model_get_particleEmitterCopies_at(self.raw.as_ptr(), index),
20227                ),
20228            }))
20229        }
20230    }
20231
20232    pub fn particle_emitter_copies_mut(
20233        &mut self,
20234        index: usize,
20235    ) -> Option<crate::support::RefMut<'_, ParticleEmitterCopy>> {
20236        if index >= self.particle_emitter_copies_len() {
20237            return None;
20238        }
20239        // SAFETY: as above; `&mut self` guarantees exclusivity.
20240        unsafe {
20241            Some(crate::support::RefMut::new(ParticleEmitterCopy {
20242                raw: core::ptr::NonNull::new_unchecked(
20243                    ffi::whiteout_m3_M3Model_get_particleEmitterCopies_at(self.raw.as_ptr(), index),
20244                ),
20245            }))
20246        }
20247    }
20248
20249    /// Iterate the elements, borrowing each in turn.
20250    pub fn particle_emitter_copies_iter(
20251        &self,
20252    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, ParticleEmitterCopy>> {
20253        (0..self.particle_emitter_copies_len())
20254            .map(move |i| self.particle_emitter_copies(i).expect("index below len"))
20255    }
20256
20257    pub fn resize_particle_emitter_copies(&mut self, count: usize) {
20258        // SAFETY: exclusive access, so no borrow is outstanding.
20259        unsafe { ffi::whiteout_m3_M3Model_resize_particleEmitterCopies(self.raw.as_ptr(), count) }
20260    }
20261
20262    /// Ribbon emitters (RIB_)
20263    pub fn ribbon_emitters_len(&self) -> usize {
20264        // SAFETY: scalar read through a live handle.
20265        unsafe { ffi::whiteout_m3_M3Model_get_ribbonEmitters_count(self.raw.as_ptr()) }
20266    }
20267
20268    /// Borrows element `index` in place. `None` when out of range.
20269    pub fn ribbon_emitters(&self, index: usize) -> Option<crate::support::Ref<'_, RibbonEmitter>> {
20270        if index >= self.ribbon_emitters_len() {
20271            return None;
20272        }
20273        // SAFETY: index checked above; the pointer is interior to `self`.
20274        unsafe {
20275            Some(crate::support::Ref::new(RibbonEmitter {
20276                raw: core::ptr::NonNull::new_unchecked(
20277                    ffi::whiteout_m3_M3Model_get_ribbonEmitters_at(self.raw.as_ptr(), index),
20278                ),
20279            }))
20280        }
20281    }
20282
20283    pub fn ribbon_emitters_mut(
20284        &mut self,
20285        index: usize,
20286    ) -> Option<crate::support::RefMut<'_, RibbonEmitter>> {
20287        if index >= self.ribbon_emitters_len() {
20288            return None;
20289        }
20290        // SAFETY: as above; `&mut self` guarantees exclusivity.
20291        unsafe {
20292            Some(crate::support::RefMut::new(RibbonEmitter {
20293                raw: core::ptr::NonNull::new_unchecked(
20294                    ffi::whiteout_m3_M3Model_get_ribbonEmitters_at(self.raw.as_ptr(), index),
20295                ),
20296            }))
20297        }
20298    }
20299
20300    /// Iterate the elements, borrowing each in turn.
20301    pub fn ribbon_emitters_iter(
20302        &self,
20303    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, RibbonEmitter>> {
20304        (0..self.ribbon_emitters_len())
20305            .map(move |i| self.ribbon_emitters(i).expect("index below len"))
20306    }
20307
20308    pub fn resize_ribbon_emitters(&mut self, count: usize) {
20309        // SAFETY: exclusive access, so no borrow is outstanding.
20310        unsafe { ffi::whiteout_m3_M3Model_resize_ribbonEmitters(self.raw.as_ptr(), count) }
20311    }
20312
20313    /// Projectors / decals (PROJ)
20314    pub fn projections_len(&self) -> usize {
20315        // SAFETY: scalar read through a live handle.
20316        unsafe { ffi::whiteout_m3_M3Model_get_projections_count(self.raw.as_ptr()) }
20317    }
20318
20319    /// Borrows element `index` in place. `None` when out of range.
20320    pub fn projections(&self, index: usize) -> Option<crate::support::Ref<'_, Projector>> {
20321        if index >= self.projections_len() {
20322            return None;
20323        }
20324        // SAFETY: index checked above; the pointer is interior to `self`.
20325        unsafe {
20326            Some(crate::support::Ref::new(Projector {
20327                raw: core::ptr::NonNull::new_unchecked(
20328                    ffi::whiteout_m3_M3Model_get_projections_at(self.raw.as_ptr(), index),
20329                ),
20330            }))
20331        }
20332    }
20333
20334    pub fn projections_mut(
20335        &mut self,
20336        index: usize,
20337    ) -> Option<crate::support::RefMut<'_, Projector>> {
20338        if index >= self.projections_len() {
20339            return None;
20340        }
20341        // SAFETY: as above; `&mut self` guarantees exclusivity.
20342        unsafe {
20343            Some(crate::support::RefMut::new(Projector {
20344                raw: core::ptr::NonNull::new_unchecked(
20345                    ffi::whiteout_m3_M3Model_get_projections_at(self.raw.as_ptr(), index),
20346                ),
20347            }))
20348        }
20349    }
20350
20351    /// Iterate the elements, borrowing each in turn.
20352    pub fn projections_iter(
20353        &self,
20354    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, Projector>> {
20355        (0..self.projections_len()).map(move |i| self.projections(i).expect("index below len"))
20356    }
20357
20358    pub fn resize_projections(&mut self, count: usize) {
20359        // SAFETY: exclusive access, so no borrow is outstanding.
20360        unsafe { ffi::whiteout_m3_M3Model_resize_projections(self.raw.as_ptr(), count) }
20361    }
20362
20363    /// Forces (FOR_)
20364    pub fn forces_len(&self) -> usize {
20365        // SAFETY: scalar read through a live handle.
20366        unsafe { ffi::whiteout_m3_M3Model_get_forces_count(self.raw.as_ptr()) }
20367    }
20368
20369    /// Borrows element `index` in place. `None` when out of range.
20370    pub fn forces(&self, index: usize) -> Option<crate::support::Ref<'_, Force>> {
20371        if index >= self.forces_len() {
20372            return None;
20373        }
20374        // SAFETY: index checked above; the pointer is interior to `self`.
20375        unsafe {
20376            Some(crate::support::Ref::new(Force {
20377                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Model_get_forces_at(
20378                    self.raw.as_ptr(),
20379                    index,
20380                )),
20381            }))
20382        }
20383    }
20384
20385    pub fn forces_mut(&mut self, index: usize) -> Option<crate::support::RefMut<'_, Force>> {
20386        if index >= self.forces_len() {
20387            return None;
20388        }
20389        // SAFETY: as above; `&mut self` guarantees exclusivity.
20390        unsafe {
20391            Some(crate::support::RefMut::new(Force {
20392                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Model_get_forces_at(
20393                    self.raw.as_ptr(),
20394                    index,
20395                )),
20396            }))
20397        }
20398    }
20399
20400    /// Iterate the elements, borrowing each in turn.
20401    pub fn forces_iter(&self) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, Force>> {
20402        (0..self.forces_len()).map(move |i| self.forces(i).expect("index below len"))
20403    }
20404
20405    pub fn resize_forces(&mut self, count: usize) {
20406        // SAFETY: exclusive access, so no borrow is outstanding.
20407        unsafe { ffi::whiteout_m3_M3Model_resize_forces(self.raw.as_ptr(), count) }
20408    }
20409
20410    /// Warps (WRP_)
20411    pub fn warps_len(&self) -> usize {
20412        // SAFETY: scalar read through a live handle.
20413        unsafe { ffi::whiteout_m3_M3Model_get_warps_count(self.raw.as_ptr()) }
20414    }
20415
20416    /// Borrows element `index` in place. `None` when out of range.
20417    pub fn warps(&self, index: usize) -> Option<crate::support::Ref<'_, Warp>> {
20418        if index >= self.warps_len() {
20419            return None;
20420        }
20421        // SAFETY: index checked above; the pointer is interior to `self`.
20422        unsafe {
20423            Some(crate::support::Ref::new(Warp {
20424                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Model_get_warps_at(
20425                    self.raw.as_ptr(),
20426                    index,
20427                )),
20428            }))
20429        }
20430    }
20431
20432    pub fn warps_mut(&mut self, index: usize) -> Option<crate::support::RefMut<'_, Warp>> {
20433        if index >= self.warps_len() {
20434            return None;
20435        }
20436        // SAFETY: as above; `&mut self` guarantees exclusivity.
20437        unsafe {
20438            Some(crate::support::RefMut::new(Warp {
20439                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Model_get_warps_at(
20440                    self.raw.as_ptr(),
20441                    index,
20442                )),
20443            }))
20444        }
20445    }
20446
20447    /// Iterate the elements, borrowing each in turn.
20448    pub fn warps_iter(&self) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, Warp>> {
20449        (0..self.warps_len()).map(move |i| self.warps(i).expect("index below len"))
20450    }
20451
20452    pub fn resize_warps(&mut self, count: usize) {
20453        // SAFETY: exclusive access, so no borrow is outstanding.
20454        unsafe { ffi::whiteout_m3_M3Model_resize_warps(self.raw.as_ptr(), count) }
20455    }
20456
20457    /// View volumes (VVOL)
20458    pub fn view_volumes_len(&self) -> usize {
20459        // SAFETY: scalar read through a live handle.
20460        unsafe { ffi::whiteout_m3_M3Model_get_viewVolumes_count(self.raw.as_ptr()) }
20461    }
20462
20463    /// Borrows element `index` in place. `None` when out of range.
20464    pub fn view_volumes(&self, index: usize) -> Option<crate::support::Ref<'_, ViewVolume>> {
20465        if index >= self.view_volumes_len() {
20466            return None;
20467        }
20468        // SAFETY: index checked above; the pointer is interior to `self`.
20469        unsafe {
20470            Some(crate::support::Ref::new(ViewVolume {
20471                raw: core::ptr::NonNull::new_unchecked(
20472                    ffi::whiteout_m3_M3Model_get_viewVolumes_at(self.raw.as_ptr(), index),
20473                ),
20474            }))
20475        }
20476    }
20477
20478    pub fn view_volumes_mut(
20479        &mut self,
20480        index: usize,
20481    ) -> Option<crate::support::RefMut<'_, ViewVolume>> {
20482        if index >= self.view_volumes_len() {
20483            return None;
20484        }
20485        // SAFETY: as above; `&mut self` guarantees exclusivity.
20486        unsafe {
20487            Some(crate::support::RefMut::new(ViewVolume {
20488                raw: core::ptr::NonNull::new_unchecked(
20489                    ffi::whiteout_m3_M3Model_get_viewVolumes_at(self.raw.as_ptr(), index),
20490                ),
20491            }))
20492        }
20493    }
20494
20495    /// Iterate the elements, borrowing each in turn.
20496    pub fn view_volumes_iter(
20497        &self,
20498    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, ViewVolume>> {
20499        (0..self.view_volumes_len()).map(move |i| self.view_volumes(i).expect("index below len"))
20500    }
20501
20502    pub fn resize_view_volumes(&mut self, count: usize) {
20503        // SAFETY: exclusive access, so no borrow is outstanding.
20504        unsafe { ffi::whiteout_m3_M3Model_resize_viewVolumes(self.raw.as_ptr(), count) }
20505    }
20506
20507    /// Rigid bodies (PHRB)
20508    pub fn rigid_bodies_len(&self) -> usize {
20509        // SAFETY: scalar read through a live handle.
20510        unsafe { ffi::whiteout_m3_M3Model_get_rigidBodies_count(self.raw.as_ptr()) }
20511    }
20512
20513    /// Borrows element `index` in place. `None` when out of range.
20514    pub fn rigid_bodies(&self, index: usize) -> Option<crate::support::Ref<'_, RigidBody>> {
20515        if index >= self.rigid_bodies_len() {
20516            return None;
20517        }
20518        // SAFETY: index checked above; the pointer is interior to `self`.
20519        unsafe {
20520            Some(crate::support::Ref::new(RigidBody {
20521                raw: core::ptr::NonNull::new_unchecked(
20522                    ffi::whiteout_m3_M3Model_get_rigidBodies_at(self.raw.as_ptr(), index),
20523                ),
20524            }))
20525        }
20526    }
20527
20528    pub fn rigid_bodies_mut(
20529        &mut self,
20530        index: usize,
20531    ) -> Option<crate::support::RefMut<'_, RigidBody>> {
20532        if index >= self.rigid_bodies_len() {
20533            return None;
20534        }
20535        // SAFETY: as above; `&mut self` guarantees exclusivity.
20536        unsafe {
20537            Some(crate::support::RefMut::new(RigidBody {
20538                raw: core::ptr::NonNull::new_unchecked(
20539                    ffi::whiteout_m3_M3Model_get_rigidBodies_at(self.raw.as_ptr(), index),
20540                ),
20541            }))
20542        }
20543    }
20544
20545    /// Iterate the elements, borrowing each in turn.
20546    pub fn rigid_bodies_iter(
20547        &self,
20548    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, RigidBody>> {
20549        (0..self.rigid_bodies_len()).map(move |i| self.rigid_bodies(i).expect("index below len"))
20550    }
20551
20552    pub fn resize_rigid_bodies(&mut self, count: usize) {
20553        // SAFETY: exclusive access, so no borrow is outstanding.
20554        unsafe { ffi::whiteout_m3_M3Model_resize_rigidBodies(self.raw.as_ptr(), count) }
20555    }
20556
20557    /// Physics constraints (PHCT)
20558    pub fn physics_constraints_len(&self) -> usize {
20559        // SAFETY: scalar read through a live handle.
20560        unsafe { ffi::whiteout_m3_M3Model_get_physicsConstraints_count(self.raw.as_ptr()) }
20561    }
20562
20563    /// Borrows element `index` in place. `None` when out of range.
20564    pub fn physics_constraints(
20565        &self,
20566        index: usize,
20567    ) -> Option<crate::support::Ref<'_, PhysicsConstraint>> {
20568        if index >= self.physics_constraints_len() {
20569            return None;
20570        }
20571        // SAFETY: index checked above; the pointer is interior to `self`.
20572        unsafe {
20573            Some(crate::support::Ref::new(PhysicsConstraint {
20574                raw: core::ptr::NonNull::new_unchecked(
20575                    ffi::whiteout_m3_M3Model_get_physicsConstraints_at(self.raw.as_ptr(), index),
20576                ),
20577            }))
20578        }
20579    }
20580
20581    pub fn physics_constraints_mut(
20582        &mut self,
20583        index: usize,
20584    ) -> Option<crate::support::RefMut<'_, PhysicsConstraint>> {
20585        if index >= self.physics_constraints_len() {
20586            return None;
20587        }
20588        // SAFETY: as above; `&mut self` guarantees exclusivity.
20589        unsafe {
20590            Some(crate::support::RefMut::new(PhysicsConstraint {
20591                raw: core::ptr::NonNull::new_unchecked(
20592                    ffi::whiteout_m3_M3Model_get_physicsConstraints_at(self.raw.as_ptr(), index),
20593                ),
20594            }))
20595        }
20596    }
20597
20598    /// Iterate the elements, borrowing each in turn.
20599    pub fn physics_constraints_iter(
20600        &self,
20601    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, PhysicsConstraint>> {
20602        (0..self.physics_constraints_len())
20603            .map(move |i| self.physics_constraints(i).expect("index below len"))
20604    }
20605
20606    pub fn resize_physics_constraints(&mut self, count: usize) {
20607        // SAFETY: exclusive access, so no borrow is outstanding.
20608        unsafe { ffi::whiteout_m3_M3Model_resize_physicsConstraints(self.raw.as_ptr(), count) }
20609    }
20610
20611    /// Physics joints (PHYJ)
20612    pub fn physics_joints_len(&self) -> usize {
20613        // SAFETY: scalar read through a live handle.
20614        unsafe { ffi::whiteout_m3_M3Model_get_physicsJoints_count(self.raw.as_ptr()) }
20615    }
20616
20617    /// Borrows element `index` in place. `None` when out of range.
20618    pub fn physics_joints(&self, index: usize) -> Option<crate::support::Ref<'_, PhysicsJoint>> {
20619        if index >= self.physics_joints_len() {
20620            return None;
20621        }
20622        // SAFETY: index checked above; the pointer is interior to `self`.
20623        unsafe {
20624            Some(crate::support::Ref::new(PhysicsJoint {
20625                raw: core::ptr::NonNull::new_unchecked(
20626                    ffi::whiteout_m3_M3Model_get_physicsJoints_at(self.raw.as_ptr(), index),
20627                ),
20628            }))
20629        }
20630    }
20631
20632    pub fn physics_joints_mut(
20633        &mut self,
20634        index: usize,
20635    ) -> Option<crate::support::RefMut<'_, PhysicsJoint>> {
20636        if index >= self.physics_joints_len() {
20637            return None;
20638        }
20639        // SAFETY: as above; `&mut self` guarantees exclusivity.
20640        unsafe {
20641            Some(crate::support::RefMut::new(PhysicsJoint {
20642                raw: core::ptr::NonNull::new_unchecked(
20643                    ffi::whiteout_m3_M3Model_get_physicsJoints_at(self.raw.as_ptr(), index),
20644                ),
20645            }))
20646        }
20647    }
20648
20649    /// Iterate the elements, borrowing each in turn.
20650    pub fn physics_joints_iter(
20651        &self,
20652    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, PhysicsJoint>> {
20653        (0..self.physics_joints_len())
20654            .map(move |i| self.physics_joints(i).expect("index below len"))
20655    }
20656
20657    pub fn resize_physics_joints(&mut self, count: usize) {
20658        // SAFETY: exclusive access, so no borrow is outstanding.
20659        unsafe { ffi::whiteout_m3_M3Model_resize_physicsJoints(self.raw.as_ptr(), count) }
20660    }
20661
20662    /// Cloth physics (PHCL, v28+)
20663    pub fn cloth_physics_len(&self) -> usize {
20664        // SAFETY: scalar read through a live handle.
20665        unsafe { ffi::whiteout_m3_M3Model_get_clothPhysics_count(self.raw.as_ptr()) }
20666    }
20667
20668    /// Borrows element `index` in place. `None` when out of range.
20669    pub fn cloth_physics(&self, index: usize) -> Option<crate::support::Ref<'_, ClothPhysics>> {
20670        if index >= self.cloth_physics_len() {
20671            return None;
20672        }
20673        // SAFETY: index checked above; the pointer is interior to `self`.
20674        unsafe {
20675            Some(crate::support::Ref::new(ClothPhysics {
20676                raw: core::ptr::NonNull::new_unchecked(
20677                    ffi::whiteout_m3_M3Model_get_clothPhysics_at(self.raw.as_ptr(), index),
20678                ),
20679            }))
20680        }
20681    }
20682
20683    pub fn cloth_physics_mut(
20684        &mut self,
20685        index: usize,
20686    ) -> Option<crate::support::RefMut<'_, ClothPhysics>> {
20687        if index >= self.cloth_physics_len() {
20688            return None;
20689        }
20690        // SAFETY: as above; `&mut self` guarantees exclusivity.
20691        unsafe {
20692            Some(crate::support::RefMut::new(ClothPhysics {
20693                raw: core::ptr::NonNull::new_unchecked(
20694                    ffi::whiteout_m3_M3Model_get_clothPhysics_at(self.raw.as_ptr(), index),
20695                ),
20696            }))
20697        }
20698    }
20699
20700    /// Iterate the elements, borrowing each in turn.
20701    pub fn cloth_physics_iter(
20702        &self,
20703    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, ClothPhysics>> {
20704        (0..self.cloth_physics_len()).map(move |i| self.cloth_physics(i).expect("index below len"))
20705    }
20706
20707    pub fn resize_cloth_physics(&mut self, count: usize) {
20708        // SAFETY: exclusive access, so no borrow is outstanding.
20709        unsafe { ffi::whiteout_m3_M3Model_resize_clothPhysics(self.raw.as_ptr(), count) }
20710    }
20711
20712    /// Two-joint IK solvers (IK2J)
20713    pub fn ik_two_joints_len(&self) -> usize {
20714        // SAFETY: scalar read through a live handle.
20715        unsafe { ffi::whiteout_m3_M3Model_get_ikTwoJoints_count(self.raw.as_ptr()) }
20716    }
20717
20718    /// Borrows element `index` in place. `None` when out of range.
20719    pub fn ik_two_joints(&self, index: usize) -> Option<crate::support::Ref<'_, IKTwoJoint>> {
20720        if index >= self.ik_two_joints_len() {
20721            return None;
20722        }
20723        // SAFETY: index checked above; the pointer is interior to `self`.
20724        unsafe {
20725            Some(crate::support::Ref::new(IKTwoJoint {
20726                raw: core::ptr::NonNull::new_unchecked(
20727                    ffi::whiteout_m3_M3Model_get_ikTwoJoints_at(self.raw.as_ptr(), index),
20728                ),
20729            }))
20730        }
20731    }
20732
20733    pub fn ik_two_joints_mut(
20734        &mut self,
20735        index: usize,
20736    ) -> Option<crate::support::RefMut<'_, IKTwoJoint>> {
20737        if index >= self.ik_two_joints_len() {
20738            return None;
20739        }
20740        // SAFETY: as above; `&mut self` guarantees exclusivity.
20741        unsafe {
20742            Some(crate::support::RefMut::new(IKTwoJoint {
20743                raw: core::ptr::NonNull::new_unchecked(
20744                    ffi::whiteout_m3_M3Model_get_ikTwoJoints_at(self.raw.as_ptr(), index),
20745                ),
20746            }))
20747        }
20748    }
20749
20750    /// Iterate the elements, borrowing each in turn.
20751    pub fn ik_two_joints_iter(
20752        &self,
20753    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, IKTwoJoint>> {
20754        (0..self.ik_two_joints_len()).map(move |i| self.ik_two_joints(i).expect("index below len"))
20755    }
20756
20757    pub fn resize_ik_two_joints(&mut self, count: usize) {
20758        // SAFETY: exclusive access, so no borrow is outstanding.
20759        unsafe { ffi::whiteout_m3_M3Model_resize_ikTwoJoints(self.raw.as_ptr(), count) }
20760    }
20761
20762    /// CCD IK solvers (IKCC, v24+)
20763    pub fn ik_ccd_len(&self) -> usize {
20764        // SAFETY: scalar read through a live handle.
20765        unsafe { ffi::whiteout_m3_M3Model_get_ikCCD_count(self.raw.as_ptr()) }
20766    }
20767
20768    /// Borrows element `index` in place. `None` when out of range.
20769    pub fn ik_ccd(&self, index: usize) -> Option<crate::support::Ref<'_, IKCCD>> {
20770        if index >= self.ik_ccd_len() {
20771            return None;
20772        }
20773        // SAFETY: index checked above; the pointer is interior to `self`.
20774        unsafe {
20775            Some(crate::support::Ref::new(IKCCD {
20776                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Model_get_ikCCD_at(
20777                    self.raw.as_ptr(),
20778                    index,
20779                )),
20780            }))
20781        }
20782    }
20783
20784    pub fn ik_ccd_mut(&mut self, index: usize) -> Option<crate::support::RefMut<'_, IKCCD>> {
20785        if index >= self.ik_ccd_len() {
20786            return None;
20787        }
20788        // SAFETY: as above; `&mut self` guarantees exclusivity.
20789        unsafe {
20790            Some(crate::support::RefMut::new(IKCCD {
20791                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Model_get_ikCCD_at(
20792                    self.raw.as_ptr(),
20793                    index,
20794                )),
20795            }))
20796        }
20797    }
20798
20799    /// Iterate the elements, borrowing each in turn.
20800    pub fn ik_ccd_iter(&self) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, IKCCD>> {
20801        (0..self.ik_ccd_len()).map(move |i| self.ik_ccd(i).expect("index below len"))
20802    }
20803
20804    pub fn resize_ik_ccd(&mut self, count: usize) {
20805        // SAFETY: exclusive access, so no borrow is outstanding.
20806        unsafe { ffi::whiteout_m3_M3Model_resize_ikCCD(self.raw.as_ptr(), count) }
20807    }
20808
20809    /// IK joints (IKJT)
20810    pub fn ik_joints_len(&self) -> usize {
20811        // SAFETY: scalar read through a live handle.
20812        unsafe { ffi::whiteout_m3_M3Model_get_ikJoints_count(self.raw.as_ptr()) }
20813    }
20814
20815    /// Borrows element `index` in place. `None` when out of range.
20816    pub fn ik_joints(&self, index: usize) -> Option<crate::support::Ref<'_, IKJoint>> {
20817        if index >= self.ik_joints_len() {
20818            return None;
20819        }
20820        // SAFETY: index checked above; the pointer is interior to `self`.
20821        unsafe {
20822            Some(crate::support::Ref::new(IKJoint {
20823                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Model_get_ikJoints_at(
20824                    self.raw.as_ptr(),
20825                    index,
20826                )),
20827            }))
20828        }
20829    }
20830
20831    pub fn ik_joints_mut(&mut self, index: usize) -> Option<crate::support::RefMut<'_, IKJoint>> {
20832        if index >= self.ik_joints_len() {
20833            return None;
20834        }
20835        // SAFETY: as above; `&mut self` guarantees exclusivity.
20836        unsafe {
20837            Some(crate::support::RefMut::new(IKJoint {
20838                raw: core::ptr::NonNull::new_unchecked(ffi::whiteout_m3_M3Model_get_ikJoints_at(
20839                    self.raw.as_ptr(),
20840                    index,
20841                )),
20842            }))
20843        }
20844    }
20845
20846    /// Iterate the elements, borrowing each in turn.
20847    pub fn ik_joints_iter(
20848        &self,
20849    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, IKJoint>> {
20850        (0..self.ik_joints_len()).map(move |i| self.ik_joints(i).expect("index below len"))
20851    }
20852
20853    pub fn resize_ik_joints(&mut self, count: usize) {
20854        // SAFETY: exclusive access, so no borrow is outstanding.
20855        unsafe { ffi::whiteout_m3_M3Model_resize_ikJoints(self.raw.as_ptr(), count) }
20856    }
20857
20858    /// One-bone IK solvers (PAOB)
20859    pub fn one_bone_solvers_len(&self) -> usize {
20860        // SAFETY: scalar read through a live handle.
20861        unsafe { ffi::whiteout_m3_M3Model_get_oneBoneSolvers_count(self.raw.as_ptr()) }
20862    }
20863
20864    /// Borrows element `index` in place. `None` when out of range.
20865    pub fn one_bone_solvers(&self, index: usize) -> Option<crate::support::Ref<'_, OneBoneSolver>> {
20866        if index >= self.one_bone_solvers_len() {
20867            return None;
20868        }
20869        // SAFETY: index checked above; the pointer is interior to `self`.
20870        unsafe {
20871            Some(crate::support::Ref::new(OneBoneSolver {
20872                raw: core::ptr::NonNull::new_unchecked(
20873                    ffi::whiteout_m3_M3Model_get_oneBoneSolvers_at(self.raw.as_ptr(), index),
20874                ),
20875            }))
20876        }
20877    }
20878
20879    pub fn one_bone_solvers_mut(
20880        &mut self,
20881        index: usize,
20882    ) -> Option<crate::support::RefMut<'_, OneBoneSolver>> {
20883        if index >= self.one_bone_solvers_len() {
20884            return None;
20885        }
20886        // SAFETY: as above; `&mut self` guarantees exclusivity.
20887        unsafe {
20888            Some(crate::support::RefMut::new(OneBoneSolver {
20889                raw: core::ptr::NonNull::new_unchecked(
20890                    ffi::whiteout_m3_M3Model_get_oneBoneSolvers_at(self.raw.as_ptr(), index),
20891                ),
20892            }))
20893        }
20894    }
20895
20896    /// Iterate the elements, borrowing each in turn.
20897    pub fn one_bone_solvers_iter(
20898        &self,
20899    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, OneBoneSolver>> {
20900        (0..self.one_bone_solvers_len())
20901            .map(move |i| self.one_bone_solvers(i).expect("index below len"))
20902    }
20903
20904    pub fn resize_one_bone_solvers(&mut self, count: usize) {
20905        // SAFETY: exclusive access, so no borrow is outstanding.
20906        unsafe { ffi::whiteout_m3_M3Model_resize_oneBoneSolvers(self.raw.as_ptr(), count) }
20907    }
20908
20909    /// Turret behaviors (PATU)
20910    pub fn turret_behaviors_len(&self) -> usize {
20911        // SAFETY: scalar read through a live handle.
20912        unsafe { ffi::whiteout_m3_M3Model_get_turretBehaviors_count(self.raw.as_ptr()) }
20913    }
20914
20915    /// Borrows element `index` in place. `None` when out of range.
20916    pub fn turret_behaviors(
20917        &self,
20918        index: usize,
20919    ) -> Option<crate::support::Ref<'_, TurretBehavior>> {
20920        if index >= self.turret_behaviors_len() {
20921            return None;
20922        }
20923        // SAFETY: index checked above; the pointer is interior to `self`.
20924        unsafe {
20925            Some(crate::support::Ref::new(TurretBehavior {
20926                raw: core::ptr::NonNull::new_unchecked(
20927                    ffi::whiteout_m3_M3Model_get_turretBehaviors_at(self.raw.as_ptr(), index),
20928                ),
20929            }))
20930        }
20931    }
20932
20933    pub fn turret_behaviors_mut(
20934        &mut self,
20935        index: usize,
20936    ) -> Option<crate::support::RefMut<'_, TurretBehavior>> {
20937        if index >= self.turret_behaviors_len() {
20938            return None;
20939        }
20940        // SAFETY: as above; `&mut self` guarantees exclusivity.
20941        unsafe {
20942            Some(crate::support::RefMut::new(TurretBehavior {
20943                raw: core::ptr::NonNull::new_unchecked(
20944                    ffi::whiteout_m3_M3Model_get_turretBehaviors_at(self.raw.as_ptr(), index),
20945                ),
20946            }))
20947        }
20948    }
20949
20950    /// Iterate the elements, borrowing each in turn.
20951    pub fn turret_behaviors_iter(
20952        &self,
20953    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, TurretBehavior>> {
20954        (0..self.turret_behaviors_len())
20955            .map(move |i| self.turret_behaviors(i).expect("index below len"))
20956    }
20957
20958    pub fn resize_turret_behaviors(&mut self, count: usize) {
20959        // SAFETY: exclusive access, so no borrow is outstanding.
20960        unsafe { ffi::whiteout_m3_M3Model_resize_turretBehaviors(self.raw.as_ptr(), count) }
20961    }
20962
20963    /// Trigger data (TRGD)
20964    pub fn trigger_data_len(&self) -> usize {
20965        // SAFETY: scalar read through a live handle.
20966        unsafe { ffi::whiteout_m3_M3Model_get_triggerData_count(self.raw.as_ptr()) }
20967    }
20968
20969    /// Borrows element `index` in place. `None` when out of range.
20970    pub fn trigger_data(&self, index: usize) -> Option<crate::support::Ref<'_, TriggerData>> {
20971        if index >= self.trigger_data_len() {
20972            return None;
20973        }
20974        // SAFETY: index checked above; the pointer is interior to `self`.
20975        unsafe {
20976            Some(crate::support::Ref::new(TriggerData {
20977                raw: core::ptr::NonNull::new_unchecked(
20978                    ffi::whiteout_m3_M3Model_get_triggerData_at(self.raw.as_ptr(), index),
20979                ),
20980            }))
20981        }
20982    }
20983
20984    pub fn trigger_data_mut(
20985        &mut self,
20986        index: usize,
20987    ) -> Option<crate::support::RefMut<'_, TriggerData>> {
20988        if index >= self.trigger_data_len() {
20989            return None;
20990        }
20991        // SAFETY: as above; `&mut self` guarantees exclusivity.
20992        unsafe {
20993            Some(crate::support::RefMut::new(TriggerData {
20994                raw: core::ptr::NonNull::new_unchecked(
20995                    ffi::whiteout_m3_M3Model_get_triggerData_at(self.raw.as_ptr(), index),
20996                ),
20997            }))
20998        }
20999    }
21000
21001    /// Iterate the elements, borrowing each in turn.
21002    pub fn trigger_data_iter(
21003        &self,
21004    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, TriggerData>> {
21005        (0..self.trigger_data_len()).map(move |i| self.trigger_data(i).expect("index below len"))
21006    }
21007
21008    pub fn resize_trigger_data(&mut self, count: usize) {
21009        // SAFETY: exclusive access, so no borrow is outstanding.
21010        unsafe { ffi::whiteout_m3_M3Model_resize_triggerData(self.raw.as_ptr(), count) }
21011    }
21012
21013    /// Inverse bind-pose matrices (IREF)
21014    pub fn initial_reference_len(&self) -> usize {
21015        // SAFETY: scalar read through a live handle.
21016        unsafe { ffi::whiteout_m3_M3Model_get_initialReference_count(self.raw.as_ptr()) }
21017    }
21018
21019    /// Borrows element `index` in place. `None` when out of range.
21020    pub fn initial_reference(
21021        &self,
21022        index: usize,
21023    ) -> Option<crate::support::Ref<'_, InitialReference>> {
21024        if index >= self.initial_reference_len() {
21025            return None;
21026        }
21027        // SAFETY: index checked above; the pointer is interior to `self`.
21028        unsafe {
21029            Some(crate::support::Ref::new(InitialReference {
21030                raw: core::ptr::NonNull::new_unchecked(
21031                    ffi::whiteout_m3_M3Model_get_initialReference_at(self.raw.as_ptr(), index),
21032                ),
21033            }))
21034        }
21035    }
21036
21037    pub fn initial_reference_mut(
21038        &mut self,
21039        index: usize,
21040    ) -> Option<crate::support::RefMut<'_, InitialReference>> {
21041        if index >= self.initial_reference_len() {
21042            return None;
21043        }
21044        // SAFETY: as above; `&mut self` guarantees exclusivity.
21045        unsafe {
21046            Some(crate::support::RefMut::new(InitialReference {
21047                raw: core::ptr::NonNull::new_unchecked(
21048                    ffi::whiteout_m3_M3Model_get_initialReference_at(self.raw.as_ptr(), index),
21049                ),
21050            }))
21051        }
21052    }
21053
21054    /// Iterate the elements, borrowing each in turn.
21055    pub fn initial_reference_iter(
21056        &self,
21057    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, InitialReference>> {
21058        (0..self.initial_reference_len())
21059            .map(move |i| self.initial_reference(i).expect("index below len"))
21060    }
21061
21062    pub fn resize_initial_reference(&mut self, count: usize) {
21063        // SAFETY: exclusive access, so no borrow is outstanding.
21064        unsafe { ffi::whiteout_m3_M3Model_resize_initialReference(self.raw.as_ptr(), count) }
21065    }
21066
21067    /// Tight hit-test shape (SSGS, inline)
21068    /// Borrows the field in place — no copy, no allocation.
21069    pub fn tight_hit_test_object(&self) -> crate::support::Ref<'_, HitTestShape> {
21070        // SAFETY: an interior pointer into `self`, valid for this
21071        // borrow and never freed by the `Ref`.
21072        unsafe {
21073            crate::support::Ref::new(HitTestShape {
21074                raw: core::ptr::NonNull::new_unchecked(
21075                    ffi::whiteout_m3_M3Model_get_tightHitTestObject(self.raw.as_ptr()),
21076                ),
21077            })
21078        }
21079    }
21080
21081    pub fn tight_hit_test_object_mut(&mut self) -> crate::support::RefMut<'_, HitTestShape> {
21082        // SAFETY: as above; `&mut self` guarantees exclusivity.
21083        unsafe {
21084            crate::support::RefMut::new(HitTestShape {
21085                raw: core::ptr::NonNull::new_unchecked(
21086                    ffi::whiteout_m3_M3Model_get_tightHitTestObject(self.raw.as_ptr()),
21087                ),
21088            })
21089        }
21090    }
21091
21092    /// Fuzzy hit-test shapes (SSGS)
21093    pub fn fuzzy_hit_test_objects_len(&self) -> usize {
21094        // SAFETY: scalar read through a live handle.
21095        unsafe { ffi::whiteout_m3_M3Model_get_fuzzyHitTestObjects_count(self.raw.as_ptr()) }
21096    }
21097
21098    /// Borrows element `index` in place. `None` when out of range.
21099    pub fn fuzzy_hit_test_objects(
21100        &self,
21101        index: usize,
21102    ) -> Option<crate::support::Ref<'_, HitTestShape>> {
21103        if index >= self.fuzzy_hit_test_objects_len() {
21104            return None;
21105        }
21106        // SAFETY: index checked above; the pointer is interior to `self`.
21107        unsafe {
21108            Some(crate::support::Ref::new(HitTestShape {
21109                raw: core::ptr::NonNull::new_unchecked(
21110                    ffi::whiteout_m3_M3Model_get_fuzzyHitTestObjects_at(self.raw.as_ptr(), index),
21111                ),
21112            }))
21113        }
21114    }
21115
21116    pub fn fuzzy_hit_test_objects_mut(
21117        &mut self,
21118        index: usize,
21119    ) -> Option<crate::support::RefMut<'_, HitTestShape>> {
21120        if index >= self.fuzzy_hit_test_objects_len() {
21121            return None;
21122        }
21123        // SAFETY: as above; `&mut self` guarantees exclusivity.
21124        unsafe {
21125            Some(crate::support::RefMut::new(HitTestShape {
21126                raw: core::ptr::NonNull::new_unchecked(
21127                    ffi::whiteout_m3_M3Model_get_fuzzyHitTestObjects_at(self.raw.as_ptr(), index),
21128                ),
21129            }))
21130        }
21131    }
21132
21133    /// Iterate the elements, borrowing each in turn.
21134    pub fn fuzzy_hit_test_objects_iter(
21135        &self,
21136    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, HitTestShape>> {
21137        (0..self.fuzzy_hit_test_objects_len())
21138            .map(move |i| self.fuzzy_hit_test_objects(i).expect("index below len"))
21139    }
21140
21141    pub fn resize_fuzzy_hit_test_objects(&mut self, count: usize) {
21142        // SAFETY: exclusive access, so no borrow is outstanding.
21143        unsafe { ffi::whiteout_m3_M3Model_resize_fuzzyHitTestObjects(self.raw.as_ptr(), count) }
21144    }
21145
21146    /// Attachment volumes (ATVL)
21147    pub fn attachment_volumes_len(&self) -> usize {
21148        // SAFETY: scalar read through a live handle.
21149        unsafe { ffi::whiteout_m3_M3Model_get_attachmentVolumes_count(self.raw.as_ptr()) }
21150    }
21151
21152    /// Borrows element `index` in place. `None` when out of range.
21153    pub fn attachment_volumes(
21154        &self,
21155        index: usize,
21156    ) -> Option<crate::support::Ref<'_, AttachmentVolume>> {
21157        if index >= self.attachment_volumes_len() {
21158            return None;
21159        }
21160        // SAFETY: index checked above; the pointer is interior to `self`.
21161        unsafe {
21162            Some(crate::support::Ref::new(AttachmentVolume {
21163                raw: core::ptr::NonNull::new_unchecked(
21164                    ffi::whiteout_m3_M3Model_get_attachmentVolumes_at(self.raw.as_ptr(), index),
21165                ),
21166            }))
21167        }
21168    }
21169
21170    pub fn attachment_volumes_mut(
21171        &mut self,
21172        index: usize,
21173    ) -> Option<crate::support::RefMut<'_, AttachmentVolume>> {
21174        if index >= self.attachment_volumes_len() {
21175            return None;
21176        }
21177        // SAFETY: as above; `&mut self` guarantees exclusivity.
21178        unsafe {
21179            Some(crate::support::RefMut::new(AttachmentVolume {
21180                raw: core::ptr::NonNull::new_unchecked(
21181                    ffi::whiteout_m3_M3Model_get_attachmentVolumes_at(self.raw.as_ptr(), index),
21182                ),
21183            }))
21184        }
21185    }
21186
21187    /// Iterate the elements, borrowing each in turn.
21188    pub fn attachment_volumes_iter(
21189        &self,
21190    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, AttachmentVolume>> {
21191        (0..self.attachment_volumes_len())
21192            .map(move |i| self.attachment_volumes(i).expect("index below len"))
21193    }
21194
21195    pub fn resize_attachment_volumes(&mut self, count: usize) {
21196        // SAFETY: exclusive access, so no borrow is outstanding.
21197        unsafe { ffi::whiteout_m3_M3Model_resize_attachmentVolumes(self.raw.as_ptr(), count) }
21198    }
21199
21200    /// Attachment volume addon 0 (U16_)
21201    /// Zero-copy view of the underlying `std::vector`.
21202    pub fn attachment_volumes_addon_0(&self) -> &[u16] {
21203        // SAFETY: `_data`/`_count` describe one contiguous C++
21204        // allocation, borrowed for as long as `self` is.
21205        unsafe {
21206            let n = ffi::whiteout_m3_M3Model_get_attachmentVolumesAddon0_count(self.raw.as_ptr());
21207            let p = ffi::whiteout_m3_M3Model_get_attachmentVolumesAddon0_data(self.raw.as_ptr());
21208            if p.is_null() || n == 0 {
21209                &[]
21210            } else {
21211                core::slice::from_raw_parts(p, n)
21212            }
21213        }
21214    }
21215
21216    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
21217    pub fn attachment_volumes_addon_0_mut(&mut self) -> &mut [u16] {
21218        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
21219        unsafe {
21220            let n = ffi::whiteout_m3_M3Model_get_attachmentVolumesAddon0_count(self.raw.as_ptr());
21221            let p = ffi::whiteout_m3_M3Model_get_attachmentVolumesAddon0_data(self.raw.as_ptr())
21222                as *mut u16;
21223            if p.is_null() || n == 0 {
21224                &mut []
21225            } else {
21226                core::slice::from_raw_parts_mut(p, n)
21227            }
21228        }
21229    }
21230
21231    pub fn set_attachment_volumes_addon_0(&mut self, values: &[u16]) {
21232        // SAFETY: the native side copies `values` before returning.
21233        unsafe {
21234            ffi::whiteout_m3_M3Model_assign_attachmentVolumesAddon0(
21235                self.raw.as_ptr(),
21236                values.as_ptr() as *const _,
21237                values.len(),
21238            )
21239        }
21240    }
21241
21242    pub fn resize_attachment_volumes_addon_0(&mut self, count: usize) {
21243        // SAFETY: reallocation is safe here precisely because
21244        // `&mut self` means no slice borrow is outstanding.
21245        unsafe { ffi::whiteout_m3_M3Model_resize_attachmentVolumesAddon0(self.raw.as_ptr(), count) }
21246    }
21247
21248    /// Attachment volume addon 1 (U16_)
21249    /// Zero-copy view of the underlying `std::vector`.
21250    pub fn attachment_volumes_addon_1(&self) -> &[u16] {
21251        // SAFETY: `_data`/`_count` describe one contiguous C++
21252        // allocation, borrowed for as long as `self` is.
21253        unsafe {
21254            let n = ffi::whiteout_m3_M3Model_get_attachmentVolumesAddon1_count(self.raw.as_ptr());
21255            let p = ffi::whiteout_m3_M3Model_get_attachmentVolumesAddon1_data(self.raw.as_ptr());
21256            if p.is_null() || n == 0 {
21257                &[]
21258            } else {
21259                core::slice::from_raw_parts(p, n)
21260            }
21261        }
21262    }
21263
21264    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
21265    pub fn attachment_volumes_addon_1_mut(&mut self) -> &mut [u16] {
21266        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
21267        unsafe {
21268            let n = ffi::whiteout_m3_M3Model_get_attachmentVolumesAddon1_count(self.raw.as_ptr());
21269            let p = ffi::whiteout_m3_M3Model_get_attachmentVolumesAddon1_data(self.raw.as_ptr())
21270                as *mut u16;
21271            if p.is_null() || n == 0 {
21272                &mut []
21273            } else {
21274                core::slice::from_raw_parts_mut(p, n)
21275            }
21276        }
21277    }
21278
21279    pub fn set_attachment_volumes_addon_1(&mut self, values: &[u16]) {
21280        // SAFETY: the native side copies `values` before returning.
21281        unsafe {
21282            ffi::whiteout_m3_M3Model_assign_attachmentVolumesAddon1(
21283                self.raw.as_ptr(),
21284                values.as_ptr() as *const _,
21285                values.len(),
21286            )
21287        }
21288    }
21289
21290    pub fn resize_attachment_volumes_addon_1(&mut self, count: usize) {
21291        // SAFETY: reallocation is safe here precisely because
21292        // `&mut self` means no slice borrow is outstanding.
21293        unsafe { ffi::whiteout_m3_M3Model_resize_attachmentVolumesAddon1(self.raw.as_ptr(), count) }
21294    }
21295
21296    /// Billboard behaviors (BBSC)
21297    pub fn billboard_behaviors_len(&self) -> usize {
21298        // SAFETY: scalar read through a live handle.
21299        unsafe { ffi::whiteout_m3_M3Model_get_billboardBehaviors_count(self.raw.as_ptr()) }
21300    }
21301
21302    /// Borrows element `index` in place. `None` when out of range.
21303    pub fn billboard_behaviors(
21304        &self,
21305        index: usize,
21306    ) -> Option<crate::support::Ref<'_, BillboardBehavior>> {
21307        if index >= self.billboard_behaviors_len() {
21308            return None;
21309        }
21310        // SAFETY: index checked above; the pointer is interior to `self`.
21311        unsafe {
21312            Some(crate::support::Ref::new(BillboardBehavior {
21313                raw: core::ptr::NonNull::new_unchecked(
21314                    ffi::whiteout_m3_M3Model_get_billboardBehaviors_at(self.raw.as_ptr(), index),
21315                ),
21316            }))
21317        }
21318    }
21319
21320    pub fn billboard_behaviors_mut(
21321        &mut self,
21322        index: usize,
21323    ) -> Option<crate::support::RefMut<'_, BillboardBehavior>> {
21324        if index >= self.billboard_behaviors_len() {
21325            return None;
21326        }
21327        // SAFETY: as above; `&mut self` guarantees exclusivity.
21328        unsafe {
21329            Some(crate::support::RefMut::new(BillboardBehavior {
21330                raw: core::ptr::NonNull::new_unchecked(
21331                    ffi::whiteout_m3_M3Model_get_billboardBehaviors_at(self.raw.as_ptr(), index),
21332                ),
21333            }))
21334        }
21335    }
21336
21337    /// Iterate the elements, borrowing each in turn.
21338    pub fn billboard_behaviors_iter(
21339        &self,
21340    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, BillboardBehavior>> {
21341        (0..self.billboard_behaviors_len())
21342            .map(move |i| self.billboard_behaviors(i).expect("index below len"))
21343    }
21344
21345    pub fn resize_billboard_behaviors(&mut self, count: usize) {
21346        // SAFETY: exclusive access, so no borrow is outstanding.
21347        unsafe { ffi::whiteout_m3_M3Model_resize_billboardBehaviors(self.raw.as_ptr(), count) }
21348    }
21349
21350    /// Trailing models (TMD_, defunct)
21351    pub fn trailing_models_len(&self) -> usize {
21352        // SAFETY: scalar read through a live handle.
21353        unsafe { ffi::whiteout_m3_M3Model_get_trailingModels_count(self.raw.as_ptr()) }
21354    }
21355
21356    /// Borrows element `index` in place. `None` when out of range.
21357    pub fn trailing_models(&self, index: usize) -> Option<crate::support::Ref<'_, TrailingModel>> {
21358        if index >= self.trailing_models_len() {
21359            return None;
21360        }
21361        // SAFETY: index checked above; the pointer is interior to `self`.
21362        unsafe {
21363            Some(crate::support::Ref::new(TrailingModel {
21364                raw: core::ptr::NonNull::new_unchecked(
21365                    ffi::whiteout_m3_M3Model_get_trailingModels_at(self.raw.as_ptr(), index),
21366                ),
21367            }))
21368        }
21369    }
21370
21371    pub fn trailing_models_mut(
21372        &mut self,
21373        index: usize,
21374    ) -> Option<crate::support::RefMut<'_, TrailingModel>> {
21375        if index >= self.trailing_models_len() {
21376            return None;
21377        }
21378        // SAFETY: as above; `&mut self` guarantees exclusivity.
21379        unsafe {
21380            Some(crate::support::RefMut::new(TrailingModel {
21381                raw: core::ptr::NonNull::new_unchecked(
21382                    ffi::whiteout_m3_M3Model_get_trailingModels_at(self.raw.as_ptr(), index),
21383                ),
21384            }))
21385        }
21386    }
21387
21388    /// Iterate the elements, borrowing each in turn.
21389    pub fn trailing_models_iter(
21390        &self,
21391    ) -> impl ExactSizeIterator<Item = crate::support::Ref<'_, TrailingModel>> {
21392        (0..self.trailing_models_len())
21393            .map(move |i| self.trailing_models(i).expect("index below len"))
21394    }
21395
21396    pub fn resize_trailing_models(&mut self, count: usize) {
21397        // SAFETY: exclusive access, so no borrow is outstanding.
21398        unsafe { ffi::whiteout_m3_M3Model_resize_trailingModels(self.raw.as_ptr(), count) }
21399    }
21400
21401    /// Hash for .m3a animation file binding
21402    pub fn m_3a_anim_hash(&self) -> u32 {
21403        // SAFETY: plain scalar read through a live handle.
21404        unsafe { ffi::whiteout_m3_M3Model_get_m3aAnimHash(self.raw.as_ptr()) }
21405    }
21406
21407    pub fn set_m_3a_anim_hash(&mut self, value: u32) {
21408        // SAFETY: plain scalar write through a live handle.
21409        unsafe { ffi::whiteout_m3_M3Model_set_m3aAnimHash(self.raw.as_ptr(), value) }
21410    }
21411
21412    /// Additional .m3a hashes (U32_)
21413    /// Zero-copy view of the underlying `std::vector`.
21414    pub fn m_3a_anim_hashes(&self) -> &[u32] {
21415        // SAFETY: `_data`/`_count` describe one contiguous C++
21416        // allocation, borrowed for as long as `self` is.
21417        unsafe {
21418            let n = ffi::whiteout_m3_M3Model_get_m3aAnimHashes_count(self.raw.as_ptr());
21419            let p = ffi::whiteout_m3_M3Model_get_m3aAnimHashes_data(self.raw.as_ptr());
21420            if p.is_null() || n == 0 {
21421                &[]
21422            } else {
21423                core::slice::from_raw_parts(p, n)
21424            }
21425        }
21426    }
21427
21428    /// Zero-copy mutable view. Resize first — the borrow forbids it after.
21429    pub fn m_3a_anim_hashes_mut(&mut self) -> &mut [u32] {
21430        // SAFETY: as above; `&mut self` rules out aliasing and resizing.
21431        unsafe {
21432            let n = ffi::whiteout_m3_M3Model_get_m3aAnimHashes_count(self.raw.as_ptr());
21433            let p = ffi::whiteout_m3_M3Model_get_m3aAnimHashes_data(self.raw.as_ptr()) as *mut u32;
21434            if p.is_null() || n == 0 {
21435                &mut []
21436            } else {
21437                core::slice::from_raw_parts_mut(p, n)
21438            }
21439        }
21440    }
21441
21442    pub fn set_m_3a_anim_hashes(&mut self, values: &[u32]) {
21443        // SAFETY: the native side copies `values` before returning.
21444        unsafe {
21445            ffi::whiteout_m3_M3Model_assign_m3aAnimHashes(
21446                self.raw.as_ptr(),
21447                values.as_ptr() as *const _,
21448                values.len(),
21449            )
21450        }
21451    }
21452
21453    pub fn resize_m_3a_anim_hashes(&mut self, count: usize) {
21454        // SAFETY: reallocation is safe here precisely because
21455        // `&mut self` means no slice borrow is outstanding.
21456        unsafe { ffi::whiteout_m3_M3Model_resize_m3aAnimHashes(self.raw.as_ptr(), count) }
21457    }
21458}
21459
21460impl Default for Model {
21461    fn default() -> Self {
21462        Self::new()
21463    }
21464}
21465
21466/// Parser for M3 model files
21467///
21468/// The Parser reads binary M3 files and converts them into the Model structure. It supports multiple parsing modes for error handling.
21469///
21470/// Uses the PImpl (Pointer to Implementation) idiom to hide implementation details.
21471pub struct Parser {
21472    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3Parser>,
21473}
21474
21475impl Drop for Parser {
21476    fn drop(&mut self) {
21477        // SAFETY: `raw` came from a native constructor and Drop runs once.
21478        unsafe { ffi::whiteout_m3_M3Parser_delete(self.raw.as_ptr()) }
21479    }
21480}
21481
21482impl Parser {
21483    /// # Safety
21484    /// `raw` must be a live handle this value takes ownership of.
21485    #[allow(dead_code)] // used by whichever methods return this type
21486    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3Parser) -> Option<Self> {
21487        core::ptr::NonNull::new(raw).map(|raw| Parser { raw })
21488    }
21489}
21490
21491// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
21492// is deliberately NOT implemented — the C++ types make no documented
21493// guarantee about concurrent use, and claiming one we haven't verified
21494// would be unsound. See `@bind thread_safe` in the plan.
21495unsafe impl Send for Parser {}
21496
21497impl core::fmt::Debug for Parser {
21498    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
21499        f.debug_struct("Parser").finish_non_exhaustive()
21500    }
21501}
21502
21503impl Parser {
21504    /// # Panics
21505    /// Panics if the native allocation fails.
21506    pub fn new() -> Self {
21507        // SAFETY: the native constructor returns a live handle; a null here
21508        // means the library is unusable.
21509        unsafe {
21510            let raw = ffi::whiteout_m3_M3Parser_new();
21511            Self::from_raw(raw).expect("native Parser allocation failed")
21512        }
21513    }
21514
21515    /// 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
21516    pub fn parse_file(&mut self, file_path: &str) -> Option<Model> {
21517        let file_path_cstr = std::ffi::CString::new(file_path).unwrap_or_default();
21518        // SAFETY: handle is live for the duration of the call.
21519        unsafe {
21520            Model::from_raw(ffi::whiteout_m3_M3Parser_parse(
21521                self.raw.as_ptr(),
21522                file_path_cstr.as_ptr(),
21523            ))
21524        }
21525    }
21526
21527    /// 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
21528    pub fn parse(&mut self, buffer: &[u8]) -> Option<Model> {
21529        // SAFETY: handle is live for the duration of the call.
21530        unsafe {
21531            Model::from_raw(ffi::whiteout_m3_M3Parser_parse_buffer(
21532                self.raw.as_ptr(),
21533                buffer.as_ptr(),
21534                buffer.len(),
21535            ))
21536        }
21537    }
21538
21539    /// Check if parsing encountered any issues @return True if there were warnings or recoverable errors
21540    pub fn has_issues(&self) -> bool {
21541        // SAFETY: handle is live for the duration of the call.
21542        unsafe { ffi::whiteout_m3_M3Parser_hasIssues(self.raw.as_ptr()) != 0 }
21543    }
21544
21545    /// Get list of issues encountered during parsing @return Vector of issue description strings
21546    pub fn issues(&self) -> Vec<String> {
21547        // SAFETY: index stays below the reported count.
21548        unsafe {
21549            let n = ffi::whiteout_m3_M3Parser_getIssues_count(self.raw.as_ptr());
21550            (0..n)
21551                .map(|i| {
21552                    crate::support::take_string(ffi::whiteout_m3_M3Parser_getIssues_at(
21553                        self.raw.as_ptr(),
21554                        i,
21555                    ))
21556                })
21557                .collect()
21558        }
21559    }
21560}
21561
21562impl Default for Parser {
21563    fn default() -> Self {
21564        Self::new()
21565    }
21566}
21567
21568/// Writer for M3 model files
21569///
21570/// Writes Model structures to disk in binary M3 format. Uses the PImpl (Pointer to Implementation) idiom to hide implementation details.
21571pub struct Writer {
21572    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3Writer>,
21573}
21574
21575impl Drop for Writer {
21576    fn drop(&mut self) {
21577        // SAFETY: `raw` came from a native constructor and Drop runs once.
21578        unsafe { ffi::whiteout_m3_M3Writer_delete(self.raw.as_ptr()) }
21579    }
21580}
21581
21582impl Writer {
21583    /// # Safety
21584    /// `raw` must be a live handle this value takes ownership of.
21585    #[allow(dead_code)] // used by whichever methods return this type
21586    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3Writer) -> Option<Self> {
21587        core::ptr::NonNull::new(raw).map(|raw| Writer { raw })
21588    }
21589}
21590
21591// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
21592// is deliberately NOT implemented — the C++ types make no documented
21593// guarantee about concurrent use, and claiming one we haven't verified
21594// would be unsound. See `@bind thread_safe` in the plan.
21595unsafe impl Send for Writer {}
21596
21597impl core::fmt::Debug for Writer {
21598    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
21599        f.debug_struct("Writer").finish_non_exhaustive()
21600    }
21601}
21602
21603impl Writer {
21604    /// # Panics
21605    /// Panics if the native allocation fails.
21606    pub fn new() -> Self {
21607        // SAFETY: the native constructor returns a live handle; a null here
21608        // means the library is unusable.
21609        unsafe {
21610            let raw = ffi::whiteout_m3_M3Writer_new();
21611            Self::from_raw(raw).expect("native Writer allocation failed")
21612        }
21613    }
21614
21615    /// 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
21616    pub fn write_file(&mut self, file_path: &str, model: &Model) {
21617        let file_path_cstr = std::ffi::CString::new(file_path).unwrap_or_default();
21618        // SAFETY: handle is live for the duration of the call.
21619        unsafe {
21620            ffi::whiteout_m3_M3Writer_write(
21621                self.raw.as_ptr(),
21622                file_path_cstr.as_ptr(),
21623                model.raw.as_ptr(),
21624            );
21625        }
21626    }
21627
21628    /// Write an M3 model to a byte buffer @param model Model data to serialize @return Byte buffer containing the M3 file data
21629    pub fn write(&mut self, model: &Model) -> Bytes {
21630        // SAFETY: handle is live for the duration of the call.
21631        unsafe {
21632            Bytes::from_raw(ffi::whiteout_m3_M3Writer_write_model(
21633                self.raw.as_ptr(),
21634                model.raw.as_ptr(),
21635            ))
21636            .unwrap_or_else(Bytes::empty)
21637        }
21638    }
21639}
21640
21641impl Default for Writer {
21642    fn default() -> Self {
21643        Self::new()
21644    }
21645}
21646
21647/// Animatable reference holding a default value and animation link
21648///
21649/// 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.
21650///
21651/// @tparam T The value type (f32, Vector3f, Quaternion, ColorBGRA, Extent, etc.)
21652pub struct AnimRefF32 {
21653    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3AnimRefF32>,
21654}
21655
21656impl Drop for AnimRefF32 {
21657    fn drop(&mut self) {
21658        // SAFETY: `raw` came from a native constructor and Drop runs once.
21659        unsafe { ffi::whiteout_m3_M3AnimRefF32_delete(self.raw.as_ptr()) }
21660    }
21661}
21662
21663impl AnimRefF32 {
21664    /// # Safety
21665    /// `raw` must be a live handle this value takes ownership of.
21666    #[allow(dead_code)] // used by whichever methods return this type
21667    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3AnimRefF32) -> Option<Self> {
21668        core::ptr::NonNull::new(raw).map(|raw| AnimRefF32 { raw })
21669    }
21670}
21671
21672// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
21673// is deliberately NOT implemented — the C++ types make no documented
21674// guarantee about concurrent use, and claiming one we haven't verified
21675// would be unsound. See `@bind thread_safe` in the plan.
21676unsafe impl Send for AnimRefF32 {}
21677
21678impl core::fmt::Debug for AnimRefF32 {
21679    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
21680        f.debug_struct("AnimRefF32").finish_non_exhaustive()
21681    }
21682}
21683
21684impl AnimRefF32 {
21685    /// # Panics
21686    /// Panics if the native allocation fails.
21687    pub fn new() -> Self {
21688        // SAFETY: the native constructor returns a live handle; a null here
21689        // means the library is unusable.
21690        unsafe {
21691            let raw = ffi::whiteout_m3_M3AnimRefF32_new();
21692            Self::from_raw(raw).expect("native AnimRefF32 allocation failed")
21693        }
21694    }
21695
21696    /// Interpolation: 0=none/step, 1=linear, 2=hermite, 3=bezier
21697    pub fn interp_type(&self) -> u16 {
21698        // SAFETY: plain scalar read through a live handle.
21699        unsafe { ffi::whiteout_m3_M3AnimRefF32_get_interpType(self.raw.as_ptr()) }
21700    }
21701
21702    pub fn set_interp_type(&mut self, value: u16) {
21703        // SAFETY: plain scalar write through a live handle.
21704        unsafe { ffi::whiteout_m3_M3AnimRefF32_set_interpType(self.raw.as_ptr(), value) }
21705    }
21706
21707    /// Animation flags
21708    pub fn flags(&self) -> u16 {
21709        // SAFETY: plain scalar read through a live handle.
21710        unsafe { ffi::whiteout_m3_M3AnimRefF32_get_flags(self.raw.as_ptr()) }
21711    }
21712
21713    pub fn set_flags(&mut self, value: u16) {
21714        // SAFETY: plain scalar write through a live handle.
21715        unsafe { ffi::whiteout_m3_M3AnimRefF32_set_flags(self.raw.as_ptr(), value) }
21716    }
21717
21718    /// Animation identifier (links to STC animation data; 0=not animated)
21719    pub fn anim_id(&self) -> u32 {
21720        // SAFETY: plain scalar read through a live handle.
21721        unsafe { ffi::whiteout_m3_M3AnimRefF32_get_animId(self.raw.as_ptr()) }
21722    }
21723
21724    pub fn set_anim_id(&mut self, value: u32) {
21725        // SAFETY: plain scalar write through a live handle.
21726        unsafe { ffi::whiteout_m3_M3AnimRefF32_set_animId(self.raw.as_ptr(), value) }
21727    }
21728
21729    /// Initial/default value (used when not animated)
21730    pub fn init_value(&self) -> f32 {
21731        // SAFETY: plain scalar read through a live handle.
21732        unsafe { ffi::whiteout_m3_M3AnimRefF32_get_initValue(self.raw.as_ptr()) }
21733    }
21734
21735    pub fn set_init_value(&mut self, value: f32) {
21736        // SAFETY: plain scalar write through a live handle.
21737        unsafe { ffi::whiteout_m3_M3AnimRefF32_set_initValue(self.raw.as_ptr(), value) }
21738    }
21739
21740    /// Null/reset value
21741    pub fn null_value(&self) -> f32 {
21742        // SAFETY: plain scalar read through a live handle.
21743        unsafe { ffi::whiteout_m3_M3AnimRefF32_get_nullValue(self.raw.as_ptr()) }
21744    }
21745
21746    pub fn set_null_value(&mut self, value: f32) {
21747        // SAFETY: plain scalar write through a live handle.
21748        unsafe { ffi::whiteout_m3_M3AnimRefF32_set_nullValue(self.raw.as_ptr(), value) }
21749    }
21750
21751    /// Typically -1
21752    pub fn unused(&self) -> i32 {
21753        // SAFETY: plain scalar read through a live handle.
21754        unsafe { ffi::whiteout_m3_M3AnimRefF32_get_unused(self.raw.as_ptr()) }
21755    }
21756
21757    pub fn set_unused(&mut self, value: i32) {
21758        // SAFETY: plain scalar write through a live handle.
21759        unsafe { ffi::whiteout_m3_M3AnimRefF32_set_unused(self.raw.as_ptr(), value) }
21760    }
21761}
21762
21763impl Default for AnimRefF32 {
21764    fn default() -> Self {
21765        Self::new()
21766    }
21767}
21768
21769/// Animatable reference holding a default value and animation link
21770///
21771/// 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.
21772///
21773/// @tparam T The value type (f32, Vector3f, Quaternion, ColorBGRA, Extent, etc.)
21774pub struct AnimRefVector3f {
21775    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3AnimRefVector3f>,
21776}
21777
21778impl Drop for AnimRefVector3f {
21779    fn drop(&mut self) {
21780        // SAFETY: `raw` came from a native constructor and Drop runs once.
21781        unsafe { ffi::whiteout_m3_M3AnimRefVector3f_delete(self.raw.as_ptr()) }
21782    }
21783}
21784
21785impl AnimRefVector3f {
21786    /// # Safety
21787    /// `raw` must be a live handle this value takes ownership of.
21788    #[allow(dead_code)] // used by whichever methods return this type
21789    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3AnimRefVector3f) -> Option<Self> {
21790        core::ptr::NonNull::new(raw).map(|raw| AnimRefVector3f { raw })
21791    }
21792}
21793
21794// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
21795// is deliberately NOT implemented — the C++ types make no documented
21796// guarantee about concurrent use, and claiming one we haven't verified
21797// would be unsound. See `@bind thread_safe` in the plan.
21798unsafe impl Send for AnimRefVector3f {}
21799
21800impl core::fmt::Debug for AnimRefVector3f {
21801    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
21802        f.debug_struct("AnimRefVector3f").finish_non_exhaustive()
21803    }
21804}
21805
21806impl AnimRefVector3f {
21807    /// # Panics
21808    /// Panics if the native allocation fails.
21809    pub fn new() -> Self {
21810        // SAFETY: the native constructor returns a live handle; a null here
21811        // means the library is unusable.
21812        unsafe {
21813            let raw = ffi::whiteout_m3_M3AnimRefVector3f_new();
21814            Self::from_raw(raw).expect("native AnimRefVector3f allocation failed")
21815        }
21816    }
21817
21818    /// Interpolation: 0=none/step, 1=linear, 2=hermite, 3=bezier
21819    pub fn interp_type(&self) -> u16 {
21820        // SAFETY: plain scalar read through a live handle.
21821        unsafe { ffi::whiteout_m3_M3AnimRefVector3f_get_interpType(self.raw.as_ptr()) }
21822    }
21823
21824    pub fn set_interp_type(&mut self, value: u16) {
21825        // SAFETY: plain scalar write through a live handle.
21826        unsafe { ffi::whiteout_m3_M3AnimRefVector3f_set_interpType(self.raw.as_ptr(), value) }
21827    }
21828
21829    /// Animation flags
21830    pub fn flags(&self) -> u16 {
21831        // SAFETY: plain scalar read through a live handle.
21832        unsafe { ffi::whiteout_m3_M3AnimRefVector3f_get_flags(self.raw.as_ptr()) }
21833    }
21834
21835    pub fn set_flags(&mut self, value: u16) {
21836        // SAFETY: plain scalar write through a live handle.
21837        unsafe { ffi::whiteout_m3_M3AnimRefVector3f_set_flags(self.raw.as_ptr(), value) }
21838    }
21839
21840    /// Animation identifier (links to STC animation data; 0=not animated)
21841    pub fn anim_id(&self) -> u32 {
21842        // SAFETY: plain scalar read through a live handle.
21843        unsafe { ffi::whiteout_m3_M3AnimRefVector3f_get_animId(self.raw.as_ptr()) }
21844    }
21845
21846    pub fn set_anim_id(&mut self, value: u32) {
21847        // SAFETY: plain scalar write through a live handle.
21848        unsafe { ffi::whiteout_m3_M3AnimRefVector3f_set_animId(self.raw.as_ptr(), value) }
21849    }
21850
21851    /// Initial/default value (used when not animated)
21852    pub fn init_value(&self) -> crate::math::Vector3f {
21853        // SAFETY: the getter returns an interior pointer to a
21854        // layout-identical POD; we copy it out immediately.
21855        unsafe {
21856            *(ffi::whiteout_m3_M3AnimRefVector3f_get_initValue(self.raw.as_ptr())
21857                as *const crate::math::Vector3f)
21858        }
21859    }
21860
21861    pub fn set_init_value(&mut self, value: crate::math::Vector3f) {
21862        // SAFETY: as above, in the other direction.
21863        unsafe {
21864            ffi::whiteout_m3_M3AnimRefVector3f_set_initValue(
21865                self.raw.as_ptr(),
21866                &value as *const crate::math::Vector3f as *const _,
21867            )
21868        }
21869    }
21870
21871    /// Null/reset value
21872    pub fn null_value(&self) -> crate::math::Vector3f {
21873        // SAFETY: the getter returns an interior pointer to a
21874        // layout-identical POD; we copy it out immediately.
21875        unsafe {
21876            *(ffi::whiteout_m3_M3AnimRefVector3f_get_nullValue(self.raw.as_ptr())
21877                as *const crate::math::Vector3f)
21878        }
21879    }
21880
21881    pub fn set_null_value(&mut self, value: crate::math::Vector3f) {
21882        // SAFETY: as above, in the other direction.
21883        unsafe {
21884            ffi::whiteout_m3_M3AnimRefVector3f_set_nullValue(
21885                self.raw.as_ptr(),
21886                &value as *const crate::math::Vector3f as *const _,
21887            )
21888        }
21889    }
21890
21891    /// Typically -1
21892    pub fn unused(&self) -> i32 {
21893        // SAFETY: plain scalar read through a live handle.
21894        unsafe { ffi::whiteout_m3_M3AnimRefVector3f_get_unused(self.raw.as_ptr()) }
21895    }
21896
21897    pub fn set_unused(&mut self, value: i32) {
21898        // SAFETY: plain scalar write through a live handle.
21899        unsafe { ffi::whiteout_m3_M3AnimRefVector3f_set_unused(self.raw.as_ptr(), value) }
21900    }
21901}
21902
21903impl Default for AnimRefVector3f {
21904    fn default() -> Self {
21905        Self::new()
21906    }
21907}
21908
21909/// Animatable reference holding a default value and animation link
21910///
21911/// 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.
21912///
21913/// @tparam T The value type (f32, Vector3f, Quaternion, ColorBGRA, Extent, etc.)
21914pub struct AnimRefM3ColorBGRA {
21915    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3AnimRefM3ColorBGRA>,
21916}
21917
21918impl Drop for AnimRefM3ColorBGRA {
21919    fn drop(&mut self) {
21920        // SAFETY: `raw` came from a native constructor and Drop runs once.
21921        unsafe { ffi::whiteout_m3_M3AnimRefM3ColorBGRA_delete(self.raw.as_ptr()) }
21922    }
21923}
21924
21925impl AnimRefM3ColorBGRA {
21926    /// # Safety
21927    /// `raw` must be a live handle this value takes ownership of.
21928    #[allow(dead_code)] // used by whichever methods return this type
21929    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3AnimRefM3ColorBGRA) -> Option<Self> {
21930        core::ptr::NonNull::new(raw).map(|raw| AnimRefM3ColorBGRA { raw })
21931    }
21932}
21933
21934// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
21935// is deliberately NOT implemented — the C++ types make no documented
21936// guarantee about concurrent use, and claiming one we haven't verified
21937// would be unsound. See `@bind thread_safe` in the plan.
21938unsafe impl Send for AnimRefM3ColorBGRA {}
21939
21940impl core::fmt::Debug for AnimRefM3ColorBGRA {
21941    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
21942        f.debug_struct("AnimRefM3ColorBGRA").finish_non_exhaustive()
21943    }
21944}
21945
21946impl AnimRefM3ColorBGRA {
21947    /// # Panics
21948    /// Panics if the native allocation fails.
21949    pub fn new() -> Self {
21950        // SAFETY: the native constructor returns a live handle; a null here
21951        // means the library is unusable.
21952        unsafe {
21953            let raw = ffi::whiteout_m3_M3AnimRefM3ColorBGRA_new();
21954            Self::from_raw(raw).expect("native AnimRefM3ColorBGRA allocation failed")
21955        }
21956    }
21957
21958    /// Interpolation: 0=none/step, 1=linear, 2=hermite, 3=bezier
21959    pub fn interp_type(&self) -> u16 {
21960        // SAFETY: plain scalar read through a live handle.
21961        unsafe { ffi::whiteout_m3_M3AnimRefM3ColorBGRA_get_interpType(self.raw.as_ptr()) }
21962    }
21963
21964    pub fn set_interp_type(&mut self, value: u16) {
21965        // SAFETY: plain scalar write through a live handle.
21966        unsafe { ffi::whiteout_m3_M3AnimRefM3ColorBGRA_set_interpType(self.raw.as_ptr(), value) }
21967    }
21968
21969    /// Animation flags
21970    pub fn flags(&self) -> u16 {
21971        // SAFETY: plain scalar read through a live handle.
21972        unsafe { ffi::whiteout_m3_M3AnimRefM3ColorBGRA_get_flags(self.raw.as_ptr()) }
21973    }
21974
21975    pub fn set_flags(&mut self, value: u16) {
21976        // SAFETY: plain scalar write through a live handle.
21977        unsafe { ffi::whiteout_m3_M3AnimRefM3ColorBGRA_set_flags(self.raw.as_ptr(), value) }
21978    }
21979
21980    /// Animation identifier (links to STC animation data; 0=not animated)
21981    pub fn anim_id(&self) -> u32 {
21982        // SAFETY: plain scalar read through a live handle.
21983        unsafe { ffi::whiteout_m3_M3AnimRefM3ColorBGRA_get_animId(self.raw.as_ptr()) }
21984    }
21985
21986    pub fn set_anim_id(&mut self, value: u32) {
21987        // SAFETY: plain scalar write through a live handle.
21988        unsafe { ffi::whiteout_m3_M3AnimRefM3ColorBGRA_set_animId(self.raw.as_ptr(), value) }
21989    }
21990
21991    /// Initial/default value (used when not animated)
21992    /// Borrows the field in place — no copy, no allocation.
21993    pub fn init_value(&self) -> crate::support::Ref<'_, ColorBGRA> {
21994        // SAFETY: an interior pointer into `self`, valid for this
21995        // borrow and never freed by the `Ref`.
21996        unsafe {
21997            crate::support::Ref::new(ColorBGRA {
21998                raw: core::ptr::NonNull::new_unchecked(
21999                    ffi::whiteout_m3_M3AnimRefM3ColorBGRA_get_initValue(self.raw.as_ptr()),
22000                ),
22001            })
22002        }
22003    }
22004
22005    pub fn init_value_mut(&mut self) -> crate::support::RefMut<'_, ColorBGRA> {
22006        // SAFETY: as above; `&mut self` guarantees exclusivity.
22007        unsafe {
22008            crate::support::RefMut::new(ColorBGRA {
22009                raw: core::ptr::NonNull::new_unchecked(
22010                    ffi::whiteout_m3_M3AnimRefM3ColorBGRA_get_initValue(self.raw.as_ptr()),
22011                ),
22012            })
22013        }
22014    }
22015
22016    /// Null/reset value
22017    /// Borrows the field in place — no copy, no allocation.
22018    pub fn null_value(&self) -> crate::support::Ref<'_, ColorBGRA> {
22019        // SAFETY: an interior pointer into `self`, valid for this
22020        // borrow and never freed by the `Ref`.
22021        unsafe {
22022            crate::support::Ref::new(ColorBGRA {
22023                raw: core::ptr::NonNull::new_unchecked(
22024                    ffi::whiteout_m3_M3AnimRefM3ColorBGRA_get_nullValue(self.raw.as_ptr()),
22025                ),
22026            })
22027        }
22028    }
22029
22030    pub fn null_value_mut(&mut self) -> crate::support::RefMut<'_, ColorBGRA> {
22031        // SAFETY: as above; `&mut self` guarantees exclusivity.
22032        unsafe {
22033            crate::support::RefMut::new(ColorBGRA {
22034                raw: core::ptr::NonNull::new_unchecked(
22035                    ffi::whiteout_m3_M3AnimRefM3ColorBGRA_get_nullValue(self.raw.as_ptr()),
22036                ),
22037            })
22038        }
22039    }
22040
22041    /// Typically -1
22042    pub fn unused(&self) -> i32 {
22043        // SAFETY: plain scalar read through a live handle.
22044        unsafe { ffi::whiteout_m3_M3AnimRefM3ColorBGRA_get_unused(self.raw.as_ptr()) }
22045    }
22046
22047    pub fn set_unused(&mut self, value: i32) {
22048        // SAFETY: plain scalar write through a live handle.
22049        unsafe { ffi::whiteout_m3_M3AnimRefM3ColorBGRA_set_unused(self.raw.as_ptr(), value) }
22050    }
22051}
22052
22053impl Default for AnimRefM3ColorBGRA {
22054    fn default() -> Self {
22055        Self::new()
22056    }
22057}
22058
22059/// Animatable reference holding a default value and animation link
22060///
22061/// 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.
22062///
22063/// @tparam T The value type (f32, Vector3f, Quaternion, ColorBGRA, Extent, etc.)
22064pub struct AnimRefU16 {
22065    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3AnimRefU16>,
22066}
22067
22068impl Drop for AnimRefU16 {
22069    fn drop(&mut self) {
22070        // SAFETY: `raw` came from a native constructor and Drop runs once.
22071        unsafe { ffi::whiteout_m3_M3AnimRefU16_delete(self.raw.as_ptr()) }
22072    }
22073}
22074
22075impl AnimRefU16 {
22076    /// # Safety
22077    /// `raw` must be a live handle this value takes ownership of.
22078    #[allow(dead_code)] // used by whichever methods return this type
22079    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3AnimRefU16) -> Option<Self> {
22080        core::ptr::NonNull::new(raw).map(|raw| AnimRefU16 { raw })
22081    }
22082}
22083
22084// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
22085// is deliberately NOT implemented — the C++ types make no documented
22086// guarantee about concurrent use, and claiming one we haven't verified
22087// would be unsound. See `@bind thread_safe` in the plan.
22088unsafe impl Send for AnimRefU16 {}
22089
22090impl core::fmt::Debug for AnimRefU16 {
22091    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
22092        f.debug_struct("AnimRefU16").finish_non_exhaustive()
22093    }
22094}
22095
22096impl AnimRefU16 {
22097    /// # Panics
22098    /// Panics if the native allocation fails.
22099    pub fn new() -> Self {
22100        // SAFETY: the native constructor returns a live handle; a null here
22101        // means the library is unusable.
22102        unsafe {
22103            let raw = ffi::whiteout_m3_M3AnimRefU16_new();
22104            Self::from_raw(raw).expect("native AnimRefU16 allocation failed")
22105        }
22106    }
22107
22108    /// Interpolation: 0=none/step, 1=linear, 2=hermite, 3=bezier
22109    pub fn interp_type(&self) -> u16 {
22110        // SAFETY: plain scalar read through a live handle.
22111        unsafe { ffi::whiteout_m3_M3AnimRefU16_get_interpType(self.raw.as_ptr()) }
22112    }
22113
22114    pub fn set_interp_type(&mut self, value: u16) {
22115        // SAFETY: plain scalar write through a live handle.
22116        unsafe { ffi::whiteout_m3_M3AnimRefU16_set_interpType(self.raw.as_ptr(), value) }
22117    }
22118
22119    /// Animation flags
22120    pub fn flags(&self) -> u16 {
22121        // SAFETY: plain scalar read through a live handle.
22122        unsafe { ffi::whiteout_m3_M3AnimRefU16_get_flags(self.raw.as_ptr()) }
22123    }
22124
22125    pub fn set_flags(&mut self, value: u16) {
22126        // SAFETY: plain scalar write through a live handle.
22127        unsafe { ffi::whiteout_m3_M3AnimRefU16_set_flags(self.raw.as_ptr(), value) }
22128    }
22129
22130    /// Animation identifier (links to STC animation data; 0=not animated)
22131    pub fn anim_id(&self) -> u32 {
22132        // SAFETY: plain scalar read through a live handle.
22133        unsafe { ffi::whiteout_m3_M3AnimRefU16_get_animId(self.raw.as_ptr()) }
22134    }
22135
22136    pub fn set_anim_id(&mut self, value: u32) {
22137        // SAFETY: plain scalar write through a live handle.
22138        unsafe { ffi::whiteout_m3_M3AnimRefU16_set_animId(self.raw.as_ptr(), value) }
22139    }
22140
22141    /// Initial/default value (used when not animated)
22142    pub fn init_value(&self) -> u16 {
22143        // SAFETY: plain scalar read through a live handle.
22144        unsafe { ffi::whiteout_m3_M3AnimRefU16_get_initValue(self.raw.as_ptr()) }
22145    }
22146
22147    pub fn set_init_value(&mut self, value: u16) {
22148        // SAFETY: plain scalar write through a live handle.
22149        unsafe { ffi::whiteout_m3_M3AnimRefU16_set_initValue(self.raw.as_ptr(), value) }
22150    }
22151
22152    /// Null/reset value
22153    pub fn null_value(&self) -> u16 {
22154        // SAFETY: plain scalar read through a live handle.
22155        unsafe { ffi::whiteout_m3_M3AnimRefU16_get_nullValue(self.raw.as_ptr()) }
22156    }
22157
22158    pub fn set_null_value(&mut self, value: u16) {
22159        // SAFETY: plain scalar write through a live handle.
22160        unsafe { ffi::whiteout_m3_M3AnimRefU16_set_nullValue(self.raw.as_ptr(), value) }
22161    }
22162
22163    /// Typically -1
22164    pub fn unused(&self) -> i32 {
22165        // SAFETY: plain scalar read through a live handle.
22166        unsafe { ffi::whiteout_m3_M3AnimRefU16_get_unused(self.raw.as_ptr()) }
22167    }
22168
22169    pub fn set_unused(&mut self, value: i32) {
22170        // SAFETY: plain scalar write through a live handle.
22171        unsafe { ffi::whiteout_m3_M3AnimRefU16_set_unused(self.raw.as_ptr(), value) }
22172    }
22173}
22174
22175impl Default for AnimRefU16 {
22176    fn default() -> Self {
22177        Self::new()
22178    }
22179}
22180
22181/// Animatable reference holding a default value and animation link
22182///
22183/// 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.
22184///
22185/// @tparam T The value type (f32, Vector3f, Quaternion, ColorBGRA, Extent, etc.)
22186pub struct AnimRefVector2f {
22187    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3AnimRefVector2f>,
22188}
22189
22190impl Drop for AnimRefVector2f {
22191    fn drop(&mut self) {
22192        // SAFETY: `raw` came from a native constructor and Drop runs once.
22193        unsafe { ffi::whiteout_m3_M3AnimRefVector2f_delete(self.raw.as_ptr()) }
22194    }
22195}
22196
22197impl AnimRefVector2f {
22198    /// # Safety
22199    /// `raw` must be a live handle this value takes ownership of.
22200    #[allow(dead_code)] // used by whichever methods return this type
22201    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3AnimRefVector2f) -> Option<Self> {
22202        core::ptr::NonNull::new(raw).map(|raw| AnimRefVector2f { raw })
22203    }
22204}
22205
22206// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
22207// is deliberately NOT implemented — the C++ types make no documented
22208// guarantee about concurrent use, and claiming one we haven't verified
22209// would be unsound. See `@bind thread_safe` in the plan.
22210unsafe impl Send for AnimRefVector2f {}
22211
22212impl core::fmt::Debug for AnimRefVector2f {
22213    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
22214        f.debug_struct("AnimRefVector2f").finish_non_exhaustive()
22215    }
22216}
22217
22218impl AnimRefVector2f {
22219    /// # Panics
22220    /// Panics if the native allocation fails.
22221    pub fn new() -> Self {
22222        // SAFETY: the native constructor returns a live handle; a null here
22223        // means the library is unusable.
22224        unsafe {
22225            let raw = ffi::whiteout_m3_M3AnimRefVector2f_new();
22226            Self::from_raw(raw).expect("native AnimRefVector2f allocation failed")
22227        }
22228    }
22229
22230    /// Interpolation: 0=none/step, 1=linear, 2=hermite, 3=bezier
22231    pub fn interp_type(&self) -> u16 {
22232        // SAFETY: plain scalar read through a live handle.
22233        unsafe { ffi::whiteout_m3_M3AnimRefVector2f_get_interpType(self.raw.as_ptr()) }
22234    }
22235
22236    pub fn set_interp_type(&mut self, value: u16) {
22237        // SAFETY: plain scalar write through a live handle.
22238        unsafe { ffi::whiteout_m3_M3AnimRefVector2f_set_interpType(self.raw.as_ptr(), value) }
22239    }
22240
22241    /// Animation flags
22242    pub fn flags(&self) -> u16 {
22243        // SAFETY: plain scalar read through a live handle.
22244        unsafe { ffi::whiteout_m3_M3AnimRefVector2f_get_flags(self.raw.as_ptr()) }
22245    }
22246
22247    pub fn set_flags(&mut self, value: u16) {
22248        // SAFETY: plain scalar write through a live handle.
22249        unsafe { ffi::whiteout_m3_M3AnimRefVector2f_set_flags(self.raw.as_ptr(), value) }
22250    }
22251
22252    /// Animation identifier (links to STC animation data; 0=not animated)
22253    pub fn anim_id(&self) -> u32 {
22254        // SAFETY: plain scalar read through a live handle.
22255        unsafe { ffi::whiteout_m3_M3AnimRefVector2f_get_animId(self.raw.as_ptr()) }
22256    }
22257
22258    pub fn set_anim_id(&mut self, value: u32) {
22259        // SAFETY: plain scalar write through a live handle.
22260        unsafe { ffi::whiteout_m3_M3AnimRefVector2f_set_animId(self.raw.as_ptr(), value) }
22261    }
22262
22263    /// Initial/default value (used when not animated)
22264    pub fn init_value(&self) -> crate::math::Vector2f {
22265        // SAFETY: the getter returns an interior pointer to a
22266        // layout-identical POD; we copy it out immediately.
22267        unsafe {
22268            *(ffi::whiteout_m3_M3AnimRefVector2f_get_initValue(self.raw.as_ptr())
22269                as *const crate::math::Vector2f)
22270        }
22271    }
22272
22273    pub fn set_init_value(&mut self, value: crate::math::Vector2f) {
22274        // SAFETY: as above, in the other direction.
22275        unsafe {
22276            ffi::whiteout_m3_M3AnimRefVector2f_set_initValue(
22277                self.raw.as_ptr(),
22278                &value as *const crate::math::Vector2f as *const _,
22279            )
22280        }
22281    }
22282
22283    /// Null/reset value
22284    pub fn null_value(&self) -> crate::math::Vector2f {
22285        // SAFETY: the getter returns an interior pointer to a
22286        // layout-identical POD; we copy it out immediately.
22287        unsafe {
22288            *(ffi::whiteout_m3_M3AnimRefVector2f_get_nullValue(self.raw.as_ptr())
22289                as *const crate::math::Vector2f)
22290        }
22291    }
22292
22293    pub fn set_null_value(&mut self, value: crate::math::Vector2f) {
22294        // SAFETY: as above, in the other direction.
22295        unsafe {
22296            ffi::whiteout_m3_M3AnimRefVector2f_set_nullValue(
22297                self.raw.as_ptr(),
22298                &value as *const crate::math::Vector2f as *const _,
22299            )
22300        }
22301    }
22302
22303    /// Typically -1
22304    pub fn unused(&self) -> i32 {
22305        // SAFETY: plain scalar read through a live handle.
22306        unsafe { ffi::whiteout_m3_M3AnimRefVector2f_get_unused(self.raw.as_ptr()) }
22307    }
22308
22309    pub fn set_unused(&mut self, value: i32) {
22310        // SAFETY: plain scalar write through a live handle.
22311        unsafe { ffi::whiteout_m3_M3AnimRefVector2f_set_unused(self.raw.as_ptr(), value) }
22312    }
22313}
22314
22315impl Default for AnimRefVector2f {
22316    fn default() -> Self {
22317        Self::new()
22318    }
22319}
22320
22321/// Animatable reference holding a default value and animation link
22322///
22323/// 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.
22324///
22325/// @tparam T The value type (f32, Vector3f, Quaternion, ColorBGRA, Extent, etc.)
22326pub struct AnimRefU32 {
22327    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3AnimRefU32>,
22328}
22329
22330impl Drop for AnimRefU32 {
22331    fn drop(&mut self) {
22332        // SAFETY: `raw` came from a native constructor and Drop runs once.
22333        unsafe { ffi::whiteout_m3_M3AnimRefU32_delete(self.raw.as_ptr()) }
22334    }
22335}
22336
22337impl AnimRefU32 {
22338    /// # Safety
22339    /// `raw` must be a live handle this value takes ownership of.
22340    #[allow(dead_code)] // used by whichever methods return this type
22341    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3AnimRefU32) -> Option<Self> {
22342        core::ptr::NonNull::new(raw).map(|raw| AnimRefU32 { raw })
22343    }
22344}
22345
22346// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
22347// is deliberately NOT implemented — the C++ types make no documented
22348// guarantee about concurrent use, and claiming one we haven't verified
22349// would be unsound. See `@bind thread_safe` in the plan.
22350unsafe impl Send for AnimRefU32 {}
22351
22352impl core::fmt::Debug for AnimRefU32 {
22353    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
22354        f.debug_struct("AnimRefU32").finish_non_exhaustive()
22355    }
22356}
22357
22358impl AnimRefU32 {
22359    /// # Panics
22360    /// Panics if the native allocation fails.
22361    pub fn new() -> Self {
22362        // SAFETY: the native constructor returns a live handle; a null here
22363        // means the library is unusable.
22364        unsafe {
22365            let raw = ffi::whiteout_m3_M3AnimRefU32_new();
22366            Self::from_raw(raw).expect("native AnimRefU32 allocation failed")
22367        }
22368    }
22369
22370    /// Interpolation: 0=none/step, 1=linear, 2=hermite, 3=bezier
22371    pub fn interp_type(&self) -> u16 {
22372        // SAFETY: plain scalar read through a live handle.
22373        unsafe { ffi::whiteout_m3_M3AnimRefU32_get_interpType(self.raw.as_ptr()) }
22374    }
22375
22376    pub fn set_interp_type(&mut self, value: u16) {
22377        // SAFETY: plain scalar write through a live handle.
22378        unsafe { ffi::whiteout_m3_M3AnimRefU32_set_interpType(self.raw.as_ptr(), value) }
22379    }
22380
22381    /// Animation flags
22382    pub fn flags(&self) -> u16 {
22383        // SAFETY: plain scalar read through a live handle.
22384        unsafe { ffi::whiteout_m3_M3AnimRefU32_get_flags(self.raw.as_ptr()) }
22385    }
22386
22387    pub fn set_flags(&mut self, value: u16) {
22388        // SAFETY: plain scalar write through a live handle.
22389        unsafe { ffi::whiteout_m3_M3AnimRefU32_set_flags(self.raw.as_ptr(), value) }
22390    }
22391
22392    /// Animation identifier (links to STC animation data; 0=not animated)
22393    pub fn anim_id(&self) -> u32 {
22394        // SAFETY: plain scalar read through a live handle.
22395        unsafe { ffi::whiteout_m3_M3AnimRefU32_get_animId(self.raw.as_ptr()) }
22396    }
22397
22398    pub fn set_anim_id(&mut self, value: u32) {
22399        // SAFETY: plain scalar write through a live handle.
22400        unsafe { ffi::whiteout_m3_M3AnimRefU32_set_animId(self.raw.as_ptr(), value) }
22401    }
22402
22403    /// Initial/default value (used when not animated)
22404    pub fn init_value(&self) -> u32 {
22405        // SAFETY: plain scalar read through a live handle.
22406        unsafe { ffi::whiteout_m3_M3AnimRefU32_get_initValue(self.raw.as_ptr()) }
22407    }
22408
22409    pub fn set_init_value(&mut self, value: u32) {
22410        // SAFETY: plain scalar write through a live handle.
22411        unsafe { ffi::whiteout_m3_M3AnimRefU32_set_initValue(self.raw.as_ptr(), value) }
22412    }
22413
22414    /// Null/reset value
22415    pub fn null_value(&self) -> u32 {
22416        // SAFETY: plain scalar read through a live handle.
22417        unsafe { ffi::whiteout_m3_M3AnimRefU32_get_nullValue(self.raw.as_ptr()) }
22418    }
22419
22420    pub fn set_null_value(&mut self, value: u32) {
22421        // SAFETY: plain scalar write through a live handle.
22422        unsafe { ffi::whiteout_m3_M3AnimRefU32_set_nullValue(self.raw.as_ptr(), value) }
22423    }
22424
22425    /// Typically -1
22426    pub fn unused(&self) -> i32 {
22427        // SAFETY: plain scalar read through a live handle.
22428        unsafe { ffi::whiteout_m3_M3AnimRefU32_get_unused(self.raw.as_ptr()) }
22429    }
22430
22431    pub fn set_unused(&mut self, value: i32) {
22432        // SAFETY: plain scalar write through a live handle.
22433        unsafe { ffi::whiteout_m3_M3AnimRefU32_set_unused(self.raw.as_ptr(), value) }
22434    }
22435}
22436
22437impl Default for AnimRefU32 {
22438    fn default() -> Self {
22439        Self::new()
22440    }
22441}
22442
22443/// Animatable reference holding a default value and animation link
22444///
22445/// 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.
22446///
22447/// @tparam T The value type (f32, Vector3f, Quaternion, ColorBGRA, Extent, etc.)
22448pub struct AnimRefQuaternion {
22449    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3AnimRefQuaternion>,
22450}
22451
22452impl Drop for AnimRefQuaternion {
22453    fn drop(&mut self) {
22454        // SAFETY: `raw` came from a native constructor and Drop runs once.
22455        unsafe { ffi::whiteout_m3_M3AnimRefQuaternion_delete(self.raw.as_ptr()) }
22456    }
22457}
22458
22459impl AnimRefQuaternion {
22460    /// # Safety
22461    /// `raw` must be a live handle this value takes ownership of.
22462    #[allow(dead_code)] // used by whichever methods return this type
22463    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3AnimRefQuaternion) -> Option<Self> {
22464        core::ptr::NonNull::new(raw).map(|raw| AnimRefQuaternion { raw })
22465    }
22466}
22467
22468// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
22469// is deliberately NOT implemented — the C++ types make no documented
22470// guarantee about concurrent use, and claiming one we haven't verified
22471// would be unsound. See `@bind thread_safe` in the plan.
22472unsafe impl Send for AnimRefQuaternion {}
22473
22474impl core::fmt::Debug for AnimRefQuaternion {
22475    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
22476        f.debug_struct("AnimRefQuaternion").finish_non_exhaustive()
22477    }
22478}
22479
22480impl AnimRefQuaternion {
22481    /// # Panics
22482    /// Panics if the native allocation fails.
22483    pub fn new() -> Self {
22484        // SAFETY: the native constructor returns a live handle; a null here
22485        // means the library is unusable.
22486        unsafe {
22487            let raw = ffi::whiteout_m3_M3AnimRefQuaternion_new();
22488            Self::from_raw(raw).expect("native AnimRefQuaternion allocation failed")
22489        }
22490    }
22491
22492    /// Interpolation: 0=none/step, 1=linear, 2=hermite, 3=bezier
22493    pub fn interp_type(&self) -> u16 {
22494        // SAFETY: plain scalar read through a live handle.
22495        unsafe { ffi::whiteout_m3_M3AnimRefQuaternion_get_interpType(self.raw.as_ptr()) }
22496    }
22497
22498    pub fn set_interp_type(&mut self, value: u16) {
22499        // SAFETY: plain scalar write through a live handle.
22500        unsafe { ffi::whiteout_m3_M3AnimRefQuaternion_set_interpType(self.raw.as_ptr(), value) }
22501    }
22502
22503    /// Animation flags
22504    pub fn flags(&self) -> u16 {
22505        // SAFETY: plain scalar read through a live handle.
22506        unsafe { ffi::whiteout_m3_M3AnimRefQuaternion_get_flags(self.raw.as_ptr()) }
22507    }
22508
22509    pub fn set_flags(&mut self, value: u16) {
22510        // SAFETY: plain scalar write through a live handle.
22511        unsafe { ffi::whiteout_m3_M3AnimRefQuaternion_set_flags(self.raw.as_ptr(), value) }
22512    }
22513
22514    /// Animation identifier (links to STC animation data; 0=not animated)
22515    pub fn anim_id(&self) -> u32 {
22516        // SAFETY: plain scalar read through a live handle.
22517        unsafe { ffi::whiteout_m3_M3AnimRefQuaternion_get_animId(self.raw.as_ptr()) }
22518    }
22519
22520    pub fn set_anim_id(&mut self, value: u32) {
22521        // SAFETY: plain scalar write through a live handle.
22522        unsafe { ffi::whiteout_m3_M3AnimRefQuaternion_set_animId(self.raw.as_ptr(), value) }
22523    }
22524
22525    /// Initial/default value (used when not animated)
22526    pub fn init_value(&self) -> crate::math::Quaternion {
22527        // SAFETY: the getter returns an interior pointer to a
22528        // layout-identical POD; we copy it out immediately.
22529        unsafe {
22530            *(ffi::whiteout_m3_M3AnimRefQuaternion_get_initValue(self.raw.as_ptr())
22531                as *const crate::math::Quaternion)
22532        }
22533    }
22534
22535    pub fn set_init_value(&mut self, value: crate::math::Quaternion) {
22536        // SAFETY: as above, in the other direction.
22537        unsafe {
22538            ffi::whiteout_m3_M3AnimRefQuaternion_set_initValue(
22539                self.raw.as_ptr(),
22540                &value as *const crate::math::Quaternion as *const _,
22541            )
22542        }
22543    }
22544
22545    /// Null/reset value
22546    pub fn null_value(&self) -> crate::math::Quaternion {
22547        // SAFETY: the getter returns an interior pointer to a
22548        // layout-identical POD; we copy it out immediately.
22549        unsafe {
22550            *(ffi::whiteout_m3_M3AnimRefQuaternion_get_nullValue(self.raw.as_ptr())
22551                as *const crate::math::Quaternion)
22552        }
22553    }
22554
22555    pub fn set_null_value(&mut self, value: crate::math::Quaternion) {
22556        // SAFETY: as above, in the other direction.
22557        unsafe {
22558            ffi::whiteout_m3_M3AnimRefQuaternion_set_nullValue(
22559                self.raw.as_ptr(),
22560                &value as *const crate::math::Quaternion as *const _,
22561            )
22562        }
22563    }
22564
22565    /// Typically -1
22566    pub fn unused(&self) -> i32 {
22567        // SAFETY: plain scalar read through a live handle.
22568        unsafe { ffi::whiteout_m3_M3AnimRefQuaternion_get_unused(self.raw.as_ptr()) }
22569    }
22570
22571    pub fn set_unused(&mut self, value: i32) {
22572        // SAFETY: plain scalar write through a live handle.
22573        unsafe { ffi::whiteout_m3_M3AnimRefQuaternion_set_unused(self.raw.as_ptr(), value) }
22574    }
22575}
22576
22577impl Default for AnimRefQuaternion {
22578    fn default() -> Self {
22579        Self::new()
22580    }
22581}
22582
22583/// Animatable reference holding a default value and animation link
22584///
22585/// 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.
22586///
22587/// @tparam T The value type (f32, Vector3f, Quaternion, ColorBGRA, Extent, etc.)
22588pub struct AnimRefM3Extent {
22589    pub(crate) raw: core::ptr::NonNull<ffi::whiteout_M3AnimRefM3Extent>,
22590}
22591
22592impl Drop for AnimRefM3Extent {
22593    fn drop(&mut self) {
22594        // SAFETY: `raw` came from a native constructor and Drop runs once.
22595        unsafe { ffi::whiteout_m3_M3AnimRefM3Extent_delete(self.raw.as_ptr()) }
22596    }
22597}
22598
22599impl AnimRefM3Extent {
22600    /// # Safety
22601    /// `raw` must be a live handle this value takes ownership of.
22602    #[allow(dead_code)] // used by whichever methods return this type
22603    pub(crate) unsafe fn from_raw(raw: *mut ffi::whiteout_M3AnimRefM3Extent) -> Option<Self> {
22604        core::ptr::NonNull::new(raw).map(|raw| AnimRefM3Extent { raw })
22605    }
22606}
22607
22608// SAFETY: handles are plain heap pointers with no thread affinity. `Sync`
22609// is deliberately NOT implemented — the C++ types make no documented
22610// guarantee about concurrent use, and claiming one we haven't verified
22611// would be unsound. See `@bind thread_safe` in the plan.
22612unsafe impl Send for AnimRefM3Extent {}
22613
22614impl core::fmt::Debug for AnimRefM3Extent {
22615    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
22616        f.debug_struct("AnimRefM3Extent").finish_non_exhaustive()
22617    }
22618}
22619
22620impl AnimRefM3Extent {
22621    /// # Panics
22622    /// Panics if the native allocation fails.
22623    pub fn new() -> Self {
22624        // SAFETY: the native constructor returns a live handle; a null here
22625        // means the library is unusable.
22626        unsafe {
22627            let raw = ffi::whiteout_m3_M3AnimRefM3Extent_new();
22628            Self::from_raw(raw).expect("native AnimRefM3Extent allocation failed")
22629        }
22630    }
22631
22632    /// Interpolation: 0=none/step, 1=linear, 2=hermite, 3=bezier
22633    pub fn interp_type(&self) -> u16 {
22634        // SAFETY: plain scalar read through a live handle.
22635        unsafe { ffi::whiteout_m3_M3AnimRefM3Extent_get_interpType(self.raw.as_ptr()) }
22636    }
22637
22638    pub fn set_interp_type(&mut self, value: u16) {
22639        // SAFETY: plain scalar write through a live handle.
22640        unsafe { ffi::whiteout_m3_M3AnimRefM3Extent_set_interpType(self.raw.as_ptr(), value) }
22641    }
22642
22643    /// Animation flags
22644    pub fn flags(&self) -> u16 {
22645        // SAFETY: plain scalar read through a live handle.
22646        unsafe { ffi::whiteout_m3_M3AnimRefM3Extent_get_flags(self.raw.as_ptr()) }
22647    }
22648
22649    pub fn set_flags(&mut self, value: u16) {
22650        // SAFETY: plain scalar write through a live handle.
22651        unsafe { ffi::whiteout_m3_M3AnimRefM3Extent_set_flags(self.raw.as_ptr(), value) }
22652    }
22653
22654    /// Animation identifier (links to STC animation data; 0=not animated)
22655    pub fn anim_id(&self) -> u32 {
22656        // SAFETY: plain scalar read through a live handle.
22657        unsafe { ffi::whiteout_m3_M3AnimRefM3Extent_get_animId(self.raw.as_ptr()) }
22658    }
22659
22660    pub fn set_anim_id(&mut self, value: u32) {
22661        // SAFETY: plain scalar write through a live handle.
22662        unsafe { ffi::whiteout_m3_M3AnimRefM3Extent_set_animId(self.raw.as_ptr(), value) }
22663    }
22664
22665    /// Initial/default value (used when not animated)
22666    /// Borrows the field in place — no copy, no allocation.
22667    pub fn init_value(&self) -> crate::support::Ref<'_, Extent> {
22668        // SAFETY: an interior pointer into `self`, valid for this
22669        // borrow and never freed by the `Ref`.
22670        unsafe {
22671            crate::support::Ref::new(Extent {
22672                raw: core::ptr::NonNull::new_unchecked(
22673                    ffi::whiteout_m3_M3AnimRefM3Extent_get_initValue(self.raw.as_ptr()),
22674                ),
22675            })
22676        }
22677    }
22678
22679    pub fn init_value_mut(&mut self) -> crate::support::RefMut<'_, Extent> {
22680        // SAFETY: as above; `&mut self` guarantees exclusivity.
22681        unsafe {
22682            crate::support::RefMut::new(Extent {
22683                raw: core::ptr::NonNull::new_unchecked(
22684                    ffi::whiteout_m3_M3AnimRefM3Extent_get_initValue(self.raw.as_ptr()),
22685                ),
22686            })
22687        }
22688    }
22689
22690    /// Null/reset value
22691    /// Borrows the field in place — no copy, no allocation.
22692    pub fn null_value(&self) -> crate::support::Ref<'_, Extent> {
22693        // SAFETY: an interior pointer into `self`, valid for this
22694        // borrow and never freed by the `Ref`.
22695        unsafe {
22696            crate::support::Ref::new(Extent {
22697                raw: core::ptr::NonNull::new_unchecked(
22698                    ffi::whiteout_m3_M3AnimRefM3Extent_get_nullValue(self.raw.as_ptr()),
22699                ),
22700            })
22701        }
22702    }
22703
22704    pub fn null_value_mut(&mut self) -> crate::support::RefMut<'_, Extent> {
22705        // SAFETY: as above; `&mut self` guarantees exclusivity.
22706        unsafe {
22707            crate::support::RefMut::new(Extent {
22708                raw: core::ptr::NonNull::new_unchecked(
22709                    ffi::whiteout_m3_M3AnimRefM3Extent_get_nullValue(self.raw.as_ptr()),
22710                ),
22711            })
22712        }
22713    }
22714
22715    /// Typically -1
22716    pub fn unused(&self) -> i32 {
22717        // SAFETY: plain scalar read through a live handle.
22718        unsafe { ffi::whiteout_m3_M3AnimRefM3Extent_get_unused(self.raw.as_ptr()) }
22719    }
22720
22721    pub fn set_unused(&mut self, value: i32) {
22722        // SAFETY: plain scalar write through a live handle.
22723        unsafe { ffi::whiteout_m3_M3AnimRefM3Extent_set_unused(self.raw.as_ptr(), value) }
22724    }
22725}
22726
22727impl Default for AnimRefM3Extent {
22728    fn default() -> Self {
22729        Self::new()
22730    }
22731}
22732
22733#[doc(hidden)]
22734pub mod ffi {
22735    #![allow(missing_debug_implementations)]
22736
22737    #[allow(unused_imports)]
22738    use crate::support::{RawBytes, RawCString};
22739
22740    #[repr(C)]
22741    pub struct whiteout_M3ColorBGRA {
22742        _private: [u8; 0],
22743    }
22744    #[repr(C)]
22745    pub struct whiteout_M3ColorBGR {
22746        _private: [u8; 0],
22747    }
22748    #[repr(C)]
22749    pub struct whiteout_M3Extent {
22750        _private: [u8; 0],
22751    }
22752    #[repr(C)]
22753    pub struct whiteout_M3Event {
22754        _private: [u8; 0],
22755    }
22756    #[repr(C)]
22757    pub struct whiteout_M3Sequence {
22758        _private: [u8; 0],
22759    }
22760    #[repr(C)]
22761    pub struct whiteout_M3SubTrackContainer {
22762        _private: [u8; 0],
22763    }
22764    #[repr(C)]
22765    pub struct whiteout_M3AnimationGroup {
22766        _private: [u8; 0],
22767    }
22768    #[repr(C)]
22769    pub struct whiteout_M3AnimationState {
22770        _private: [u8; 0],
22771    }
22772    #[repr(C)]
22773    pub struct whiteout_M3BoneAnimationSet {
22774        _private: [u8; 0],
22775    }
22776    #[repr(C)]
22777    pub struct whiteout_M3ParticleEmitter {
22778        _private: [u8; 0],
22779    }
22780    #[repr(C)]
22781    pub struct whiteout_M3ParticleEmitterCopy {
22782        _private: [u8; 0],
22783    }
22784    #[repr(C)]
22785    pub struct whiteout_M3SplineRibbon {
22786        _private: [u8; 0],
22787    }
22788    #[repr(C)]
22789    pub struct whiteout_M3RibbonEmitter {
22790        _private: [u8; 0],
22791    }
22792    #[repr(C)]
22793    pub struct whiteout_M3Projector {
22794        _private: [u8; 0],
22795    }
22796    #[repr(C)]
22797    pub struct whiteout_M3MaterialMap {
22798        _private: [u8; 0],
22799    }
22800    #[repr(C)]
22801    pub struct whiteout_M3TextureLayer {
22802        _private: [u8; 0],
22803    }
22804    #[repr(C)]
22805    pub struct whiteout_M3StandardMaterial {
22806        _private: [u8; 0],
22807    }
22808    #[repr(C)]
22809    pub struct whiteout_M3DisplacementMaterial {
22810        _private: [u8; 0],
22811    }
22812    #[repr(C)]
22813    pub struct whiteout_M3CompositeSection {
22814        _private: [u8; 0],
22815    }
22816    #[repr(C)]
22817    pub struct whiteout_M3CompositeMaterial {
22818        _private: [u8; 0],
22819    }
22820    #[repr(C)]
22821    pub struct whiteout_M3TerrainMaterial {
22822        _private: [u8; 0],
22823    }
22824    #[repr(C)]
22825    pub struct whiteout_M3VolumeMaterial {
22826        _private: [u8; 0],
22827    }
22828    #[repr(C)]
22829    pub struct whiteout_M3HairMaterial {
22830        _private: [u8; 0],
22831    }
22832    #[repr(C)]
22833    pub struct whiteout_M3VolumeNoiseMaterial {
22834        _private: [u8; 0],
22835    }
22836    #[repr(C)]
22837    pub struct whiteout_M3CreepMaterial {
22838        _private: [u8; 0],
22839    }
22840    #[repr(C)]
22841    pub struct whiteout_M3STBMaterial {
22842        _private: [u8; 0],
22843    }
22844    #[repr(C)]
22845    pub struct whiteout_M3ReflectionMaterial {
22846        _private: [u8; 0],
22847    }
22848    #[repr(C)]
22849    pub struct whiteout_M3SubFlare {
22850        _private: [u8; 0],
22851    }
22852    #[repr(C)]
22853    pub struct whiteout_M3LensFlare {
22854        _private: [u8; 0],
22855    }
22856    #[repr(C)]
22857    pub struct whiteout_M3MaterialAddData {
22858        _private: [u8; 0],
22859    }
22860    #[repr(C)]
22861    pub struct whiteout_M3Bone {
22862        _private: [u8; 0],
22863    }
22864    #[repr(C)]
22865    pub struct whiteout_M3Region {
22866        _private: [u8; 0],
22867    }
22868    #[repr(C)]
22869    pub struct whiteout_M3Batch {
22870        _private: [u8; 0],
22871    }
22872    #[repr(C)]
22873    pub struct whiteout_M3MeshSection {
22874        _private: [u8; 0],
22875    }
22876    #[repr(C)]
22877    pub struct whiteout_M3MeshDivision {
22878        _private: [u8; 0],
22879    }
22880    #[repr(C)]
22881    pub struct whiteout_M3InitialReference {
22882        _private: [u8; 0],
22883    }
22884    #[repr(C)]
22885    pub struct whiteout_M3AttachmentPoint {
22886        _private: [u8; 0],
22887    }
22888    #[repr(C)]
22889    pub struct whiteout_M3HitTestShape {
22890        _private: [u8; 0],
22891    }
22892    #[repr(C)]
22893    pub struct whiteout_M3AttachmentVolume {
22894        _private: [u8; 0],
22895    }
22896    #[repr(C)]
22897    pub struct whiteout_M3TriggerData {
22898        _private: [u8; 0],
22899    }
22900    #[repr(C)]
22901    pub struct whiteout_M3TurretBehavior {
22902        _private: [u8; 0],
22903    }
22904    #[repr(C)]
22905    pub struct whiteout_M3BillboardBehavior {
22906        _private: [u8; 0],
22907    }
22908    #[repr(C)]
22909    pub struct whiteout_M3IKJoint {
22910        _private: [u8; 0],
22911    }
22912    #[repr(C)]
22913    pub struct whiteout_M3IKTwoJoint {
22914        _private: [u8; 0],
22915    }
22916    #[repr(C)]
22917    pub struct whiteout_M3IKCCD {
22918        _private: [u8; 0],
22919    }
22920    #[repr(C)]
22921    pub struct whiteout_M3OneBoneSolver {
22922        _private: [u8; 0],
22923    }
22924    #[repr(C)]
22925    pub struct whiteout_M3ShadowBox {
22926        _private: [u8; 0],
22927    }
22928    #[repr(C)]
22929    pub struct whiteout_M3ViewVolume {
22930        _private: [u8; 0],
22931    }
22932    #[repr(C)]
22933    pub struct whiteout_M3TrailingModel {
22934        _private: [u8; 0],
22935    }
22936    #[repr(C)]
22937    pub struct whiteout_M3Force {
22938        _private: [u8; 0],
22939    }
22940    #[repr(C)]
22941    pub struct whiteout_M3Warp {
22942        _private: [u8; 0],
22943    }
22944    #[repr(C)]
22945    pub struct whiteout_M3ConvexHullHalfEdge {
22946        _private: [u8; 0],
22947    }
22948    #[repr(C)]
22949    pub struct whiteout_M3PhysicsMeshBvhNode {
22950        _private: [u8; 0],
22951    }
22952    #[repr(C)]
22953    pub struct whiteout_M3PhysicsMeshTriangle {
22954        _private: [u8; 0],
22955    }
22956    #[repr(C)]
22957    pub struct whiteout_M3PhysicsMeshEdge {
22958        _private: [u8; 0],
22959    }
22960    #[repr(C)]
22961    pub struct whiteout_M3PhysicsShape {
22962        _private: [u8; 0],
22963    }
22964    #[repr(C)]
22965    pub struct whiteout_M3RigidBody {
22966        _private: [u8; 0],
22967    }
22968    #[repr(C)]
22969    pub struct whiteout_M3PhysicsJoint {
22970        _private: [u8; 0],
22971    }
22972    #[repr(C)]
22973    pub struct whiteout_M3PhysicsConstraint {
22974        _private: [u8; 0],
22975    }
22976    #[repr(C)]
22977    pub struct whiteout_M3ClothCollider {
22978        _private: [u8; 0],
22979    }
22980    #[repr(C)]
22981    pub struct whiteout_M3ClothProxy {
22982        _private: [u8; 0],
22983    }
22984    #[repr(C)]
22985    pub struct whiteout_M3ClothPhysics {
22986        _private: [u8; 0],
22987    }
22988    #[repr(C)]
22989    pub struct whiteout_M3Light {
22990        _private: [u8; 0],
22991    }
22992    #[repr(C)]
22993    pub struct whiteout_M3Camera {
22994        _private: [u8; 0],
22995    }
22996    #[repr(C)]
22997    pub struct whiteout_M3Model {
22998        _private: [u8; 0],
22999    }
23000    #[repr(C)]
23001    pub struct whiteout_M3Parser {
23002        _private: [u8; 0],
23003    }
23004    #[repr(C)]
23005    pub struct whiteout_M3Writer {
23006        _private: [u8; 0],
23007    }
23008    #[repr(C)]
23009    pub struct whiteout_M3AnimRefF32 {
23010        _private: [u8; 0],
23011    }
23012    #[repr(C)]
23013    pub struct whiteout_M3AnimRefVector3f {
23014        _private: [u8; 0],
23015    }
23016    #[repr(C)]
23017    pub struct whiteout_M3AnimRefM3ColorBGRA {
23018        _private: [u8; 0],
23019    }
23020    #[repr(C)]
23021    pub struct whiteout_M3AnimRefU16 {
23022        _private: [u8; 0],
23023    }
23024    #[repr(C)]
23025    pub struct whiteout_M3AnimRefVector2f {
23026        _private: [u8; 0],
23027    }
23028    #[repr(C)]
23029    pub struct whiteout_M3AnimRefU32 {
23030        _private: [u8; 0],
23031    }
23032    #[repr(C)]
23033    pub struct whiteout_M3AnimRefQuaternion {
23034        _private: [u8; 0],
23035    }
23036    #[repr(C)]
23037    pub struct whiteout_M3AnimRefM3Extent {
23038        _private: [u8; 0],
23039    }
23040
23041    extern "C" {
23042        // ColorBGRA
23043        pub fn whiteout_m3_M3ColorBGRA_new() -> *mut whiteout_M3ColorBGRA;
23044        pub fn whiteout_m3_M3ColorBGRA_delete(self_: *mut whiteout_M3ColorBGRA);
23045        pub fn whiteout_m3_M3ColorBGRA_get_b(self_: *mut whiteout_M3ColorBGRA) -> u8;
23046        pub fn whiteout_m3_M3ColorBGRA_set_b(self_: *mut whiteout_M3ColorBGRA, value: u8);
23047        pub fn whiteout_m3_M3ColorBGRA_get_g(self_: *mut whiteout_M3ColorBGRA) -> u8;
23048        pub fn whiteout_m3_M3ColorBGRA_set_g(self_: *mut whiteout_M3ColorBGRA, value: u8);
23049        pub fn whiteout_m3_M3ColorBGRA_get_r(self_: *mut whiteout_M3ColorBGRA) -> u8;
23050        pub fn whiteout_m3_M3ColorBGRA_set_r(self_: *mut whiteout_M3ColorBGRA, value: u8);
23051        pub fn whiteout_m3_M3ColorBGRA_get_a(self_: *mut whiteout_M3ColorBGRA) -> u8;
23052        pub fn whiteout_m3_M3ColorBGRA_set_a(self_: *mut whiteout_M3ColorBGRA, value: u8);
23053        // ColorBGR
23054        pub fn whiteout_m3_M3ColorBGR_new() -> *mut whiteout_M3ColorBGR;
23055        pub fn whiteout_m3_M3ColorBGR_delete(self_: *mut whiteout_M3ColorBGR);
23056        pub fn whiteout_m3_M3ColorBGR_get_b(self_: *mut whiteout_M3ColorBGR) -> u8;
23057        pub fn whiteout_m3_M3ColorBGR_set_b(self_: *mut whiteout_M3ColorBGR, value: u8);
23058        pub fn whiteout_m3_M3ColorBGR_get_g(self_: *mut whiteout_M3ColorBGR) -> u8;
23059        pub fn whiteout_m3_M3ColorBGR_set_g(self_: *mut whiteout_M3ColorBGR, value: u8);
23060        pub fn whiteout_m3_M3ColorBGR_get_r(self_: *mut whiteout_M3ColorBGR) -> u8;
23061        pub fn whiteout_m3_M3ColorBGR_set_r(self_: *mut whiteout_M3ColorBGR, value: u8);
23062        // Extent
23063        pub fn whiteout_m3_M3Extent_new() -> *mut whiteout_M3Extent;
23064        pub fn whiteout_m3_M3Extent_delete(self_: *mut whiteout_M3Extent);
23065        pub fn whiteout_m3_M3Extent_get_min(
23066            self_: *mut whiteout_M3Extent,
23067        ) -> *mut core::ffi::c_void;
23068        pub fn whiteout_m3_M3Extent_set_min(
23069            self_: *mut whiteout_M3Extent,
23070            value: *const core::ffi::c_void,
23071        );
23072        pub fn whiteout_m3_M3Extent_get_max(
23073            self_: *mut whiteout_M3Extent,
23074        ) -> *mut core::ffi::c_void;
23075        pub fn whiteout_m3_M3Extent_set_max(
23076            self_: *mut whiteout_M3Extent,
23077            value: *const core::ffi::c_void,
23078        );
23079        pub fn whiteout_m3_M3Extent_get_radius(self_: *mut whiteout_M3Extent) -> f32;
23080        pub fn whiteout_m3_M3Extent_set_radius(self_: *mut whiteout_M3Extent, value: f32);
23081        // Event
23082        pub fn whiteout_m3_M3Event_new() -> *mut whiteout_M3Event;
23083        pub fn whiteout_m3_M3Event_delete(self_: *mut whiteout_M3Event);
23084        pub fn whiteout_m3_M3Event_get_name(self_: *mut whiteout_M3Event) -> RawCString;
23085        pub fn whiteout_m3_M3Event_set_name(
23086            self_: *mut whiteout_M3Event,
23087            value: *const core::ffi::c_char,
23088        );
23089        pub fn whiteout_m3_M3Event_get_unknown(self_: *mut whiteout_M3Event) -> u32;
23090        pub fn whiteout_m3_M3Event_set_unknown(self_: *mut whiteout_M3Event, value: u32);
23091        pub fn whiteout_m3_M3Event_get_boneIndex(self_: *mut whiteout_M3Event) -> u16;
23092        pub fn whiteout_m3_M3Event_set_boneIndex(self_: *mut whiteout_M3Event, value: u16);
23093        pub fn whiteout_m3_M3Event_get_padding(self_: *mut whiteout_M3Event) -> u16;
23094        pub fn whiteout_m3_M3Event_set_padding(self_: *mut whiteout_M3Event, value: u16);
23095        pub fn whiteout_m3_M3Event_get_eventType(self_: *mut whiteout_M3Event) -> u32;
23096        pub fn whiteout_m3_M3Event_set_eventType(self_: *mut whiteout_M3Event, value: u32);
23097        pub fn whiteout_m3_M3Event_get_optionString(self_: *mut whiteout_M3Event) -> RawCString;
23098        pub fn whiteout_m3_M3Event_set_optionString(
23099            self_: *mut whiteout_M3Event,
23100            value: *const core::ffi::c_char,
23101        );
23102        pub fn whiteout_m3_M3Event_get_rttChannelIndex(self_: *mut whiteout_M3Event) -> u32;
23103        pub fn whiteout_m3_M3Event_set_rttChannelIndex(self_: *mut whiteout_M3Event, value: u32);
23104        pub fn whiteout_m3_M3Event_get_extraParameter(self_: *mut whiteout_M3Event) -> u32;
23105        pub fn whiteout_m3_M3Event_set_extraParameter(self_: *mut whiteout_M3Event, value: u32);
23106        // Sequence
23107        pub fn whiteout_m3_M3Sequence_new() -> *mut whiteout_M3Sequence;
23108        pub fn whiteout_m3_M3Sequence_delete(self_: *mut whiteout_M3Sequence);
23109        pub fn whiteout_m3_M3Sequence_get_id(self_: *mut whiteout_M3Sequence) -> i32;
23110        pub fn whiteout_m3_M3Sequence_set_id(self_: *mut whiteout_M3Sequence, value: i32);
23111        pub fn whiteout_m3_M3Sequence_get_index(self_: *mut whiteout_M3Sequence) -> i32;
23112        pub fn whiteout_m3_M3Sequence_set_index(self_: *mut whiteout_M3Sequence, value: i32);
23113        pub fn whiteout_m3_M3Sequence_get_name(self_: *mut whiteout_M3Sequence) -> RawCString;
23114        pub fn whiteout_m3_M3Sequence_set_name(
23115            self_: *mut whiteout_M3Sequence,
23116            value: *const core::ffi::c_char,
23117        );
23118        pub fn whiteout_m3_M3Sequence_get_startFrame(self_: *mut whiteout_M3Sequence) -> u32;
23119        pub fn whiteout_m3_M3Sequence_set_startFrame(self_: *mut whiteout_M3Sequence, value: u32);
23120        pub fn whiteout_m3_M3Sequence_get_endFrame(self_: *mut whiteout_M3Sequence) -> u32;
23121        pub fn whiteout_m3_M3Sequence_set_endFrame(self_: *mut whiteout_M3Sequence, value: u32);
23122        pub fn whiteout_m3_M3Sequence_get_moveSpeed(self_: *mut whiteout_M3Sequence) -> f32;
23123        pub fn whiteout_m3_M3Sequence_set_moveSpeed(self_: *mut whiteout_M3Sequence, value: f32);
23124        pub fn whiteout_m3_M3Sequence_get_flags(self_: *mut whiteout_M3Sequence) -> i32;
23125        pub fn whiteout_m3_M3Sequence_set_flags(self_: *mut whiteout_M3Sequence, value: i32);
23126        pub fn whiteout_m3_M3Sequence_get_frequency(self_: *mut whiteout_M3Sequence) -> u32;
23127        pub fn whiteout_m3_M3Sequence_set_frequency(self_: *mut whiteout_M3Sequence, value: u32);
23128        pub fn whiteout_m3_M3Sequence_get_replayStart(self_: *mut whiteout_M3Sequence) -> u32;
23129        pub fn whiteout_m3_M3Sequence_set_replayStart(self_: *mut whiteout_M3Sequence, value: u32);
23130        pub fn whiteout_m3_M3Sequence_get_replayEnd(self_: *mut whiteout_M3Sequence) -> u32;
23131        pub fn whiteout_m3_M3Sequence_set_replayEnd(self_: *mut whiteout_M3Sequence, value: u32);
23132        pub fn whiteout_m3_M3Sequence_get_blendTime(self_: *mut whiteout_M3Sequence) -> u32;
23133        pub fn whiteout_m3_M3Sequence_set_blendTime(self_: *mut whiteout_M3Sequence, value: u32);
23134        pub fn whiteout_m3_M3Sequence_get_bounds(
23135            self_: *mut whiteout_M3Sequence,
23136        ) -> *mut whiteout_M3Extent;
23137        pub fn whiteout_m3_M3Sequence_set_bounds(
23138            self_: *mut whiteout_M3Sequence,
23139            value: *const whiteout_M3Extent,
23140        );
23141        pub fn whiteout_m3_M3Sequence_get_animationSets_count(
23142            self_: *mut whiteout_M3Sequence,
23143        ) -> usize;
23144        pub fn whiteout_m3_M3Sequence_resize_animationSets(
23145            self_: *mut whiteout_M3Sequence,
23146            count: usize,
23147        );
23148        pub fn whiteout_m3_M3Sequence_get_animationSets_data(
23149            self_: *mut whiteout_M3Sequence,
23150        ) -> *const u8;
23151        pub fn whiteout_m3_M3Sequence_assign_animationSets(
23152            self_: *mut whiteout_M3Sequence,
23153            data: *const u8,
23154            count: usize,
23155        );
23156        // SubTrackContainer
23157        pub fn whiteout_m3_M3SubTrackContainer_new() -> *mut whiteout_M3SubTrackContainer;
23158        pub fn whiteout_m3_M3SubTrackContainer_delete(self_: *mut whiteout_M3SubTrackContainer);
23159        pub fn whiteout_m3_M3SubTrackContainer_get_name(
23160            self_: *mut whiteout_M3SubTrackContainer,
23161        ) -> RawCString;
23162        pub fn whiteout_m3_M3SubTrackContainer_set_name(
23163            self_: *mut whiteout_M3SubTrackContainer,
23164            value: *const core::ffi::c_char,
23165        );
23166        pub fn whiteout_m3_M3SubTrackContainer_get_runsConcurrent(
23167            self_: *mut whiteout_M3SubTrackContainer,
23168        ) -> u16;
23169        pub fn whiteout_m3_M3SubTrackContainer_set_runsConcurrent(
23170            self_: *mut whiteout_M3SubTrackContainer,
23171            value: u16,
23172        );
23173        pub fn whiteout_m3_M3SubTrackContainer_get_animPriority(
23174            self_: *mut whiteout_M3SubTrackContainer,
23175        ) -> u16;
23176        pub fn whiteout_m3_M3SubTrackContainer_set_animPriority(
23177            self_: *mut whiteout_M3SubTrackContainer,
23178            value: u16,
23179        );
23180        pub fn whiteout_m3_M3SubTrackContainer_get_animationStateIndex(
23181            self_: *mut whiteout_M3SubTrackContainer,
23182        ) -> u16;
23183        pub fn whiteout_m3_M3SubTrackContainer_set_animationStateIndex(
23184            self_: *mut whiteout_M3SubTrackContainer,
23185            value: u16,
23186        );
23187        pub fn whiteout_m3_M3SubTrackContainer_get_padding(
23188            self_: *mut whiteout_M3SubTrackContainer,
23189        ) -> u16;
23190        pub fn whiteout_m3_M3SubTrackContainer_set_padding(
23191            self_: *mut whiteout_M3SubTrackContainer,
23192            value: u16,
23193        );
23194        pub fn whiteout_m3_M3SubTrackContainer_get_animIds_count(
23195            self_: *mut whiteout_M3SubTrackContainer,
23196        ) -> usize;
23197        pub fn whiteout_m3_M3SubTrackContainer_resize_animIds(
23198            self_: *mut whiteout_M3SubTrackContainer,
23199            count: usize,
23200        );
23201        pub fn whiteout_m3_M3SubTrackContainer_get_animIds_data(
23202            self_: *mut whiteout_M3SubTrackContainer,
23203        ) -> *const u32;
23204        pub fn whiteout_m3_M3SubTrackContainer_assign_animIds(
23205            self_: *mut whiteout_M3SubTrackContainer,
23206            data: *const u32,
23207            count: usize,
23208        );
23209        pub fn whiteout_m3_M3SubTrackContainer_get_animRefs_count(
23210            self_: *mut whiteout_M3SubTrackContainer,
23211        ) -> usize;
23212        pub fn whiteout_m3_M3SubTrackContainer_resize_animRefs(
23213            self_: *mut whiteout_M3SubTrackContainer,
23214            count: usize,
23215        );
23216        pub fn whiteout_m3_M3SubTrackContainer_get_animRefs_data(
23217            self_: *mut whiteout_M3SubTrackContainer,
23218        ) -> *const u32;
23219        pub fn whiteout_m3_M3SubTrackContainer_assign_animRefs(
23220            self_: *mut whiteout_M3SubTrackContainer,
23221            data: *const u32,
23222            count: usize,
23223        );
23224        pub fn whiteout_m3_M3SubTrackContainer_get_unknown(
23225            self_: *mut whiteout_M3SubTrackContainer,
23226        ) -> u32;
23227        pub fn whiteout_m3_M3SubTrackContainer_set_unknown(
23228            self_: *mut whiteout_M3SubTrackContainer,
23229            value: u32,
23230        );
23231        // AnimationGroup
23232        pub fn whiteout_m3_M3AnimationGroup_new() -> *mut whiteout_M3AnimationGroup;
23233        pub fn whiteout_m3_M3AnimationGroup_delete(self_: *mut whiteout_M3AnimationGroup);
23234        pub fn whiteout_m3_M3AnimationGroup_get_name(
23235            self_: *mut whiteout_M3AnimationGroup,
23236        ) -> RawCString;
23237        pub fn whiteout_m3_M3AnimationGroup_set_name(
23238            self_: *mut whiteout_M3AnimationGroup,
23239            value: *const core::ffi::c_char,
23240        );
23241        pub fn whiteout_m3_M3AnimationGroup_get_subtrackIndices_count(
23242            self_: *mut whiteout_M3AnimationGroup,
23243        ) -> usize;
23244        pub fn whiteout_m3_M3AnimationGroup_resize_subtrackIndices(
23245            self_: *mut whiteout_M3AnimationGroup,
23246            count: usize,
23247        );
23248        pub fn whiteout_m3_M3AnimationGroup_get_subtrackIndices_data(
23249            self_: *mut whiteout_M3AnimationGroup,
23250        ) -> *const u32;
23251        pub fn whiteout_m3_M3AnimationGroup_assign_subtrackIndices(
23252            self_: *mut whiteout_M3AnimationGroup,
23253            data: *const u32,
23254            count: usize,
23255        );
23256        // AnimationState
23257        pub fn whiteout_m3_M3AnimationState_new() -> *mut whiteout_M3AnimationState;
23258        pub fn whiteout_m3_M3AnimationState_delete(self_: *mut whiteout_M3AnimationState);
23259        pub fn whiteout_m3_M3AnimationState_get_animIds_count(
23260            self_: *mut whiteout_M3AnimationState,
23261        ) -> usize;
23262        pub fn whiteout_m3_M3AnimationState_resize_animIds(
23263            self_: *mut whiteout_M3AnimationState,
23264            count: usize,
23265        );
23266        pub fn whiteout_m3_M3AnimationState_get_animIds_data(
23267            self_: *mut whiteout_M3AnimationState,
23268        ) -> *const u32;
23269        pub fn whiteout_m3_M3AnimationState_assign_animIds(
23270            self_: *mut whiteout_M3AnimationState,
23271            data: *const u32,
23272            count: usize,
23273        );
23274        pub fn whiteout_m3_M3AnimationState_unknown_size() -> usize;
23275        pub fn whiteout_m3_M3AnimationState_get_unknown_at(
23276            self_: *mut whiteout_M3AnimationState,
23277            index: usize,
23278        ) -> u8;
23279        pub fn whiteout_m3_M3AnimationState_set_unknown_at(
23280            self_: *mut whiteout_M3AnimationState,
23281            index: usize,
23282            value: u8,
23283        );
23284        // BoneAnimationSet
23285        pub fn whiteout_m3_M3BoneAnimationSet_new() -> *mut whiteout_M3BoneAnimationSet;
23286        pub fn whiteout_m3_M3BoneAnimationSet_delete(self_: *mut whiteout_M3BoneAnimationSet);
23287        pub fn whiteout_m3_M3BoneAnimationSet_get_animationSequenceIndex(
23288            self_: *mut whiteout_M3BoneAnimationSet,
23289        ) -> u16;
23290        pub fn whiteout_m3_M3BoneAnimationSet_set_animationSequenceIndex(
23291            self_: *mut whiteout_M3BoneAnimationSet,
23292            value: u16,
23293        );
23294        pub fn whiteout_m3_M3BoneAnimationSet_get_fallbackSequenceIndex(
23295            self_: *mut whiteout_M3BoneAnimationSet,
23296        ) -> u16;
23297        pub fn whiteout_m3_M3BoneAnimationSet_set_fallbackSequenceIndex(
23298            self_: *mut whiteout_M3BoneAnimationSet,
23299            value: u16,
23300        );
23301        pub fn whiteout_m3_M3BoneAnimationSet_get_name(
23302            self_: *mut whiteout_M3BoneAnimationSet,
23303        ) -> RawCString;
23304        pub fn whiteout_m3_M3BoneAnimationSet_set_name(
23305            self_: *mut whiteout_M3BoneAnimationSet,
23306            value: *const core::ffi::c_char,
23307        );
23308        pub fn whiteout_m3_M3BoneAnimationSet_get_splitItems_count(
23309            self_: *mut whiteout_M3BoneAnimationSet,
23310        ) -> usize;
23311        pub fn whiteout_m3_M3BoneAnimationSet_resize_splitItems(
23312            self_: *mut whiteout_M3BoneAnimationSet,
23313            count: usize,
23314        );
23315        pub fn whiteout_m3_M3BoneAnimationSet_get_splitItems_data(
23316            self_: *mut whiteout_M3BoneAnimationSet,
23317        ) -> *const u16;
23318        pub fn whiteout_m3_M3BoneAnimationSet_assign_splitItems(
23319            self_: *mut whiteout_M3BoneAnimationSet,
23320            data: *const u16,
23321            count: usize,
23322        );
23323        // ParticleEmitter
23324        pub fn whiteout_m3_M3ParticleEmitter_new() -> *mut whiteout_M3ParticleEmitter;
23325        pub fn whiteout_m3_M3ParticleEmitter_delete(self_: *mut whiteout_M3ParticleEmitter);
23326        pub fn whiteout_m3_M3ParticleEmitter_get_boneIndex(
23327            self_: *mut whiteout_M3ParticleEmitter,
23328        ) -> u32;
23329        pub fn whiteout_m3_M3ParticleEmitter_set_boneIndex(
23330            self_: *mut whiteout_M3ParticleEmitter,
23331            value: u32,
23332        );
23333        pub fn whiteout_m3_M3ParticleEmitter_get_materialIndex(
23334            self_: *mut whiteout_M3ParticleEmitter,
23335        ) -> u32;
23336        pub fn whiteout_m3_M3ParticleEmitter_set_materialIndex(
23337            self_: *mut whiteout_M3ParticleEmitter,
23338            value: u32,
23339        );
23340        pub fn whiteout_m3_M3ParticleEmitter_get_additionalFlags(
23341            self_: *mut whiteout_M3ParticleEmitter,
23342        ) -> i32;
23343        pub fn whiteout_m3_M3ParticleEmitter_set_additionalFlags(
23344            self_: *mut whiteout_M3ParticleEmitter,
23345            value: i32,
23346        );
23347        pub fn whiteout_m3_M3ParticleEmitter_get_initialSpeed(
23348            self_: *mut whiteout_M3ParticleEmitter,
23349        ) -> *mut whiteout_M3AnimRefF32;
23350        pub fn whiteout_m3_M3ParticleEmitter_set_initialSpeed(
23351            self_: *mut whiteout_M3ParticleEmitter,
23352            value: *const whiteout_M3AnimRefF32,
23353        );
23354        pub fn whiteout_m3_M3ParticleEmitter_get_initialSpeedRandom(
23355            self_: *mut whiteout_M3ParticleEmitter,
23356        ) -> *mut whiteout_M3AnimRefF32;
23357        pub fn whiteout_m3_M3ParticleEmitter_set_initialSpeedRandom(
23358            self_: *mut whiteout_M3ParticleEmitter,
23359            value: *const whiteout_M3AnimRefF32,
23360        );
23361        pub fn whiteout_m3_M3ParticleEmitter_get_initialYaw(
23362            self_: *mut whiteout_M3ParticleEmitter,
23363        ) -> *mut whiteout_M3AnimRefF32;
23364        pub fn whiteout_m3_M3ParticleEmitter_set_initialYaw(
23365            self_: *mut whiteout_M3ParticleEmitter,
23366            value: *const whiteout_M3AnimRefF32,
23367        );
23368        pub fn whiteout_m3_M3ParticleEmitter_get_initialPitch(
23369            self_: *mut whiteout_M3ParticleEmitter,
23370        ) -> *mut whiteout_M3AnimRefF32;
23371        pub fn whiteout_m3_M3ParticleEmitter_set_initialPitch(
23372            self_: *mut whiteout_M3ParticleEmitter,
23373            value: *const whiteout_M3AnimRefF32,
23374        );
23375        pub fn whiteout_m3_M3ParticleEmitter_get_initialHorizontal(
23376            self_: *mut whiteout_M3ParticleEmitter,
23377        ) -> *mut whiteout_M3AnimRefF32;
23378        pub fn whiteout_m3_M3ParticleEmitter_set_initialHorizontal(
23379            self_: *mut whiteout_M3ParticleEmitter,
23380            value: *const whiteout_M3AnimRefF32,
23381        );
23382        pub fn whiteout_m3_M3ParticleEmitter_get_initialVertical(
23383            self_: *mut whiteout_M3ParticleEmitter,
23384        ) -> *mut whiteout_M3AnimRefF32;
23385        pub fn whiteout_m3_M3ParticleEmitter_set_initialVertical(
23386            self_: *mut whiteout_M3ParticleEmitter,
23387            value: *const whiteout_M3AnimRefF32,
23388        );
23389        pub fn whiteout_m3_M3ParticleEmitter_get_lifetime(
23390            self_: *mut whiteout_M3ParticleEmitter,
23391        ) -> *mut whiteout_M3AnimRefF32;
23392        pub fn whiteout_m3_M3ParticleEmitter_set_lifetime(
23393            self_: *mut whiteout_M3ParticleEmitter,
23394            value: *const whiteout_M3AnimRefF32,
23395        );
23396        pub fn whiteout_m3_M3ParticleEmitter_get_lifetimeRandom(
23397            self_: *mut whiteout_M3ParticleEmitter,
23398        ) -> *mut whiteout_M3AnimRefF32;
23399        pub fn whiteout_m3_M3ParticleEmitter_set_lifetimeRandom(
23400            self_: *mut whiteout_M3ParticleEmitter,
23401            value: *const whiteout_M3AnimRefF32,
23402        );
23403        pub fn whiteout_m3_M3ParticleEmitter_get_killRadius(
23404            self_: *mut whiteout_M3ParticleEmitter,
23405        ) -> f32;
23406        pub fn whiteout_m3_M3ParticleEmitter_set_killRadius(
23407            self_: *mut whiteout_M3ParticleEmitter,
23408            value: f32,
23409        );
23410        pub fn whiteout_m3_M3ParticleEmitter_get_gravityX(
23411            self_: *mut whiteout_M3ParticleEmitter,
23412        ) -> u32;
23413        pub fn whiteout_m3_M3ParticleEmitter_set_gravityX(
23414            self_: *mut whiteout_M3ParticleEmitter,
23415            value: u32,
23416        );
23417        pub fn whiteout_m3_M3ParticleEmitter_get_gravityY(
23418            self_: *mut whiteout_M3ParticleEmitter,
23419        ) -> u32;
23420        pub fn whiteout_m3_M3ParticleEmitter_set_gravityY(
23421            self_: *mut whiteout_M3ParticleEmitter,
23422            value: u32,
23423        );
23424        pub fn whiteout_m3_M3ParticleEmitter_get_gravity(
23425            self_: *mut whiteout_M3ParticleEmitter,
23426        ) -> f32;
23427        pub fn whiteout_m3_M3ParticleEmitter_set_gravity(
23428            self_: *mut whiteout_M3ParticleEmitter,
23429            value: f32,
23430        );
23431        pub fn whiteout_m3_M3ParticleEmitter_get_sizeMidTime(
23432            self_: *mut whiteout_M3ParticleEmitter,
23433        ) -> f32;
23434        pub fn whiteout_m3_M3ParticleEmitter_set_sizeMidTime(
23435            self_: *mut whiteout_M3ParticleEmitter,
23436            value: f32,
23437        );
23438        pub fn whiteout_m3_M3ParticleEmitter_get_colorMidTime(
23439            self_: *mut whiteout_M3ParticleEmitter,
23440        ) -> f32;
23441        pub fn whiteout_m3_M3ParticleEmitter_set_colorMidTime(
23442            self_: *mut whiteout_M3ParticleEmitter,
23443            value: f32,
23444        );
23445        pub fn whiteout_m3_M3ParticleEmitter_get_alphaMidTime(
23446            self_: *mut whiteout_M3ParticleEmitter,
23447        ) -> f32;
23448        pub fn whiteout_m3_M3ParticleEmitter_set_alphaMidTime(
23449            self_: *mut whiteout_M3ParticleEmitter,
23450            value: f32,
23451        );
23452        pub fn whiteout_m3_M3ParticleEmitter_get_rotationMidTime(
23453            self_: *mut whiteout_M3ParticleEmitter,
23454        ) -> f32;
23455        pub fn whiteout_m3_M3ParticleEmitter_set_rotationMidTime(
23456            self_: *mut whiteout_M3ParticleEmitter,
23457            value: f32,
23458        );
23459        pub fn whiteout_m3_M3ParticleEmitter_get_sizeMidHoldTime(
23460            self_: *mut whiteout_M3ParticleEmitter,
23461        ) -> f32;
23462        pub fn whiteout_m3_M3ParticleEmitter_set_sizeMidHoldTime(
23463            self_: *mut whiteout_M3ParticleEmitter,
23464            value: f32,
23465        );
23466        pub fn whiteout_m3_M3ParticleEmitter_get_colorMidHoldTime(
23467            self_: *mut whiteout_M3ParticleEmitter,
23468        ) -> f32;
23469        pub fn whiteout_m3_M3ParticleEmitter_set_colorMidHoldTime(
23470            self_: *mut whiteout_M3ParticleEmitter,
23471            value: f32,
23472        );
23473        pub fn whiteout_m3_M3ParticleEmitter_get_alphaMidHoldTime(
23474            self_: *mut whiteout_M3ParticleEmitter,
23475        ) -> f32;
23476        pub fn whiteout_m3_M3ParticleEmitter_set_alphaMidHoldTime(
23477            self_: *mut whiteout_M3ParticleEmitter,
23478            value: f32,
23479        );
23480        pub fn whiteout_m3_M3ParticleEmitter_get_rotationMidHoldTime(
23481            self_: *mut whiteout_M3ParticleEmitter,
23482        ) -> f32;
23483        pub fn whiteout_m3_M3ParticleEmitter_set_rotationMidHoldTime(
23484            self_: *mut whiteout_M3ParticleEmitter,
23485            value: f32,
23486        );
23487        pub fn whiteout_m3_M3ParticleEmitter_get_sizeAnimation(
23488            self_: *mut whiteout_M3ParticleEmitter,
23489        ) -> *mut whiteout_M3AnimRefVector3f;
23490        pub fn whiteout_m3_M3ParticleEmitter_set_sizeAnimation(
23491            self_: *mut whiteout_M3ParticleEmitter,
23492            value: *const whiteout_M3AnimRefVector3f,
23493        );
23494        pub fn whiteout_m3_M3ParticleEmitter_get_rotationAnimation(
23495            self_: *mut whiteout_M3ParticleEmitter,
23496        ) -> *mut whiteout_M3AnimRefVector3f;
23497        pub fn whiteout_m3_M3ParticleEmitter_set_rotationAnimation(
23498            self_: *mut whiteout_M3ParticleEmitter,
23499            value: *const whiteout_M3AnimRefVector3f,
23500        );
23501        pub fn whiteout_m3_M3ParticleEmitter_get_colorStart(
23502            self_: *mut whiteout_M3ParticleEmitter,
23503        ) -> *mut whiteout_M3AnimRefM3ColorBGRA;
23504        pub fn whiteout_m3_M3ParticleEmitter_set_colorStart(
23505            self_: *mut whiteout_M3ParticleEmitter,
23506            value: *const whiteout_M3AnimRefM3ColorBGRA,
23507        );
23508        pub fn whiteout_m3_M3ParticleEmitter_get_colorMid(
23509            self_: *mut whiteout_M3ParticleEmitter,
23510        ) -> *mut whiteout_M3AnimRefM3ColorBGRA;
23511        pub fn whiteout_m3_M3ParticleEmitter_set_colorMid(
23512            self_: *mut whiteout_M3ParticleEmitter,
23513            value: *const whiteout_M3AnimRefM3ColorBGRA,
23514        );
23515        pub fn whiteout_m3_M3ParticleEmitter_get_colorEnd(
23516            self_: *mut whiteout_M3ParticleEmitter,
23517        ) -> *mut whiteout_M3AnimRefM3ColorBGRA;
23518        pub fn whiteout_m3_M3ParticleEmitter_set_colorEnd(
23519            self_: *mut whiteout_M3ParticleEmitter,
23520            value: *const whiteout_M3AnimRefM3ColorBGRA,
23521        );
23522        pub fn whiteout_m3_M3ParticleEmitter_get_drag(
23523            self_: *mut whiteout_M3ParticleEmitter,
23524        ) -> f32;
23525        pub fn whiteout_m3_M3ParticleEmitter_set_drag(
23526            self_: *mut whiteout_M3ParticleEmitter,
23527            value: f32,
23528        );
23529        pub fn whiteout_m3_M3ParticleEmitter_get_mass(
23530            self_: *mut whiteout_M3ParticleEmitter,
23531        ) -> f32;
23532        pub fn whiteout_m3_M3ParticleEmitter_set_mass(
23533            self_: *mut whiteout_M3ParticleEmitter,
23534            value: f32,
23535        );
23536        pub fn whiteout_m3_M3ParticleEmitter_get_massRandom(
23537            self_: *mut whiteout_M3ParticleEmitter,
23538        ) -> f32;
23539        pub fn whiteout_m3_M3ParticleEmitter_set_massRandom(
23540            self_: *mut whiteout_M3ParticleEmitter,
23541            value: f32,
23542        );
23543        pub fn whiteout_m3_M3ParticleEmitter_get_massSizeMultiplier(
23544            self_: *mut whiteout_M3ParticleEmitter,
23545        ) -> f32;
23546        pub fn whiteout_m3_M3ParticleEmitter_set_massSizeMultiplier(
23547            self_: *mut whiteout_M3ParticleEmitter,
23548            value: f32,
23549        );
23550        pub fn whiteout_m3_M3ParticleEmitter_get_localForces(
23551            self_: *mut whiteout_M3ParticleEmitter,
23552        ) -> u16;
23553        pub fn whiteout_m3_M3ParticleEmitter_set_localForces(
23554            self_: *mut whiteout_M3ParticleEmitter,
23555            value: u16,
23556        );
23557        pub fn whiteout_m3_M3ParticleEmitter_get_worldForces(
23558            self_: *mut whiteout_M3ParticleEmitter,
23559        ) -> u16;
23560        pub fn whiteout_m3_M3ParticleEmitter_set_worldForces(
23561            self_: *mut whiteout_M3ParticleEmitter,
23562            value: u16,
23563        );
23564        pub fn whiteout_m3_M3ParticleEmitter_get_localForcesFallback(
23565            self_: *mut whiteout_M3ParticleEmitter,
23566        ) -> u16;
23567        pub fn whiteout_m3_M3ParticleEmitter_set_localForcesFallback(
23568            self_: *mut whiteout_M3ParticleEmitter,
23569            value: u16,
23570        );
23571        pub fn whiteout_m3_M3ParticleEmitter_get_worldForcesFallback(
23572            self_: *mut whiteout_M3ParticleEmitter,
23573        ) -> u16;
23574        pub fn whiteout_m3_M3ParticleEmitter_set_worldForcesFallback(
23575            self_: *mut whiteout_M3ParticleEmitter,
23576            value: u16,
23577        );
23578        pub fn whiteout_m3_M3ParticleEmitter_get_worldForcesMassMultiplier(
23579            self_: *mut whiteout_M3ParticleEmitter,
23580        ) -> f32;
23581        pub fn whiteout_m3_M3ParticleEmitter_set_worldForcesMassMultiplier(
23582            self_: *mut whiteout_M3ParticleEmitter,
23583            value: f32,
23584        );
23585        pub fn whiteout_m3_M3ParticleEmitter_get_noiseAmplitude(
23586            self_: *mut whiteout_M3ParticleEmitter,
23587        ) -> f32;
23588        pub fn whiteout_m3_M3ParticleEmitter_set_noiseAmplitude(
23589            self_: *mut whiteout_M3ParticleEmitter,
23590            value: f32,
23591        );
23592        pub fn whiteout_m3_M3ParticleEmitter_get_noiseFrequency(
23593            self_: *mut whiteout_M3ParticleEmitter,
23594        ) -> f32;
23595        pub fn whiteout_m3_M3ParticleEmitter_set_noiseFrequency(
23596            self_: *mut whiteout_M3ParticleEmitter,
23597            value: f32,
23598        );
23599        pub fn whiteout_m3_M3ParticleEmitter_get_noiseCoherence(
23600            self_: *mut whiteout_M3ParticleEmitter,
23601        ) -> f32;
23602        pub fn whiteout_m3_M3ParticleEmitter_set_noiseCoherence(
23603            self_: *mut whiteout_M3ParticleEmitter,
23604            value: f32,
23605        );
23606        pub fn whiteout_m3_M3ParticleEmitter_get_noiseEdge(
23607            self_: *mut whiteout_M3ParticleEmitter,
23608        ) -> f32;
23609        pub fn whiteout_m3_M3ParticleEmitter_set_noiseEdge(
23610            self_: *mut whiteout_M3ParticleEmitter,
23611            value: f32,
23612        );
23613        pub fn whiteout_m3_M3ParticleEmitter_get_indexPlusLength(
23614            self_: *mut whiteout_M3ParticleEmitter,
23615        ) -> u32;
23616        pub fn whiteout_m3_M3ParticleEmitter_set_indexPlusLength(
23617            self_: *mut whiteout_M3ParticleEmitter,
23618            value: u32,
23619        );
23620        pub fn whiteout_m3_M3ParticleEmitter_get_maxParticles(
23621            self_: *mut whiteout_M3ParticleEmitter,
23622        ) -> u32;
23623        pub fn whiteout_m3_M3ParticleEmitter_set_maxParticles(
23624            self_: *mut whiteout_M3ParticleEmitter,
23625            value: u32,
23626        );
23627        pub fn whiteout_m3_M3ParticleEmitter_get_emissionRate(
23628            self_: *mut whiteout_M3ParticleEmitter,
23629        ) -> *mut whiteout_M3AnimRefF32;
23630        pub fn whiteout_m3_M3ParticleEmitter_set_emissionRate(
23631            self_: *mut whiteout_M3ParticleEmitter,
23632            value: *const whiteout_M3AnimRefF32,
23633        );
23634        pub fn whiteout_m3_M3ParticleEmitter_get_emitterShape(
23635            self_: *mut whiteout_M3ParticleEmitter,
23636        ) -> i32;
23637        pub fn whiteout_m3_M3ParticleEmitter_set_emitterShape(
23638            self_: *mut whiteout_M3ParticleEmitter,
23639            value: i32,
23640        );
23641        pub fn whiteout_m3_M3ParticleEmitter_get_shapeOuter(
23642            self_: *mut whiteout_M3ParticleEmitter,
23643        ) -> *mut whiteout_M3AnimRefVector3f;
23644        pub fn whiteout_m3_M3ParticleEmitter_set_shapeOuter(
23645            self_: *mut whiteout_M3ParticleEmitter,
23646            value: *const whiteout_M3AnimRefVector3f,
23647        );
23648        pub fn whiteout_m3_M3ParticleEmitter_get_shapeInner(
23649            self_: *mut whiteout_M3ParticleEmitter,
23650        ) -> *mut whiteout_M3AnimRefVector3f;
23651        pub fn whiteout_m3_M3ParticleEmitter_set_shapeInner(
23652            self_: *mut whiteout_M3ParticleEmitter,
23653            value: *const whiteout_M3AnimRefVector3f,
23654        );
23655        pub fn whiteout_m3_M3ParticleEmitter_get_outerRadius(
23656            self_: *mut whiteout_M3ParticleEmitter,
23657        ) -> *mut whiteout_M3AnimRefF32;
23658        pub fn whiteout_m3_M3ParticleEmitter_set_outerRadius(
23659            self_: *mut whiteout_M3ParticleEmitter,
23660            value: *const whiteout_M3AnimRefF32,
23661        );
23662        pub fn whiteout_m3_M3ParticleEmitter_get_innerRadius(
23663            self_: *mut whiteout_M3ParticleEmitter,
23664        ) -> *mut whiteout_M3AnimRefF32;
23665        pub fn whiteout_m3_M3ParticleEmitter_set_innerRadius(
23666            self_: *mut whiteout_M3ParticleEmitter,
23667            value: *const whiteout_M3AnimRefF32,
23668        );
23669        pub fn whiteout_m3_M3ParticleEmitter_get_shapeRegions_count(
23670            self_: *mut whiteout_M3ParticleEmitter,
23671        ) -> usize;
23672        pub fn whiteout_m3_M3ParticleEmitter_resize_shapeRegions(
23673            self_: *mut whiteout_M3ParticleEmitter,
23674            count: usize,
23675        );
23676        pub fn whiteout_m3_M3ParticleEmitter_get_shapeRegions_data(
23677            self_: *mut whiteout_M3ParticleEmitter,
23678        ) -> *const u32;
23679        pub fn whiteout_m3_M3ParticleEmitter_assign_shapeRegions(
23680            self_: *mut whiteout_M3ParticleEmitter,
23681            data: *const u32,
23682            count: usize,
23683        );
23684        pub fn whiteout_m3_M3ParticleEmitter_get_velocityType(
23685            self_: *mut whiteout_M3ParticleEmitter,
23686        ) -> u32;
23687        pub fn whiteout_m3_M3ParticleEmitter_set_velocityType(
23688            self_: *mut whiteout_M3ParticleEmitter,
23689            value: u32,
23690        );
23691        pub fn whiteout_m3_M3ParticleEmitter_get_sizeRandomEnable(
23692            self_: *mut whiteout_M3ParticleEmitter,
23693        ) -> u32;
23694        pub fn whiteout_m3_M3ParticleEmitter_set_sizeRandomEnable(
23695            self_: *mut whiteout_M3ParticleEmitter,
23696            value: u32,
23697        );
23698        pub fn whiteout_m3_M3ParticleEmitter_get_sizeRandomAnimation(
23699            self_: *mut whiteout_M3ParticleEmitter,
23700        ) -> *mut whiteout_M3AnimRefVector3f;
23701        pub fn whiteout_m3_M3ParticleEmitter_set_sizeRandomAnimation(
23702            self_: *mut whiteout_M3ParticleEmitter,
23703            value: *const whiteout_M3AnimRefVector3f,
23704        );
23705        pub fn whiteout_m3_M3ParticleEmitter_get_rotationRandomEnable(
23706            self_: *mut whiteout_M3ParticleEmitter,
23707        ) -> u32;
23708        pub fn whiteout_m3_M3ParticleEmitter_set_rotationRandomEnable(
23709            self_: *mut whiteout_M3ParticleEmitter,
23710            value: u32,
23711        );
23712        pub fn whiteout_m3_M3ParticleEmitter_get_rotationRandomAnimation(
23713            self_: *mut whiteout_M3ParticleEmitter,
23714        ) -> *mut whiteout_M3AnimRefVector3f;
23715        pub fn whiteout_m3_M3ParticleEmitter_set_rotationRandomAnimation(
23716            self_: *mut whiteout_M3ParticleEmitter,
23717            value: *const whiteout_M3AnimRefVector3f,
23718        );
23719        pub fn whiteout_m3_M3ParticleEmitter_get_colorRandomEnable(
23720            self_: *mut whiteout_M3ParticleEmitter,
23721        ) -> u32;
23722        pub fn whiteout_m3_M3ParticleEmitter_set_colorRandomEnable(
23723            self_: *mut whiteout_M3ParticleEmitter,
23724            value: u32,
23725        );
23726        pub fn whiteout_m3_M3ParticleEmitter_get_colorStartRandom(
23727            self_: *mut whiteout_M3ParticleEmitter,
23728        ) -> *mut whiteout_M3AnimRefM3ColorBGRA;
23729        pub fn whiteout_m3_M3ParticleEmitter_set_colorStartRandom(
23730            self_: *mut whiteout_M3ParticleEmitter,
23731            value: *const whiteout_M3AnimRefM3ColorBGRA,
23732        );
23733        pub fn whiteout_m3_M3ParticleEmitter_get_colorMidRandom(
23734            self_: *mut whiteout_M3ParticleEmitter,
23735        ) -> *mut whiteout_M3AnimRefM3ColorBGRA;
23736        pub fn whiteout_m3_M3ParticleEmitter_set_colorMidRandom(
23737            self_: *mut whiteout_M3ParticleEmitter,
23738            value: *const whiteout_M3AnimRefM3ColorBGRA,
23739        );
23740        pub fn whiteout_m3_M3ParticleEmitter_get_colorEndRandom(
23741            self_: *mut whiteout_M3ParticleEmitter,
23742        ) -> *mut whiteout_M3AnimRefM3ColorBGRA;
23743        pub fn whiteout_m3_M3ParticleEmitter_set_colorEndRandom(
23744            self_: *mut whiteout_M3ParticleEmitter,
23745            value: *const whiteout_M3AnimRefM3ColorBGRA,
23746        );
23747        pub fn whiteout_m3_M3ParticleEmitter_get_alphaRandomEnable(
23748            self_: *mut whiteout_M3ParticleEmitter,
23749        ) -> u32;
23750        pub fn whiteout_m3_M3ParticleEmitter_set_alphaRandomEnable(
23751            self_: *mut whiteout_M3ParticleEmitter,
23752            value: u32,
23753        );
23754        pub fn whiteout_m3_M3ParticleEmitter_get_squirtAmount(
23755            self_: *mut whiteout_M3ParticleEmitter,
23756        ) -> *mut whiteout_M3AnimRefU16;
23757        pub fn whiteout_m3_M3ParticleEmitter_set_squirtAmount(
23758            self_: *mut whiteout_M3ParticleEmitter,
23759            value: *const whiteout_M3AnimRefU16,
23760        );
23761        pub fn whiteout_m3_M3ParticleEmitter_get_flipbookStartInitIndex(
23762            self_: *mut whiteout_M3ParticleEmitter,
23763        ) -> u8;
23764        pub fn whiteout_m3_M3ParticleEmitter_set_flipbookStartInitIndex(
23765            self_: *mut whiteout_M3ParticleEmitter,
23766            value: u8,
23767        );
23768        pub fn whiteout_m3_M3ParticleEmitter_get_flipbookStartStopIndex(
23769            self_: *mut whiteout_M3ParticleEmitter,
23770        ) -> u8;
23771        pub fn whiteout_m3_M3ParticleEmitter_set_flipbookStartStopIndex(
23772            self_: *mut whiteout_M3ParticleEmitter,
23773            value: u8,
23774        );
23775        pub fn whiteout_m3_M3ParticleEmitter_get_flipbookEndInitIndex(
23776            self_: *mut whiteout_M3ParticleEmitter,
23777        ) -> u8;
23778        pub fn whiteout_m3_M3ParticleEmitter_set_flipbookEndInitIndex(
23779            self_: *mut whiteout_M3ParticleEmitter,
23780            value: u8,
23781        );
23782        pub fn whiteout_m3_M3ParticleEmitter_get_flipbookEndStopIndex(
23783            self_: *mut whiteout_M3ParticleEmitter,
23784        ) -> u8;
23785        pub fn whiteout_m3_M3ParticleEmitter_set_flipbookEndStopIndex(
23786            self_: *mut whiteout_M3ParticleEmitter,
23787            value: u8,
23788        );
23789        pub fn whiteout_m3_M3ParticleEmitter_get_flipbookMidTime(
23790            self_: *mut whiteout_M3ParticleEmitter,
23791        ) -> f32;
23792        pub fn whiteout_m3_M3ParticleEmitter_set_flipbookMidTime(
23793            self_: *mut whiteout_M3ParticleEmitter,
23794            value: f32,
23795        );
23796        pub fn whiteout_m3_M3ParticleEmitter_get_flipbookColumns(
23797            self_: *mut whiteout_M3ParticleEmitter,
23798        ) -> u16;
23799        pub fn whiteout_m3_M3ParticleEmitter_set_flipbookColumns(
23800            self_: *mut whiteout_M3ParticleEmitter,
23801            value: u16,
23802        );
23803        pub fn whiteout_m3_M3ParticleEmitter_get_flipbookRows(
23804            self_: *mut whiteout_M3ParticleEmitter,
23805        ) -> u16;
23806        pub fn whiteout_m3_M3ParticleEmitter_set_flipbookRows(
23807            self_: *mut whiteout_M3ParticleEmitter,
23808            value: u16,
23809        );
23810        pub fn whiteout_m3_M3ParticleEmitter_get_flipbookColumnFraction(
23811            self_: *mut whiteout_M3ParticleEmitter,
23812        ) -> f32;
23813        pub fn whiteout_m3_M3ParticleEmitter_set_flipbookColumnFraction(
23814            self_: *mut whiteout_M3ParticleEmitter,
23815            value: f32,
23816        );
23817        pub fn whiteout_m3_M3ParticleEmitter_get_flipbookRowFraction(
23818            self_: *mut whiteout_M3ParticleEmitter,
23819        ) -> f32;
23820        pub fn whiteout_m3_M3ParticleEmitter_set_flipbookRowFraction(
23821            self_: *mut whiteout_M3ParticleEmitter,
23822            value: f32,
23823        );
23824        pub fn whiteout_m3_M3ParticleEmitter_get_bounce(
23825            self_: *mut whiteout_M3ParticleEmitter,
23826        ) -> f32;
23827        pub fn whiteout_m3_M3ParticleEmitter_set_bounce(
23828            self_: *mut whiteout_M3ParticleEmitter,
23829            value: f32,
23830        );
23831        pub fn whiteout_m3_M3ParticleEmitter_get_friction(
23832            self_: *mut whiteout_M3ParticleEmitter,
23833        ) -> f32;
23834        pub fn whiteout_m3_M3ParticleEmitter_set_friction(
23835            self_: *mut whiteout_M3ParticleEmitter,
23836            value: f32,
23837        );
23838        pub fn whiteout_m3_M3ParticleEmitter_get_collisionSpawnIndex(
23839            self_: *mut whiteout_M3ParticleEmitter,
23840        ) -> i32;
23841        pub fn whiteout_m3_M3ParticleEmitter_set_collisionSpawnIndex(
23842            self_: *mut whiteout_M3ParticleEmitter,
23843            value: i32,
23844        );
23845        pub fn whiteout_m3_M3ParticleEmitter_get_collisionSpawnMin(
23846            self_: *mut whiteout_M3ParticleEmitter,
23847        ) -> u32;
23848        pub fn whiteout_m3_M3ParticleEmitter_set_collisionSpawnMin(
23849            self_: *mut whiteout_M3ParticleEmitter,
23850            value: u32,
23851        );
23852        pub fn whiteout_m3_M3ParticleEmitter_get_collisionSpawnMax(
23853            self_: *mut whiteout_M3ParticleEmitter,
23854        ) -> u32;
23855        pub fn whiteout_m3_M3ParticleEmitter_set_collisionSpawnMax(
23856            self_: *mut whiteout_M3ParticleEmitter,
23857            value: u32,
23858        );
23859        pub fn whiteout_m3_M3ParticleEmitter_get_collisionSpawnChance(
23860            self_: *mut whiteout_M3ParticleEmitter,
23861        ) -> f32;
23862        pub fn whiteout_m3_M3ParticleEmitter_set_collisionSpawnChance(
23863            self_: *mut whiteout_M3ParticleEmitter,
23864            value: f32,
23865        );
23866        pub fn whiteout_m3_M3ParticleEmitter_get_collisionSpawnEnergy(
23867            self_: *mut whiteout_M3ParticleEmitter,
23868        ) -> f32;
23869        pub fn whiteout_m3_M3ParticleEmitter_set_collisionSpawnEnergy(
23870            self_: *mut whiteout_M3ParticleEmitter,
23871            value: f32,
23872        );
23873        pub fn whiteout_m3_M3ParticleEmitter_get_collisionDieBounce(
23874            self_: *mut whiteout_M3ParticleEmitter,
23875        ) -> u32;
23876        pub fn whiteout_m3_M3ParticleEmitter_set_collisionDieBounce(
23877            self_: *mut whiteout_M3ParticleEmitter,
23878            value: u32,
23879        );
23880        pub fn whiteout_m3_M3ParticleEmitter_get_instanceType(
23881            self_: *mut whiteout_M3ParticleEmitter,
23882        ) -> i32;
23883        pub fn whiteout_m3_M3ParticleEmitter_set_instanceType(
23884            self_: *mut whiteout_M3ParticleEmitter,
23885            value: i32,
23886        );
23887        pub fn whiteout_m3_M3ParticleEmitter_get_tailLength(
23888            self_: *mut whiteout_M3ParticleEmitter,
23889        ) -> f32;
23890        pub fn whiteout_m3_M3ParticleEmitter_set_tailLength(
23891            self_: *mut whiteout_M3ParticleEmitter,
23892            value: f32,
23893        );
23894        pub fn whiteout_m3_M3ParticleEmitter_get_instanceAngle(
23895            self_: *mut whiteout_M3ParticleEmitter,
23896        ) -> *mut core::ffi::c_void;
23897        pub fn whiteout_m3_M3ParticleEmitter_set_instanceAngle(
23898            self_: *mut whiteout_M3ParticleEmitter,
23899            value: *const core::ffi::c_void,
23900        );
23901        pub fn whiteout_m3_M3ParticleEmitter_get_instanceDistance(
23902            self_: *mut whiteout_M3ParticleEmitter,
23903        ) -> f32;
23904        pub fn whiteout_m3_M3ParticleEmitter_set_instanceDistance(
23905            self_: *mut whiteout_M3ParticleEmitter,
23906            value: f32,
23907        );
23908        pub fn whiteout_m3_M3ParticleEmitter_get_pitchType(
23909            self_: *mut whiteout_M3ParticleEmitter,
23910        ) -> u32;
23911        pub fn whiteout_m3_M3ParticleEmitter_set_pitchType(
23912            self_: *mut whiteout_M3ParticleEmitter,
23913            value: u32,
23914        );
23915        pub fn whiteout_m3_M3ParticleEmitter_get_pitchAmplitude(
23916            self_: *mut whiteout_M3ParticleEmitter,
23917        ) -> *mut whiteout_M3AnimRefF32;
23918        pub fn whiteout_m3_M3ParticleEmitter_set_pitchAmplitude(
23919            self_: *mut whiteout_M3ParticleEmitter,
23920            value: *const whiteout_M3AnimRefF32,
23921        );
23922        pub fn whiteout_m3_M3ParticleEmitter_get_pitchFrequency(
23923            self_: *mut whiteout_M3ParticleEmitter,
23924        ) -> *mut whiteout_M3AnimRefF32;
23925        pub fn whiteout_m3_M3ParticleEmitter_set_pitchFrequency(
23926            self_: *mut whiteout_M3ParticleEmitter,
23927            value: *const whiteout_M3AnimRefF32,
23928        );
23929        pub fn whiteout_m3_M3ParticleEmitter_get_yawType(
23930            self_: *mut whiteout_M3ParticleEmitter,
23931        ) -> u32;
23932        pub fn whiteout_m3_M3ParticleEmitter_set_yawType(
23933            self_: *mut whiteout_M3ParticleEmitter,
23934            value: u32,
23935        );
23936        pub fn whiteout_m3_M3ParticleEmitter_get_yawAmplitude(
23937            self_: *mut whiteout_M3ParticleEmitter,
23938        ) -> *mut whiteout_M3AnimRefF32;
23939        pub fn whiteout_m3_M3ParticleEmitter_set_yawAmplitude(
23940            self_: *mut whiteout_M3ParticleEmitter,
23941            value: *const whiteout_M3AnimRefF32,
23942        );
23943        pub fn whiteout_m3_M3ParticleEmitter_get_yawFrequency(
23944            self_: *mut whiteout_M3ParticleEmitter,
23945        ) -> *mut whiteout_M3AnimRefF32;
23946        pub fn whiteout_m3_M3ParticleEmitter_set_yawFrequency(
23947            self_: *mut whiteout_M3ParticleEmitter,
23948            value: *const whiteout_M3AnimRefF32,
23949        );
23950        pub fn whiteout_m3_M3ParticleEmitter_get_speedType(
23951            self_: *mut whiteout_M3ParticleEmitter,
23952        ) -> u32;
23953        pub fn whiteout_m3_M3ParticleEmitter_set_speedType(
23954            self_: *mut whiteout_M3ParticleEmitter,
23955            value: u32,
23956        );
23957        pub fn whiteout_m3_M3ParticleEmitter_get_speedAmplitude(
23958            self_: *mut whiteout_M3ParticleEmitter,
23959        ) -> *mut whiteout_M3AnimRefF32;
23960        pub fn whiteout_m3_M3ParticleEmitter_set_speedAmplitude(
23961            self_: *mut whiteout_M3ParticleEmitter,
23962            value: *const whiteout_M3AnimRefF32,
23963        );
23964        pub fn whiteout_m3_M3ParticleEmitter_get_speedFrequency(
23965            self_: *mut whiteout_M3ParticleEmitter,
23966        ) -> *mut whiteout_M3AnimRefF32;
23967        pub fn whiteout_m3_M3ParticleEmitter_set_speedFrequency(
23968            self_: *mut whiteout_M3ParticleEmitter,
23969            value: *const whiteout_M3AnimRefF32,
23970        );
23971        pub fn whiteout_m3_M3ParticleEmitter_get_sizeType(
23972            self_: *mut whiteout_M3ParticleEmitter,
23973        ) -> u32;
23974        pub fn whiteout_m3_M3ParticleEmitter_set_sizeType(
23975            self_: *mut whiteout_M3ParticleEmitter,
23976            value: u32,
23977        );
23978        pub fn whiteout_m3_M3ParticleEmitter_get_sizeAmplitude(
23979            self_: *mut whiteout_M3ParticleEmitter,
23980        ) -> *mut whiteout_M3AnimRefF32;
23981        pub fn whiteout_m3_M3ParticleEmitter_set_sizeAmplitude(
23982            self_: *mut whiteout_M3ParticleEmitter,
23983            value: *const whiteout_M3AnimRefF32,
23984        );
23985        pub fn whiteout_m3_M3ParticleEmitter_get_sizeFrequency(
23986            self_: *mut whiteout_M3ParticleEmitter,
23987        ) -> *mut whiteout_M3AnimRefF32;
23988        pub fn whiteout_m3_M3ParticleEmitter_set_sizeFrequency(
23989            self_: *mut whiteout_M3ParticleEmitter,
23990            value: *const whiteout_M3AnimRefF32,
23991        );
23992        pub fn whiteout_m3_M3ParticleEmitter_get_alphaType(
23993            self_: *mut whiteout_M3ParticleEmitter,
23994        ) -> u32;
23995        pub fn whiteout_m3_M3ParticleEmitter_set_alphaType(
23996            self_: *mut whiteout_M3ParticleEmitter,
23997            value: u32,
23998        );
23999        pub fn whiteout_m3_M3ParticleEmitter_get_alphaAmplitude(
24000            self_: *mut whiteout_M3ParticleEmitter,
24001        ) -> *mut whiteout_M3AnimRefF32;
24002        pub fn whiteout_m3_M3ParticleEmitter_set_alphaAmplitude(
24003            self_: *mut whiteout_M3ParticleEmitter,
24004            value: *const whiteout_M3AnimRefF32,
24005        );
24006        pub fn whiteout_m3_M3ParticleEmitter_get_alphaFrequency(
24007            self_: *mut whiteout_M3ParticleEmitter,
24008        ) -> *mut whiteout_M3AnimRefF32;
24009        pub fn whiteout_m3_M3ParticleEmitter_set_alphaFrequency(
24010            self_: *mut whiteout_M3ParticleEmitter,
24011            value: *const whiteout_M3AnimRefF32,
24012        );
24013        pub fn whiteout_m3_M3ParticleEmitter_get_colorType(
24014            self_: *mut whiteout_M3ParticleEmitter,
24015        ) -> u32;
24016        pub fn whiteout_m3_M3ParticleEmitter_set_colorType(
24017            self_: *mut whiteout_M3ParticleEmitter,
24018            value: u32,
24019        );
24020        pub fn whiteout_m3_M3ParticleEmitter_get_colorAmplitude(
24021            self_: *mut whiteout_M3ParticleEmitter,
24022        ) -> *mut whiteout_M3AnimRefF32;
24023        pub fn whiteout_m3_M3ParticleEmitter_set_colorAmplitude(
24024            self_: *mut whiteout_M3ParticleEmitter,
24025            value: *const whiteout_M3AnimRefF32,
24026        );
24027        pub fn whiteout_m3_M3ParticleEmitter_get_colorFrequency(
24028            self_: *mut whiteout_M3ParticleEmitter,
24029        ) -> *mut whiteout_M3AnimRefF32;
24030        pub fn whiteout_m3_M3ParticleEmitter_set_colorFrequency(
24031            self_: *mut whiteout_M3ParticleEmitter,
24032            value: *const whiteout_M3AnimRefF32,
24033        );
24034        pub fn whiteout_m3_M3ParticleEmitter_get_rotationType(
24035            self_: *mut whiteout_M3ParticleEmitter,
24036        ) -> u32;
24037        pub fn whiteout_m3_M3ParticleEmitter_set_rotationType(
24038            self_: *mut whiteout_M3ParticleEmitter,
24039            value: u32,
24040        );
24041        pub fn whiteout_m3_M3ParticleEmitter_get_rotationAmplitude(
24042            self_: *mut whiteout_M3ParticleEmitter,
24043        ) -> *mut whiteout_M3AnimRefF32;
24044        pub fn whiteout_m3_M3ParticleEmitter_set_rotationAmplitude(
24045            self_: *mut whiteout_M3ParticleEmitter,
24046            value: *const whiteout_M3AnimRefF32,
24047        );
24048        pub fn whiteout_m3_M3ParticleEmitter_get_rotationFrequency(
24049            self_: *mut whiteout_M3ParticleEmitter,
24050        ) -> *mut whiteout_M3AnimRefF32;
24051        pub fn whiteout_m3_M3ParticleEmitter_set_rotationFrequency(
24052            self_: *mut whiteout_M3ParticleEmitter,
24053            value: *const whiteout_M3AnimRefF32,
24054        );
24055        pub fn whiteout_m3_M3ParticleEmitter_get_horizontalType(
24056            self_: *mut whiteout_M3ParticleEmitter,
24057        ) -> u32;
24058        pub fn whiteout_m3_M3ParticleEmitter_set_horizontalType(
24059            self_: *mut whiteout_M3ParticleEmitter,
24060            value: u32,
24061        );
24062        pub fn whiteout_m3_M3ParticleEmitter_get_horizontalAmplitude(
24063            self_: *mut whiteout_M3ParticleEmitter,
24064        ) -> *mut whiteout_M3AnimRefF32;
24065        pub fn whiteout_m3_M3ParticleEmitter_set_horizontalAmplitude(
24066            self_: *mut whiteout_M3ParticleEmitter,
24067            value: *const whiteout_M3AnimRefF32,
24068        );
24069        pub fn whiteout_m3_M3ParticleEmitter_get_horizontalFrequency(
24070            self_: *mut whiteout_M3ParticleEmitter,
24071        ) -> *mut whiteout_M3AnimRefF32;
24072        pub fn whiteout_m3_M3ParticleEmitter_set_horizontalFrequency(
24073            self_: *mut whiteout_M3ParticleEmitter,
24074            value: *const whiteout_M3AnimRefF32,
24075        );
24076        pub fn whiteout_m3_M3ParticleEmitter_get_verticalType(
24077            self_: *mut whiteout_M3ParticleEmitter,
24078        ) -> u32;
24079        pub fn whiteout_m3_M3ParticleEmitter_set_verticalType(
24080            self_: *mut whiteout_M3ParticleEmitter,
24081            value: u32,
24082        );
24083        pub fn whiteout_m3_M3ParticleEmitter_get_verticalAmplitude(
24084            self_: *mut whiteout_M3ParticleEmitter,
24085        ) -> *mut whiteout_M3AnimRefF32;
24086        pub fn whiteout_m3_M3ParticleEmitter_set_verticalAmplitude(
24087            self_: *mut whiteout_M3ParticleEmitter,
24088            value: *const whiteout_M3AnimRefF32,
24089        );
24090        pub fn whiteout_m3_M3ParticleEmitter_get_verticalFrequency(
24091            self_: *mut whiteout_M3ParticleEmitter,
24092        ) -> *mut whiteout_M3AnimRefF32;
24093        pub fn whiteout_m3_M3ParticleEmitter_set_verticalFrequency(
24094            self_: *mut whiteout_M3ParticleEmitter,
24095            value: *const whiteout_M3AnimRefF32,
24096        );
24097        pub fn whiteout_m3_M3ParticleEmitter_get_particleVelocity(
24098            self_: *mut whiteout_M3ParticleEmitter,
24099        ) -> *mut whiteout_M3AnimRefF32;
24100        pub fn whiteout_m3_M3ParticleEmitter_set_particleVelocity(
24101            self_: *mut whiteout_M3ParticleEmitter,
24102            value: *const whiteout_M3AnimRefF32,
24103        );
24104        pub fn whiteout_m3_M3ParticleEmitter_get_phaseShift(
24105            self_: *mut whiteout_M3ParticleEmitter,
24106        ) -> *mut whiteout_M3AnimRefF32;
24107        pub fn whiteout_m3_M3ParticleEmitter_set_phaseShift(
24108            self_: *mut whiteout_M3ParticleEmitter,
24109            value: *const whiteout_M3AnimRefF32,
24110        );
24111        pub fn whiteout_m3_M3ParticleEmitter_get_flags(
24112            self_: *mut whiteout_M3ParticleEmitter,
24113        ) -> i32;
24114        pub fn whiteout_m3_M3ParticleEmitter_set_flags(
24115            self_: *mut whiteout_M3ParticleEmitter,
24116            value: i32,
24117        );
24118        pub fn whiteout_m3_M3ParticleEmitter_get_rotationFlags(
24119            self_: *mut whiteout_M3ParticleEmitter,
24120        ) -> i32;
24121        pub fn whiteout_m3_M3ParticleEmitter_set_rotationFlags(
24122            self_: *mut whiteout_M3ParticleEmitter,
24123            value: i32,
24124        );
24125        pub fn whiteout_m3_M3ParticleEmitter_get_colorSmoothing(
24126            self_: *mut whiteout_M3ParticleEmitter,
24127        ) -> i32;
24128        pub fn whiteout_m3_M3ParticleEmitter_set_colorSmoothing(
24129            self_: *mut whiteout_M3ParticleEmitter,
24130            value: i32,
24131        );
24132        pub fn whiteout_m3_M3ParticleEmitter_get_sizeSmoothing(
24133            self_: *mut whiteout_M3ParticleEmitter,
24134        ) -> i32;
24135        pub fn whiteout_m3_M3ParticleEmitter_set_sizeSmoothing(
24136            self_: *mut whiteout_M3ParticleEmitter,
24137            value: i32,
24138        );
24139        pub fn whiteout_m3_M3ParticleEmitter_get_rotationSmoothing(
24140            self_: *mut whiteout_M3ParticleEmitter,
24141        ) -> i32;
24142        pub fn whiteout_m3_M3ParticleEmitter_set_rotationSmoothing(
24143            self_: *mut whiteout_M3ParticleEmitter,
24144            value: i32,
24145        );
24146        pub fn whiteout_m3_M3ParticleEmitter_get_alphaThreshold(
24147            self_: *mut whiteout_M3ParticleEmitter,
24148        ) -> *mut whiteout_M3AnimRefF32;
24149        pub fn whiteout_m3_M3ParticleEmitter_set_alphaThreshold(
24150            self_: *mut whiteout_M3ParticleEmitter,
24151            value: *const whiteout_M3AnimRefF32,
24152        );
24153        pub fn whiteout_m3_M3ParticleEmitter_get_uvOffset(
24154            self_: *mut whiteout_M3ParticleEmitter,
24155        ) -> *mut whiteout_M3AnimRefVector2f;
24156        pub fn whiteout_m3_M3ParticleEmitter_set_uvOffset(
24157            self_: *mut whiteout_M3ParticleEmitter,
24158            value: *const whiteout_M3AnimRefVector2f,
24159        );
24160        pub fn whiteout_m3_M3ParticleEmitter_get_uvAngle(
24161            self_: *mut whiteout_M3ParticleEmitter,
24162        ) -> *mut whiteout_M3AnimRefVector3f;
24163        pub fn whiteout_m3_M3ParticleEmitter_set_uvAngle(
24164            self_: *mut whiteout_M3ParticleEmitter,
24165            value: *const whiteout_M3AnimRefVector3f,
24166        );
24167        pub fn whiteout_m3_M3ParticleEmitter_get_uvTiling(
24168            self_: *mut whiteout_M3ParticleEmitter,
24169        ) -> *mut whiteout_M3AnimRefVector2f;
24170        pub fn whiteout_m3_M3ParticleEmitter_set_uvTiling(
24171            self_: *mut whiteout_M3ParticleEmitter,
24172            value: *const whiteout_M3AnimRefVector2f,
24173        );
24174        pub fn whiteout_m3_M3ParticleEmitter_get_splineLineData_count(
24175            self_: *mut whiteout_M3ParticleEmitter,
24176        ) -> usize;
24177        pub fn whiteout_m3_M3ParticleEmitter_resize_splineLineData(
24178            self_: *mut whiteout_M3ParticleEmitter,
24179            count: usize,
24180        );
24181        pub fn whiteout_m3_M3ParticleEmitter_get_splineLineData_at(
24182            self_: *mut whiteout_M3ParticleEmitter,
24183            index: usize,
24184        ) -> *mut whiteout_M3AnimRefVector3f;
24185        pub fn whiteout_m3_M3ParticleEmitter_get_windMultiplier(
24186            self_: *mut whiteout_M3ParticleEmitter,
24187        ) -> f32;
24188        pub fn whiteout_m3_M3ParticleEmitter_set_windMultiplier(
24189            self_: *mut whiteout_M3ParticleEmitter,
24190            value: f32,
24191        );
24192        pub fn whiteout_m3_M3ParticleEmitter_get_lodReduce(
24193            self_: *mut whiteout_M3ParticleEmitter,
24194        ) -> u32;
24195        pub fn whiteout_m3_M3ParticleEmitter_set_lodReduce(
24196            self_: *mut whiteout_M3ParticleEmitter,
24197            value: u32,
24198        );
24199        pub fn whiteout_m3_M3ParticleEmitter_get_lodCut(
24200            self_: *mut whiteout_M3ParticleEmitter,
24201        ) -> u32;
24202        pub fn whiteout_m3_M3ParticleEmitter_set_lodCut(
24203            self_: *mut whiteout_M3ParticleEmitter,
24204            value: u32,
24205        );
24206        pub fn whiteout_m3_M3ParticleEmitter_get_lowerBound(
24207            self_: *mut whiteout_M3ParticleEmitter,
24208        ) -> *mut whiteout_M3AnimRefF32;
24209        pub fn whiteout_m3_M3ParticleEmitter_set_lowerBound(
24210            self_: *mut whiteout_M3ParticleEmitter,
24211            value: *const whiteout_M3AnimRefF32,
24212        );
24213        pub fn whiteout_m3_M3ParticleEmitter_get_upperBound(
24214            self_: *mut whiteout_M3ParticleEmitter,
24215        ) -> *mut whiteout_M3AnimRefF32;
24216        pub fn whiteout_m3_M3ParticleEmitter_set_upperBound(
24217            self_: *mut whiteout_M3ParticleEmitter,
24218            value: *const whiteout_M3AnimRefF32,
24219        );
24220        pub fn whiteout_m3_M3ParticleEmitter_get_trailLinkIndex(
24221            self_: *mut whiteout_M3ParticleEmitter,
24222        ) -> i32;
24223        pub fn whiteout_m3_M3ParticleEmitter_set_trailLinkIndex(
24224            self_: *mut whiteout_M3ParticleEmitter,
24225            value: i32,
24226        );
24227        pub fn whiteout_m3_M3ParticleEmitter_get_trailChance(
24228            self_: *mut whiteout_M3ParticleEmitter,
24229        ) -> f32;
24230        pub fn whiteout_m3_M3ParticleEmitter_set_trailChance(
24231            self_: *mut whiteout_M3ParticleEmitter,
24232            value: f32,
24233        );
24234        pub fn whiteout_m3_M3ParticleEmitter_get_trailEmissionRate(
24235            self_: *mut whiteout_M3ParticleEmitter,
24236        ) -> *mut whiteout_M3AnimRefF32;
24237        pub fn whiteout_m3_M3ParticleEmitter_set_trailEmissionRate(
24238            self_: *mut whiteout_M3ParticleEmitter,
24239            value: *const whiteout_M3AnimRefF32,
24240        );
24241        pub fn whiteout_m3_M3ParticleEmitter_get_splatProjectionIndex(
24242            self_: *mut whiteout_M3ParticleEmitter,
24243        ) -> i32;
24244        pub fn whiteout_m3_M3ParticleEmitter_set_splatProjectionIndex(
24245            self_: *mut whiteout_M3ParticleEmitter,
24246            value: i32,
24247        );
24248        pub fn whiteout_m3_M3ParticleEmitter_get_splatChance(
24249            self_: *mut whiteout_M3ParticleEmitter,
24250        ) -> f32;
24251        pub fn whiteout_m3_M3ParticleEmitter_set_splatChance(
24252            self_: *mut whiteout_M3ParticleEmitter,
24253            value: f32,
24254        );
24255        pub fn whiteout_m3_M3ParticleEmitter_get_copyIndices_count(
24256            self_: *mut whiteout_M3ParticleEmitter,
24257        ) -> usize;
24258        pub fn whiteout_m3_M3ParticleEmitter_resize_copyIndices(
24259            self_: *mut whiteout_M3ParticleEmitter,
24260            count: usize,
24261        );
24262        pub fn whiteout_m3_M3ParticleEmitter_get_copyIndices_data(
24263            self_: *mut whiteout_M3ParticleEmitter,
24264        ) -> *const u32;
24265        pub fn whiteout_m3_M3ParticleEmitter_assign_copyIndices(
24266            self_: *mut whiteout_M3ParticleEmitter,
24267            data: *const u32,
24268            count: usize,
24269        );
24270        pub fn whiteout_m3_M3ParticleEmitter_get_spawnRibbonOnBounceChance(
24271            self_: *mut whiteout_M3ParticleEmitter,
24272        ) -> f32;
24273        pub fn whiteout_m3_M3ParticleEmitter_set_spawnRibbonOnBounceChance(
24274            self_: *mut whiteout_M3ParticleEmitter,
24275            value: f32,
24276        );
24277        pub fn whiteout_m3_M3ParticleEmitter_get_ribbonLinkIndex(
24278            self_: *mut whiteout_M3ParticleEmitter,
24279        ) -> i32;
24280        pub fn whiteout_m3_M3ParticleEmitter_set_ribbonLinkIndex(
24281            self_: *mut whiteout_M3ParticleEmitter,
24282            value: i32,
24283        );
24284        // ParticleEmitterCopy
24285        pub fn whiteout_m3_M3ParticleEmitterCopy_new() -> *mut whiteout_M3ParticleEmitterCopy;
24286        pub fn whiteout_m3_M3ParticleEmitterCopy_delete(self_: *mut whiteout_M3ParticleEmitterCopy);
24287        pub fn whiteout_m3_M3ParticleEmitterCopy_get_emissionRate(
24288            self_: *mut whiteout_M3ParticleEmitterCopy,
24289        ) -> *mut whiteout_M3AnimRefF32;
24290        pub fn whiteout_m3_M3ParticleEmitterCopy_set_emissionRate(
24291            self_: *mut whiteout_M3ParticleEmitterCopy,
24292            value: *const whiteout_M3AnimRefF32,
24293        );
24294        pub fn whiteout_m3_M3ParticleEmitterCopy_get_squirtAmount(
24295            self_: *mut whiteout_M3ParticleEmitterCopy,
24296        ) -> *mut whiteout_M3AnimRefU16;
24297        pub fn whiteout_m3_M3ParticleEmitterCopy_set_squirtAmount(
24298            self_: *mut whiteout_M3ParticleEmitterCopy,
24299            value: *const whiteout_M3AnimRefU16,
24300        );
24301        pub fn whiteout_m3_M3ParticleEmitterCopy_get_boneIndex(
24302            self_: *mut whiteout_M3ParticleEmitterCopy,
24303        ) -> u32;
24304        pub fn whiteout_m3_M3ParticleEmitterCopy_set_boneIndex(
24305            self_: *mut whiteout_M3ParticleEmitterCopy,
24306            value: u32,
24307        );
24308        // SplineRibbon
24309        pub fn whiteout_m3_M3SplineRibbon_new() -> *mut whiteout_M3SplineRibbon;
24310        pub fn whiteout_m3_M3SplineRibbon_delete(self_: *mut whiteout_M3SplineRibbon);
24311        pub fn whiteout_m3_M3SplineRibbon_get_emissionOffset(
24312            self_: *mut whiteout_M3SplineRibbon,
24313        ) -> *mut core::ffi::c_void;
24314        pub fn whiteout_m3_M3SplineRibbon_set_emissionOffset(
24315            self_: *mut whiteout_M3SplineRibbon,
24316            value: *const core::ffi::c_void,
24317        );
24318        pub fn whiteout_m3_M3SplineRibbon_get_emissionVector(
24319            self_: *mut whiteout_M3SplineRibbon,
24320        ) -> *mut core::ffi::c_void;
24321        pub fn whiteout_m3_M3SplineRibbon_set_emissionVector(
24322            self_: *mut whiteout_M3SplineRibbon,
24323            value: *const core::ffi::c_void,
24324        );
24325        pub fn whiteout_m3_M3SplineRibbon_get_velocity(
24326            self_: *mut whiteout_M3SplineRibbon,
24327        ) -> *mut whiteout_M3AnimRefF32;
24328        pub fn whiteout_m3_M3SplineRibbon_set_velocity(
24329            self_: *mut whiteout_M3SplineRibbon,
24330            value: *const whiteout_M3AnimRefF32,
24331        );
24332        pub fn whiteout_m3_M3SplineRibbon_get_reserved(self_: *mut whiteout_M3SplineRibbon) -> u32;
24333        pub fn whiteout_m3_M3SplineRibbon_set_reserved(
24334            self_: *mut whiteout_M3SplineRibbon,
24335            value: u32,
24336        );
24337        pub fn whiteout_m3_M3SplineRibbon_get_boneIndex(self_: *mut whiteout_M3SplineRibbon)
24338            -> u32;
24339        pub fn whiteout_m3_M3SplineRibbon_set_boneIndex(
24340            self_: *mut whiteout_M3SplineRibbon,
24341            value: u32,
24342        );
24343        pub fn whiteout_m3_M3SplineRibbon_get_velocityBaseFactor(
24344            self_: *mut whiteout_M3SplineRibbon,
24345        ) -> *mut whiteout_M3AnimRefF32;
24346        pub fn whiteout_m3_M3SplineRibbon_set_velocityBaseFactor(
24347            self_: *mut whiteout_M3SplineRibbon,
24348            value: *const whiteout_M3AnimRefF32,
24349        );
24350        pub fn whiteout_m3_M3SplineRibbon_get_velocityEndFactor(
24351            self_: *mut whiteout_M3SplineRibbon,
24352        ) -> *mut whiteout_M3AnimRefF32;
24353        pub fn whiteout_m3_M3SplineRibbon_set_velocityEndFactor(
24354            self_: *mut whiteout_M3SplineRibbon,
24355            value: *const whiteout_M3AnimRefF32,
24356        );
24357        pub fn whiteout_m3_M3SplineRibbon_get_yawType(self_: *mut whiteout_M3SplineRibbon) -> u32;
24358        pub fn whiteout_m3_M3SplineRibbon_set_yawType(
24359            self_: *mut whiteout_M3SplineRibbon,
24360            value: u32,
24361        );
24362        pub fn whiteout_m3_M3SplineRibbon_get_yawAmplitude(
24363            self_: *mut whiteout_M3SplineRibbon,
24364        ) -> *mut whiteout_M3AnimRefF32;
24365        pub fn whiteout_m3_M3SplineRibbon_set_yawAmplitude(
24366            self_: *mut whiteout_M3SplineRibbon,
24367            value: *const whiteout_M3AnimRefF32,
24368        );
24369        pub fn whiteout_m3_M3SplineRibbon_get_yawFrequency(
24370            self_: *mut whiteout_M3SplineRibbon,
24371        ) -> *mut whiteout_M3AnimRefF32;
24372        pub fn whiteout_m3_M3SplineRibbon_set_yawFrequency(
24373            self_: *mut whiteout_M3SplineRibbon,
24374            value: *const whiteout_M3AnimRefF32,
24375        );
24376        pub fn whiteout_m3_M3SplineRibbon_get_pitchType(self_: *mut whiteout_M3SplineRibbon)
24377            -> u32;
24378        pub fn whiteout_m3_M3SplineRibbon_set_pitchType(
24379            self_: *mut whiteout_M3SplineRibbon,
24380            value: u32,
24381        );
24382        pub fn whiteout_m3_M3SplineRibbon_get_pitchAmplitude(
24383            self_: *mut whiteout_M3SplineRibbon,
24384        ) -> *mut whiteout_M3AnimRefF32;
24385        pub fn whiteout_m3_M3SplineRibbon_set_pitchAmplitude(
24386            self_: *mut whiteout_M3SplineRibbon,
24387            value: *const whiteout_M3AnimRefF32,
24388        );
24389        pub fn whiteout_m3_M3SplineRibbon_get_pitchFrequency(
24390            self_: *mut whiteout_M3SplineRibbon,
24391        ) -> *mut whiteout_M3AnimRefF32;
24392        pub fn whiteout_m3_M3SplineRibbon_set_pitchFrequency(
24393            self_: *mut whiteout_M3SplineRibbon,
24394            value: *const whiteout_M3AnimRefF32,
24395        );
24396        pub fn whiteout_m3_M3SplineRibbon_get_velocityType(
24397            self_: *mut whiteout_M3SplineRibbon,
24398        ) -> u32;
24399        pub fn whiteout_m3_M3SplineRibbon_set_velocityType(
24400            self_: *mut whiteout_M3SplineRibbon,
24401            value: u32,
24402        );
24403        pub fn whiteout_m3_M3SplineRibbon_get_velocityAmplitude(
24404            self_: *mut whiteout_M3SplineRibbon,
24405        ) -> *mut whiteout_M3AnimRefF32;
24406        pub fn whiteout_m3_M3SplineRibbon_set_velocityAmplitude(
24407            self_: *mut whiteout_M3SplineRibbon,
24408            value: *const whiteout_M3AnimRefF32,
24409        );
24410        pub fn whiteout_m3_M3SplineRibbon_get_velocityFrequency(
24411            self_: *mut whiteout_M3SplineRibbon,
24412        ) -> *mut whiteout_M3AnimRefF32;
24413        pub fn whiteout_m3_M3SplineRibbon_set_velocityFrequency(
24414            self_: *mut whiteout_M3SplineRibbon,
24415            value: *const whiteout_M3AnimRefF32,
24416        );
24417        pub fn whiteout_m3_M3SplineRibbon_get_yaw(
24418            self_: *mut whiteout_M3SplineRibbon,
24419        ) -> *mut whiteout_M3AnimRefF32;
24420        pub fn whiteout_m3_M3SplineRibbon_set_yaw(
24421            self_: *mut whiteout_M3SplineRibbon,
24422            value: *const whiteout_M3AnimRefF32,
24423        );
24424        pub fn whiteout_m3_M3SplineRibbon_get_pitch(
24425            self_: *mut whiteout_M3SplineRibbon,
24426        ) -> *mut whiteout_M3AnimRefF32;
24427        pub fn whiteout_m3_M3SplineRibbon_set_pitch(
24428            self_: *mut whiteout_M3SplineRibbon,
24429            value: *const whiteout_M3AnimRefF32,
24430        );
24431        pub fn whiteout_m3_M3SplineRibbon_get_emissionVectorNormFactor(
24432            self_: *mut whiteout_M3SplineRibbon,
24433        ) -> f32;
24434        pub fn whiteout_m3_M3SplineRibbon_set_emissionVectorNormFactor(
24435            self_: *mut whiteout_M3SplineRibbon,
24436            value: f32,
24437        );
24438        pub fn whiteout_m3_M3SplineRibbon_get_velocityNormFactor(
24439            self_: *mut whiteout_M3SplineRibbon,
24440        ) -> f32;
24441        pub fn whiteout_m3_M3SplineRibbon_set_velocityNormFactor(
24442            self_: *mut whiteout_M3SplineRibbon,
24443            value: f32,
24444        );
24445        // RibbonEmitter
24446        pub fn whiteout_m3_M3RibbonEmitter_new() -> *mut whiteout_M3RibbonEmitter;
24447        pub fn whiteout_m3_M3RibbonEmitter_delete(self_: *mut whiteout_M3RibbonEmitter);
24448        pub fn whiteout_m3_M3RibbonEmitter_get_boneIndex(
24449            self_: *mut whiteout_M3RibbonEmitter,
24450        ) -> u16;
24451        pub fn whiteout_m3_M3RibbonEmitter_set_boneIndex(
24452            self_: *mut whiteout_M3RibbonEmitter,
24453            value: u16,
24454        );
24455        pub fn whiteout_m3_M3RibbonEmitter_get_boneIndexFallback(
24456            self_: *mut whiteout_M3RibbonEmitter,
24457        ) -> u16;
24458        pub fn whiteout_m3_M3RibbonEmitter_set_boneIndexFallback(
24459            self_: *mut whiteout_M3RibbonEmitter,
24460            value: u16,
24461        );
24462        pub fn whiteout_m3_M3RibbonEmitter_get_materialIndex(
24463            self_: *mut whiteout_M3RibbonEmitter,
24464        ) -> u32;
24465        pub fn whiteout_m3_M3RibbonEmitter_set_materialIndex(
24466            self_: *mut whiteout_M3RibbonEmitter,
24467            value: u32,
24468        );
24469        pub fn whiteout_m3_M3RibbonEmitter_get_additionalFlags(
24470            self_: *mut whiteout_M3RibbonEmitter,
24471        ) -> i32;
24472        pub fn whiteout_m3_M3RibbonEmitter_set_additionalFlags(
24473            self_: *mut whiteout_M3RibbonEmitter,
24474            value: i32,
24475        );
24476        pub fn whiteout_m3_M3RibbonEmitter_get_initialSpeed(
24477            self_: *mut whiteout_M3RibbonEmitter,
24478        ) -> *mut whiteout_M3AnimRefF32;
24479        pub fn whiteout_m3_M3RibbonEmitter_set_initialSpeed(
24480            self_: *mut whiteout_M3RibbonEmitter,
24481            value: *const whiteout_M3AnimRefF32,
24482        );
24483        pub fn whiteout_m3_M3RibbonEmitter_get_initialSpeedRandom(
24484            self_: *mut whiteout_M3RibbonEmitter,
24485        ) -> *mut whiteout_M3AnimRefF32;
24486        pub fn whiteout_m3_M3RibbonEmitter_set_initialSpeedRandom(
24487            self_: *mut whiteout_M3RibbonEmitter,
24488            value: *const whiteout_M3AnimRefF32,
24489        );
24490        pub fn whiteout_m3_M3RibbonEmitter_get_initialYaw(
24491            self_: *mut whiteout_M3RibbonEmitter,
24492        ) -> *mut whiteout_M3AnimRefF32;
24493        pub fn whiteout_m3_M3RibbonEmitter_set_initialYaw(
24494            self_: *mut whiteout_M3RibbonEmitter,
24495            value: *const whiteout_M3AnimRefF32,
24496        );
24497        pub fn whiteout_m3_M3RibbonEmitter_get_initialPitch(
24498            self_: *mut whiteout_M3RibbonEmitter,
24499        ) -> *mut whiteout_M3AnimRefF32;
24500        pub fn whiteout_m3_M3RibbonEmitter_set_initialPitch(
24501            self_: *mut whiteout_M3RibbonEmitter,
24502            value: *const whiteout_M3AnimRefF32,
24503        );
24504        pub fn whiteout_m3_M3RibbonEmitter_get_initialHorizontal(
24505            self_: *mut whiteout_M3RibbonEmitter,
24506        ) -> *mut whiteout_M3AnimRefF32;
24507        pub fn whiteout_m3_M3RibbonEmitter_set_initialHorizontal(
24508            self_: *mut whiteout_M3RibbonEmitter,
24509            value: *const whiteout_M3AnimRefF32,
24510        );
24511        pub fn whiteout_m3_M3RibbonEmitter_get_initialVertical(
24512            self_: *mut whiteout_M3RibbonEmitter,
24513        ) -> *mut whiteout_M3AnimRefF32;
24514        pub fn whiteout_m3_M3RibbonEmitter_set_initialVertical(
24515            self_: *mut whiteout_M3RibbonEmitter,
24516            value: *const whiteout_M3AnimRefF32,
24517        );
24518        pub fn whiteout_m3_M3RibbonEmitter_get_lifetime(
24519            self_: *mut whiteout_M3RibbonEmitter,
24520        ) -> *mut whiteout_M3AnimRefF32;
24521        pub fn whiteout_m3_M3RibbonEmitter_set_lifetime(
24522            self_: *mut whiteout_M3RibbonEmitter,
24523            value: *const whiteout_M3AnimRefF32,
24524        );
24525        pub fn whiteout_m3_M3RibbonEmitter_get_lifetimeRandom(
24526            self_: *mut whiteout_M3RibbonEmitter,
24527        ) -> *mut whiteout_M3AnimRefF32;
24528        pub fn whiteout_m3_M3RibbonEmitter_set_lifetimeRandom(
24529            self_: *mut whiteout_M3RibbonEmitter,
24530            value: *const whiteout_M3AnimRefF32,
24531        );
24532        pub fn whiteout_m3_M3RibbonEmitter_get_killRadius(
24533            self_: *mut whiteout_M3RibbonEmitter,
24534        ) -> u32;
24535        pub fn whiteout_m3_M3RibbonEmitter_set_killRadius(
24536            self_: *mut whiteout_M3RibbonEmitter,
24537            value: u32,
24538        );
24539        pub fn whiteout_m3_M3RibbonEmitter_get_gravityX(
24540            self_: *mut whiteout_M3RibbonEmitter,
24541        ) -> f32;
24542        pub fn whiteout_m3_M3RibbonEmitter_set_gravityX(
24543            self_: *mut whiteout_M3RibbonEmitter,
24544            value: f32,
24545        );
24546        pub fn whiteout_m3_M3RibbonEmitter_get_gravityY(
24547            self_: *mut whiteout_M3RibbonEmitter,
24548        ) -> f32;
24549        pub fn whiteout_m3_M3RibbonEmitter_set_gravityY(
24550            self_: *mut whiteout_M3RibbonEmitter,
24551            value: f32,
24552        );
24553        pub fn whiteout_m3_M3RibbonEmitter_get_gravity(self_: *mut whiteout_M3RibbonEmitter)
24554            -> f32;
24555        pub fn whiteout_m3_M3RibbonEmitter_set_gravity(
24556            self_: *mut whiteout_M3RibbonEmitter,
24557            value: f32,
24558        );
24559        pub fn whiteout_m3_M3RibbonEmitter_get_sizeMidTime(
24560            self_: *mut whiteout_M3RibbonEmitter,
24561        ) -> f32;
24562        pub fn whiteout_m3_M3RibbonEmitter_set_sizeMidTime(
24563            self_: *mut whiteout_M3RibbonEmitter,
24564            value: f32,
24565        );
24566        pub fn whiteout_m3_M3RibbonEmitter_get_colorMidTime(
24567            self_: *mut whiteout_M3RibbonEmitter,
24568        ) -> f32;
24569        pub fn whiteout_m3_M3RibbonEmitter_set_colorMidTime(
24570            self_: *mut whiteout_M3RibbonEmitter,
24571            value: f32,
24572        );
24573        pub fn whiteout_m3_M3RibbonEmitter_get_alphaMidTime(
24574            self_: *mut whiteout_M3RibbonEmitter,
24575        ) -> f32;
24576        pub fn whiteout_m3_M3RibbonEmitter_set_alphaMidTime(
24577            self_: *mut whiteout_M3RibbonEmitter,
24578            value: f32,
24579        );
24580        pub fn whiteout_m3_M3RibbonEmitter_get_rotationMidTime(
24581            self_: *mut whiteout_M3RibbonEmitter,
24582        ) -> f32;
24583        pub fn whiteout_m3_M3RibbonEmitter_set_rotationMidTime(
24584            self_: *mut whiteout_M3RibbonEmitter,
24585            value: f32,
24586        );
24587        pub fn whiteout_m3_M3RibbonEmitter_get_sizeMidHoldTime(
24588            self_: *mut whiteout_M3RibbonEmitter,
24589        ) -> f32;
24590        pub fn whiteout_m3_M3RibbonEmitter_set_sizeMidHoldTime(
24591            self_: *mut whiteout_M3RibbonEmitter,
24592            value: f32,
24593        );
24594        pub fn whiteout_m3_M3RibbonEmitter_get_colorMidHoldTime(
24595            self_: *mut whiteout_M3RibbonEmitter,
24596        ) -> f32;
24597        pub fn whiteout_m3_M3RibbonEmitter_set_colorMidHoldTime(
24598            self_: *mut whiteout_M3RibbonEmitter,
24599            value: f32,
24600        );
24601        pub fn whiteout_m3_M3RibbonEmitter_get_alphaMidHoldTime(
24602            self_: *mut whiteout_M3RibbonEmitter,
24603        ) -> f32;
24604        pub fn whiteout_m3_M3RibbonEmitter_set_alphaMidHoldTime(
24605            self_: *mut whiteout_M3RibbonEmitter,
24606            value: f32,
24607        );
24608        pub fn whiteout_m3_M3RibbonEmitter_get_rotationMidHoldTime(
24609            self_: *mut whiteout_M3RibbonEmitter,
24610        ) -> f32;
24611        pub fn whiteout_m3_M3RibbonEmitter_set_rotationMidHoldTime(
24612            self_: *mut whiteout_M3RibbonEmitter,
24613            value: f32,
24614        );
24615        pub fn whiteout_m3_M3RibbonEmitter_get_sizeAnimation(
24616            self_: *mut whiteout_M3RibbonEmitter,
24617        ) -> *mut whiteout_M3AnimRefVector3f;
24618        pub fn whiteout_m3_M3RibbonEmitter_set_sizeAnimation(
24619            self_: *mut whiteout_M3RibbonEmitter,
24620            value: *const whiteout_M3AnimRefVector3f,
24621        );
24622        pub fn whiteout_m3_M3RibbonEmitter_get_rotationAnimation(
24623            self_: *mut whiteout_M3RibbonEmitter,
24624        ) -> *mut whiteout_M3AnimRefVector3f;
24625        pub fn whiteout_m3_M3RibbonEmitter_set_rotationAnimation(
24626            self_: *mut whiteout_M3RibbonEmitter,
24627            value: *const whiteout_M3AnimRefVector3f,
24628        );
24629        pub fn whiteout_m3_M3RibbonEmitter_get_colorStart(
24630            self_: *mut whiteout_M3RibbonEmitter,
24631        ) -> *mut whiteout_M3AnimRefM3ColorBGRA;
24632        pub fn whiteout_m3_M3RibbonEmitter_set_colorStart(
24633            self_: *mut whiteout_M3RibbonEmitter,
24634            value: *const whiteout_M3AnimRefM3ColorBGRA,
24635        );
24636        pub fn whiteout_m3_M3RibbonEmitter_get_colorMid(
24637            self_: *mut whiteout_M3RibbonEmitter,
24638        ) -> *mut whiteout_M3AnimRefM3ColorBGRA;
24639        pub fn whiteout_m3_M3RibbonEmitter_set_colorMid(
24640            self_: *mut whiteout_M3RibbonEmitter,
24641            value: *const whiteout_M3AnimRefM3ColorBGRA,
24642        );
24643        pub fn whiteout_m3_M3RibbonEmitter_get_colorEnd(
24644            self_: *mut whiteout_M3RibbonEmitter,
24645        ) -> *mut whiteout_M3AnimRefM3ColorBGRA;
24646        pub fn whiteout_m3_M3RibbonEmitter_set_colorEnd(
24647            self_: *mut whiteout_M3RibbonEmitter,
24648            value: *const whiteout_M3AnimRefM3ColorBGRA,
24649        );
24650        pub fn whiteout_m3_M3RibbonEmitter_get_drag(self_: *mut whiteout_M3RibbonEmitter) -> f32;
24651        pub fn whiteout_m3_M3RibbonEmitter_set_drag(
24652            self_: *mut whiteout_M3RibbonEmitter,
24653            value: f32,
24654        );
24655        pub fn whiteout_m3_M3RibbonEmitter_get_mass(self_: *mut whiteout_M3RibbonEmitter) -> f32;
24656        pub fn whiteout_m3_M3RibbonEmitter_set_mass(
24657            self_: *mut whiteout_M3RibbonEmitter,
24658            value: f32,
24659        );
24660        pub fn whiteout_m3_M3RibbonEmitter_get_massRandom(
24661            self_: *mut whiteout_M3RibbonEmitter,
24662        ) -> f32;
24663        pub fn whiteout_m3_M3RibbonEmitter_set_massRandom(
24664            self_: *mut whiteout_M3RibbonEmitter,
24665            value: f32,
24666        );
24667        pub fn whiteout_m3_M3RibbonEmitter_get_massSizeMultiplier(
24668            self_: *mut whiteout_M3RibbonEmitter,
24669        ) -> f32;
24670        pub fn whiteout_m3_M3RibbonEmitter_set_massSizeMultiplier(
24671            self_: *mut whiteout_M3RibbonEmitter,
24672            value: f32,
24673        );
24674        pub fn whiteout_m3_M3RibbonEmitter_get_localForces(
24675            self_: *mut whiteout_M3RibbonEmitter,
24676        ) -> u16;
24677        pub fn whiteout_m3_M3RibbonEmitter_set_localForces(
24678            self_: *mut whiteout_M3RibbonEmitter,
24679            value: u16,
24680        );
24681        pub fn whiteout_m3_M3RibbonEmitter_get_worldForces(
24682            self_: *mut whiteout_M3RibbonEmitter,
24683        ) -> u16;
24684        pub fn whiteout_m3_M3RibbonEmitter_set_worldForces(
24685            self_: *mut whiteout_M3RibbonEmitter,
24686            value: u16,
24687        );
24688        pub fn whiteout_m3_M3RibbonEmitter_get_localForcesFallback(
24689            self_: *mut whiteout_M3RibbonEmitter,
24690        ) -> u16;
24691        pub fn whiteout_m3_M3RibbonEmitter_set_localForcesFallback(
24692            self_: *mut whiteout_M3RibbonEmitter,
24693            value: u16,
24694        );
24695        pub fn whiteout_m3_M3RibbonEmitter_get_worldForcesFallback(
24696            self_: *mut whiteout_M3RibbonEmitter,
24697        ) -> u16;
24698        pub fn whiteout_m3_M3RibbonEmitter_set_worldForcesFallback(
24699            self_: *mut whiteout_M3RibbonEmitter,
24700            value: u16,
24701        );
24702        pub fn whiteout_m3_M3RibbonEmitter_get_worldForcesMassMultiplier(
24703            self_: *mut whiteout_M3RibbonEmitter,
24704        ) -> f32;
24705        pub fn whiteout_m3_M3RibbonEmitter_set_worldForcesMassMultiplier(
24706            self_: *mut whiteout_M3RibbonEmitter,
24707            value: f32,
24708        );
24709        pub fn whiteout_m3_M3RibbonEmitter_get_noiseAmplitude(
24710            self_: *mut whiteout_M3RibbonEmitter,
24711        ) -> f32;
24712        pub fn whiteout_m3_M3RibbonEmitter_set_noiseAmplitude(
24713            self_: *mut whiteout_M3RibbonEmitter,
24714            value: f32,
24715        );
24716        pub fn whiteout_m3_M3RibbonEmitter_get_noiseFrequency(
24717            self_: *mut whiteout_M3RibbonEmitter,
24718        ) -> f32;
24719        pub fn whiteout_m3_M3RibbonEmitter_set_noiseFrequency(
24720            self_: *mut whiteout_M3RibbonEmitter,
24721            value: f32,
24722        );
24723        pub fn whiteout_m3_M3RibbonEmitter_get_noiseCoherence(
24724            self_: *mut whiteout_M3RibbonEmitter,
24725        ) -> f32;
24726        pub fn whiteout_m3_M3RibbonEmitter_set_noiseCoherence(
24727            self_: *mut whiteout_M3RibbonEmitter,
24728            value: f32,
24729        );
24730        pub fn whiteout_m3_M3RibbonEmitter_get_noiseEdge(
24731            self_: *mut whiteout_M3RibbonEmitter,
24732        ) -> f32;
24733        pub fn whiteout_m3_M3RibbonEmitter_set_noiseEdge(
24734            self_: *mut whiteout_M3RibbonEmitter,
24735            value: f32,
24736        );
24737        pub fn whiteout_m3_M3RibbonEmitter_get_indexPlusLength(
24738            self_: *mut whiteout_M3RibbonEmitter,
24739        ) -> u32;
24740        pub fn whiteout_m3_M3RibbonEmitter_set_indexPlusLength(
24741            self_: *mut whiteout_M3RibbonEmitter,
24742            value: u32,
24743        );
24744        pub fn whiteout_m3_M3RibbonEmitter_get_emitterShape(
24745            self_: *mut whiteout_M3RibbonEmitter,
24746        ) -> u32;
24747        pub fn whiteout_m3_M3RibbonEmitter_set_emitterShape(
24748            self_: *mut whiteout_M3RibbonEmitter,
24749            value: u32,
24750        );
24751        pub fn whiteout_m3_M3RibbonEmitter_get_ribbonType(
24752            self_: *mut whiteout_M3RibbonEmitter,
24753        ) -> i32;
24754        pub fn whiteout_m3_M3RibbonEmitter_set_ribbonType(
24755            self_: *mut whiteout_M3RibbonEmitter,
24756            value: i32,
24757        );
24758        pub fn whiteout_m3_M3RibbonEmitter_get_divisions(
24759            self_: *mut whiteout_M3RibbonEmitter,
24760        ) -> f32;
24761        pub fn whiteout_m3_M3RibbonEmitter_set_divisions(
24762            self_: *mut whiteout_M3RibbonEmitter,
24763            value: f32,
24764        );
24765        pub fn whiteout_m3_M3RibbonEmitter_get_edges(self_: *mut whiteout_M3RibbonEmitter) -> u32;
24766        pub fn whiteout_m3_M3RibbonEmitter_set_edges(
24767            self_: *mut whiteout_M3RibbonEmitter,
24768            value: u32,
24769        );
24770        pub fn whiteout_m3_M3RibbonEmitter_get_innerRadius(
24771            self_: *mut whiteout_M3RibbonEmitter,
24772        ) -> f32;
24773        pub fn whiteout_m3_M3RibbonEmitter_set_innerRadius(
24774            self_: *mut whiteout_M3RibbonEmitter,
24775            value: f32,
24776        );
24777        pub fn whiteout_m3_M3RibbonEmitter_get_maxLength(
24778            self_: *mut whiteout_M3RibbonEmitter,
24779        ) -> *mut whiteout_M3AnimRefF32;
24780        pub fn whiteout_m3_M3RibbonEmitter_set_maxLength(
24781            self_: *mut whiteout_M3RibbonEmitter,
24782            value: *const whiteout_M3AnimRefF32,
24783        );
24784        pub fn whiteout_m3_M3RibbonEmitter_get_splineRibbons_count(
24785            self_: *mut whiteout_M3RibbonEmitter,
24786        ) -> usize;
24787        pub fn whiteout_m3_M3RibbonEmitter_resize_splineRibbons(
24788            self_: *mut whiteout_M3RibbonEmitter,
24789            count: usize,
24790        );
24791        pub fn whiteout_m3_M3RibbonEmitter_get_splineRibbons_at(
24792            self_: *mut whiteout_M3RibbonEmitter,
24793            index: usize,
24794        ) -> *mut whiteout_M3SplineRibbon;
24795        pub fn whiteout_m3_M3RibbonEmitter_get_active(
24796            self_: *mut whiteout_M3RibbonEmitter,
24797        ) -> *mut whiteout_M3AnimRefU32;
24798        pub fn whiteout_m3_M3RibbonEmitter_set_active(
24799            self_: *mut whiteout_M3RibbonEmitter,
24800            value: *const whiteout_M3AnimRefU32,
24801        );
24802        pub fn whiteout_m3_M3RibbonEmitter_get_flags(self_: *mut whiteout_M3RibbonEmitter) -> i32;
24803        pub fn whiteout_m3_M3RibbonEmitter_set_flags(
24804            self_: *mut whiteout_M3RibbonEmitter,
24805            value: i32,
24806        );
24807        pub fn whiteout_m3_M3RibbonEmitter_get_sizeSmoothing(
24808            self_: *mut whiteout_M3RibbonEmitter,
24809        ) -> i32;
24810        pub fn whiteout_m3_M3RibbonEmitter_set_sizeSmoothing(
24811            self_: *mut whiteout_M3RibbonEmitter,
24812            value: i32,
24813        );
24814        pub fn whiteout_m3_M3RibbonEmitter_get_colorSmoothing(
24815            self_: *mut whiteout_M3RibbonEmitter,
24816        ) -> i32;
24817        pub fn whiteout_m3_M3RibbonEmitter_set_colorSmoothing(
24818            self_: *mut whiteout_M3RibbonEmitter,
24819            value: i32,
24820        );
24821        pub fn whiteout_m3_M3RibbonEmitter_get_friction(
24822            self_: *mut whiteout_M3RibbonEmitter,
24823        ) -> f32;
24824        pub fn whiteout_m3_M3RibbonEmitter_set_friction(
24825            self_: *mut whiteout_M3RibbonEmitter,
24826            value: f32,
24827        );
24828        pub fn whiteout_m3_M3RibbonEmitter_get_bounce(self_: *mut whiteout_M3RibbonEmitter) -> f32;
24829        pub fn whiteout_m3_M3RibbonEmitter_set_bounce(
24830            self_: *mut whiteout_M3RibbonEmitter,
24831            value: f32,
24832        );
24833        pub fn whiteout_m3_M3RibbonEmitter_get_lodReduce(
24834            self_: *mut whiteout_M3RibbonEmitter,
24835        ) -> u32;
24836        pub fn whiteout_m3_M3RibbonEmitter_set_lodReduce(
24837            self_: *mut whiteout_M3RibbonEmitter,
24838            value: u32,
24839        );
24840        pub fn whiteout_m3_M3RibbonEmitter_get_lodCut(self_: *mut whiteout_M3RibbonEmitter) -> u32;
24841        pub fn whiteout_m3_M3RibbonEmitter_set_lodCut(
24842            self_: *mut whiteout_M3RibbonEmitter,
24843            value: u32,
24844        );
24845        pub fn whiteout_m3_M3RibbonEmitter_get_yawType(self_: *mut whiteout_M3RibbonEmitter)
24846            -> u32;
24847        pub fn whiteout_m3_M3RibbonEmitter_set_yawType(
24848            self_: *mut whiteout_M3RibbonEmitter,
24849            value: u32,
24850        );
24851        pub fn whiteout_m3_M3RibbonEmitter_get_yawAmplitude(
24852            self_: *mut whiteout_M3RibbonEmitter,
24853        ) -> *mut whiteout_M3AnimRefF32;
24854        pub fn whiteout_m3_M3RibbonEmitter_set_yawAmplitude(
24855            self_: *mut whiteout_M3RibbonEmitter,
24856            value: *const whiteout_M3AnimRefF32,
24857        );
24858        pub fn whiteout_m3_M3RibbonEmitter_get_yawFrequency(
24859            self_: *mut whiteout_M3RibbonEmitter,
24860        ) -> *mut whiteout_M3AnimRefF32;
24861        pub fn whiteout_m3_M3RibbonEmitter_set_yawFrequency(
24862            self_: *mut whiteout_M3RibbonEmitter,
24863            value: *const whiteout_M3AnimRefF32,
24864        );
24865        pub fn whiteout_m3_M3RibbonEmitter_get_pitchType(
24866            self_: *mut whiteout_M3RibbonEmitter,
24867        ) -> u32;
24868        pub fn whiteout_m3_M3RibbonEmitter_set_pitchType(
24869            self_: *mut whiteout_M3RibbonEmitter,
24870            value: u32,
24871        );
24872        pub fn whiteout_m3_M3RibbonEmitter_get_pitchAmplitude(
24873            self_: *mut whiteout_M3RibbonEmitter,
24874        ) -> *mut whiteout_M3AnimRefF32;
24875        pub fn whiteout_m3_M3RibbonEmitter_set_pitchAmplitude(
24876            self_: *mut whiteout_M3RibbonEmitter,
24877            value: *const whiteout_M3AnimRefF32,
24878        );
24879        pub fn whiteout_m3_M3RibbonEmitter_get_pitchFrequency(
24880            self_: *mut whiteout_M3RibbonEmitter,
24881        ) -> *mut whiteout_M3AnimRefF32;
24882        pub fn whiteout_m3_M3RibbonEmitter_set_pitchFrequency(
24883            self_: *mut whiteout_M3RibbonEmitter,
24884            value: *const whiteout_M3AnimRefF32,
24885        );
24886        pub fn whiteout_m3_M3RibbonEmitter_get_speedType(
24887            self_: *mut whiteout_M3RibbonEmitter,
24888        ) -> u32;
24889        pub fn whiteout_m3_M3RibbonEmitter_set_speedType(
24890            self_: *mut whiteout_M3RibbonEmitter,
24891            value: u32,
24892        );
24893        pub fn whiteout_m3_M3RibbonEmitter_get_speedAmplitude(
24894            self_: *mut whiteout_M3RibbonEmitter,
24895        ) -> *mut whiteout_M3AnimRefF32;
24896        pub fn whiteout_m3_M3RibbonEmitter_set_speedAmplitude(
24897            self_: *mut whiteout_M3RibbonEmitter,
24898            value: *const whiteout_M3AnimRefF32,
24899        );
24900        pub fn whiteout_m3_M3RibbonEmitter_get_speedFrequency(
24901            self_: *mut whiteout_M3RibbonEmitter,
24902        ) -> *mut whiteout_M3AnimRefF32;
24903        pub fn whiteout_m3_M3RibbonEmitter_set_speedFrequency(
24904            self_: *mut whiteout_M3RibbonEmitter,
24905            value: *const whiteout_M3AnimRefF32,
24906        );
24907        pub fn whiteout_m3_M3RibbonEmitter_get_sizeType(
24908            self_: *mut whiteout_M3RibbonEmitter,
24909        ) -> u32;
24910        pub fn whiteout_m3_M3RibbonEmitter_set_sizeType(
24911            self_: *mut whiteout_M3RibbonEmitter,
24912            value: u32,
24913        );
24914        pub fn whiteout_m3_M3RibbonEmitter_get_sizeAmplitude(
24915            self_: *mut whiteout_M3RibbonEmitter,
24916        ) -> *mut whiteout_M3AnimRefF32;
24917        pub fn whiteout_m3_M3RibbonEmitter_set_sizeAmplitude(
24918            self_: *mut whiteout_M3RibbonEmitter,
24919            value: *const whiteout_M3AnimRefF32,
24920        );
24921        pub fn whiteout_m3_M3RibbonEmitter_get_sizeFrequency(
24922            self_: *mut whiteout_M3RibbonEmitter,
24923        ) -> *mut whiteout_M3AnimRefF32;
24924        pub fn whiteout_m3_M3RibbonEmitter_set_sizeFrequency(
24925            self_: *mut whiteout_M3RibbonEmitter,
24926            value: *const whiteout_M3AnimRefF32,
24927        );
24928        pub fn whiteout_m3_M3RibbonEmitter_get_alphaType(
24929            self_: *mut whiteout_M3RibbonEmitter,
24930        ) -> u32;
24931        pub fn whiteout_m3_M3RibbonEmitter_set_alphaType(
24932            self_: *mut whiteout_M3RibbonEmitter,
24933            value: u32,
24934        );
24935        pub fn whiteout_m3_M3RibbonEmitter_get_alphaAmplitude(
24936            self_: *mut whiteout_M3RibbonEmitter,
24937        ) -> *mut whiteout_M3AnimRefF32;
24938        pub fn whiteout_m3_M3RibbonEmitter_set_alphaAmplitude(
24939            self_: *mut whiteout_M3RibbonEmitter,
24940            value: *const whiteout_M3AnimRefF32,
24941        );
24942        pub fn whiteout_m3_M3RibbonEmitter_get_alphaFrequency(
24943            self_: *mut whiteout_M3RibbonEmitter,
24944        ) -> *mut whiteout_M3AnimRefF32;
24945        pub fn whiteout_m3_M3RibbonEmitter_set_alphaFrequency(
24946            self_: *mut whiteout_M3RibbonEmitter,
24947            value: *const whiteout_M3AnimRefF32,
24948        );
24949        pub fn whiteout_m3_M3RibbonEmitter_get_particleVelocity(
24950            self_: *mut whiteout_M3RibbonEmitter,
24951        ) -> *mut whiteout_M3AnimRefF32;
24952        pub fn whiteout_m3_M3RibbonEmitter_set_particleVelocity(
24953            self_: *mut whiteout_M3RibbonEmitter,
24954            value: *const whiteout_M3AnimRefF32,
24955        );
24956        pub fn whiteout_m3_M3RibbonEmitter_get_overlay(
24957            self_: *mut whiteout_M3RibbonEmitter,
24958        ) -> *mut whiteout_M3AnimRefF32;
24959        pub fn whiteout_m3_M3RibbonEmitter_set_overlay(
24960            self_: *mut whiteout_M3RibbonEmitter,
24961            value: *const whiteout_M3AnimRefF32,
24962        );
24963        // Projector
24964        pub fn whiteout_m3_M3Projector_new() -> *mut whiteout_M3Projector;
24965        pub fn whiteout_m3_M3Projector_delete(self_: *mut whiteout_M3Projector);
24966        pub fn whiteout_m3_M3Projector_get_projectionType(self_: *mut whiteout_M3Projector) -> i32;
24967        pub fn whiteout_m3_M3Projector_set_projectionType(
24968            self_: *mut whiteout_M3Projector,
24969            value: i32,
24970        );
24971        pub fn whiteout_m3_M3Projector_get_bone(self_: *mut whiteout_M3Projector) -> u32;
24972        pub fn whiteout_m3_M3Projector_set_bone(self_: *mut whiteout_M3Projector, value: u32);
24973        pub fn whiteout_m3_M3Projector_get_materialReferenceIndex(
24974            self_: *mut whiteout_M3Projector,
24975        ) -> u32;
24976        pub fn whiteout_m3_M3Projector_set_materialReferenceIndex(
24977            self_: *mut whiteout_M3Projector,
24978            value: u32,
24979        );
24980        pub fn whiteout_m3_M3Projector_get_offset(
24981            self_: *mut whiteout_M3Projector,
24982        ) -> *mut whiteout_M3AnimRefVector3f;
24983        pub fn whiteout_m3_M3Projector_set_offset(
24984            self_: *mut whiteout_M3Projector,
24985            value: *const whiteout_M3AnimRefVector3f,
24986        );
24987        pub fn whiteout_m3_M3Projector_get_pitch(
24988            self_: *mut whiteout_M3Projector,
24989        ) -> *mut whiteout_M3AnimRefF32;
24990        pub fn whiteout_m3_M3Projector_set_pitch(
24991            self_: *mut whiteout_M3Projector,
24992            value: *const whiteout_M3AnimRefF32,
24993        );
24994        pub fn whiteout_m3_M3Projector_get_yaw(
24995            self_: *mut whiteout_M3Projector,
24996        ) -> *mut whiteout_M3AnimRefF32;
24997        pub fn whiteout_m3_M3Projector_set_yaw(
24998            self_: *mut whiteout_M3Projector,
24999            value: *const whiteout_M3AnimRefF32,
25000        );
25001        pub fn whiteout_m3_M3Projector_get_roll(
25002            self_: *mut whiteout_M3Projector,
25003        ) -> *mut whiteout_M3AnimRefF32;
25004        pub fn whiteout_m3_M3Projector_set_roll(
25005            self_: *mut whiteout_M3Projector,
25006            value: *const whiteout_M3AnimRefF32,
25007        );
25008        pub fn whiteout_m3_M3Projector_get_fieldOfView(
25009            self_: *mut whiteout_M3Projector,
25010        ) -> *mut whiteout_M3AnimRefF32;
25011        pub fn whiteout_m3_M3Projector_set_fieldOfView(
25012            self_: *mut whiteout_M3Projector,
25013            value: *const whiteout_M3AnimRefF32,
25014        );
25015        pub fn whiteout_m3_M3Projector_get_aspectRatio(
25016            self_: *mut whiteout_M3Projector,
25017        ) -> *mut whiteout_M3AnimRefF32;
25018        pub fn whiteout_m3_M3Projector_set_aspectRatio(
25019            self_: *mut whiteout_M3Projector,
25020            value: *const whiteout_M3AnimRefF32,
25021        );
25022        pub fn whiteout_m3_M3Projector_get_near(
25023            self_: *mut whiteout_M3Projector,
25024        ) -> *mut whiteout_M3AnimRefF32;
25025        pub fn whiteout_m3_M3Projector_set_near(
25026            self_: *mut whiteout_M3Projector,
25027            value: *const whiteout_M3AnimRefF32,
25028        );
25029        pub fn whiteout_m3_M3Projector_get_far(
25030            self_: *mut whiteout_M3Projector,
25031        ) -> *mut whiteout_M3AnimRefF32;
25032        pub fn whiteout_m3_M3Projector_set_far(
25033            self_: *mut whiteout_M3Projector,
25034            value: *const whiteout_M3AnimRefF32,
25035        );
25036        pub fn whiteout_m3_M3Projector_get_boxOffsetZBottom(
25037            self_: *mut whiteout_M3Projector,
25038        ) -> *mut whiteout_M3AnimRefF32;
25039        pub fn whiteout_m3_M3Projector_set_boxOffsetZBottom(
25040            self_: *mut whiteout_M3Projector,
25041            value: *const whiteout_M3AnimRefF32,
25042        );
25043        pub fn whiteout_m3_M3Projector_get_boxOffsetZTop(
25044            self_: *mut whiteout_M3Projector,
25045        ) -> *mut whiteout_M3AnimRefF32;
25046        pub fn whiteout_m3_M3Projector_set_boxOffsetZTop(
25047            self_: *mut whiteout_M3Projector,
25048            value: *const whiteout_M3AnimRefF32,
25049        );
25050        pub fn whiteout_m3_M3Projector_get_boxOffsetXLeft(
25051            self_: *mut whiteout_M3Projector,
25052        ) -> *mut whiteout_M3AnimRefF32;
25053        pub fn whiteout_m3_M3Projector_set_boxOffsetXLeft(
25054            self_: *mut whiteout_M3Projector,
25055            value: *const whiteout_M3AnimRefF32,
25056        );
25057        pub fn whiteout_m3_M3Projector_get_boxOffsetXRight(
25058            self_: *mut whiteout_M3Projector,
25059        ) -> *mut whiteout_M3AnimRefF32;
25060        pub fn whiteout_m3_M3Projector_set_boxOffsetXRight(
25061            self_: *mut whiteout_M3Projector,
25062            value: *const whiteout_M3AnimRefF32,
25063        );
25064        pub fn whiteout_m3_M3Projector_get_boxOffsetYFront(
25065            self_: *mut whiteout_M3Projector,
25066        ) -> *mut whiteout_M3AnimRefF32;
25067        pub fn whiteout_m3_M3Projector_set_boxOffsetYFront(
25068            self_: *mut whiteout_M3Projector,
25069            value: *const whiteout_M3AnimRefF32,
25070        );
25071        pub fn whiteout_m3_M3Projector_get_boxOffsetYBack(
25072            self_: *mut whiteout_M3Projector,
25073        ) -> *mut whiteout_M3AnimRefF32;
25074        pub fn whiteout_m3_M3Projector_set_boxOffsetYBack(
25075            self_: *mut whiteout_M3Projector,
25076            value: *const whiteout_M3AnimRefF32,
25077        );
25078        pub fn whiteout_m3_M3Projector_get_falloff(self_: *mut whiteout_M3Projector) -> f32;
25079        pub fn whiteout_m3_M3Projector_set_falloff(self_: *mut whiteout_M3Projector, value: f32);
25080        pub fn whiteout_m3_M3Projector_get_alphaInit(self_: *mut whiteout_M3Projector) -> f32;
25081        pub fn whiteout_m3_M3Projector_set_alphaInit(self_: *mut whiteout_M3Projector, value: f32);
25082        pub fn whiteout_m3_M3Projector_get_alphaMid(self_: *mut whiteout_M3Projector) -> f32;
25083        pub fn whiteout_m3_M3Projector_set_alphaMid(self_: *mut whiteout_M3Projector, value: f32);
25084        pub fn whiteout_m3_M3Projector_get_alphaEnd(self_: *mut whiteout_M3Projector) -> f32;
25085        pub fn whiteout_m3_M3Projector_set_alphaEnd(self_: *mut whiteout_M3Projector, value: f32);
25086        pub fn whiteout_m3_M3Projector_get_lifetimeAttack(self_: *mut whiteout_M3Projector) -> f32;
25087        pub fn whiteout_m3_M3Projector_set_lifetimeAttack(
25088            self_: *mut whiteout_M3Projector,
25089            value: f32,
25090        );
25091        pub fn whiteout_m3_M3Projector_get_lifetimeAttackTo(
25092            self_: *mut whiteout_M3Projector,
25093        ) -> f32;
25094        pub fn whiteout_m3_M3Projector_set_lifetimeAttackTo(
25095            self_: *mut whiteout_M3Projector,
25096            value: f32,
25097        );
25098        pub fn whiteout_m3_M3Projector_get_lifetimeHold(self_: *mut whiteout_M3Projector) -> f32;
25099        pub fn whiteout_m3_M3Projector_set_lifetimeHold(
25100            self_: *mut whiteout_M3Projector,
25101            value: f32,
25102        );
25103        pub fn whiteout_m3_M3Projector_get_lifetimeHoldTo(self_: *mut whiteout_M3Projector) -> f32;
25104        pub fn whiteout_m3_M3Projector_set_lifetimeHoldTo(
25105            self_: *mut whiteout_M3Projector,
25106            value: f32,
25107        );
25108        pub fn whiteout_m3_M3Projector_get_lifetimeDecay(self_: *mut whiteout_M3Projector) -> f32;
25109        pub fn whiteout_m3_M3Projector_set_lifetimeDecay(
25110            self_: *mut whiteout_M3Projector,
25111            value: f32,
25112        );
25113        pub fn whiteout_m3_M3Projector_get_lifetimeDecayTo(self_: *mut whiteout_M3Projector)
25114            -> f32;
25115        pub fn whiteout_m3_M3Projector_set_lifetimeDecayTo(
25116            self_: *mut whiteout_M3Projector,
25117            value: f32,
25118        );
25119        pub fn whiteout_m3_M3Projector_get_attenuationDistance(
25120            self_: *mut whiteout_M3Projector,
25121        ) -> f32;
25122        pub fn whiteout_m3_M3Projector_set_attenuationDistance(
25123            self_: *mut whiteout_M3Projector,
25124            value: f32,
25125        );
25126        pub fn whiteout_m3_M3Projector_get_active(
25127            self_: *mut whiteout_M3Projector,
25128        ) -> *mut whiteout_M3AnimRefU32;
25129        pub fn whiteout_m3_M3Projector_set_active(
25130            self_: *mut whiteout_M3Projector,
25131            value: *const whiteout_M3AnimRefU32,
25132        );
25133        pub fn whiteout_m3_M3Projector_get_layer(self_: *mut whiteout_M3Projector) -> u32;
25134        pub fn whiteout_m3_M3Projector_set_layer(self_: *mut whiteout_M3Projector, value: u32);
25135        pub fn whiteout_m3_M3Projector_get_lodReduce(self_: *mut whiteout_M3Projector) -> u32;
25136        pub fn whiteout_m3_M3Projector_set_lodReduce(self_: *mut whiteout_M3Projector, value: u32);
25137        pub fn whiteout_m3_M3Projector_get_lodCut(self_: *mut whiteout_M3Projector) -> u32;
25138        pub fn whiteout_m3_M3Projector_set_lodCut(self_: *mut whiteout_M3Projector, value: u32);
25139        pub fn whiteout_m3_M3Projector_get_flags(self_: *mut whiteout_M3Projector) -> i32;
25140        pub fn whiteout_m3_M3Projector_set_flags(self_: *mut whiteout_M3Projector, value: i32);
25141        // MaterialMap
25142        pub fn whiteout_m3_M3MaterialMap_new() -> *mut whiteout_M3MaterialMap;
25143        pub fn whiteout_m3_M3MaterialMap_delete(self_: *mut whiteout_M3MaterialMap);
25144        pub fn whiteout_m3_M3MaterialMap_get_materialType(
25145            self_: *mut whiteout_M3MaterialMap,
25146        ) -> i32;
25147        pub fn whiteout_m3_M3MaterialMap_set_materialType(
25148            self_: *mut whiteout_M3MaterialMap,
25149            value: i32,
25150        );
25151        pub fn whiteout_m3_M3MaterialMap_get_materialIndex(
25152            self_: *mut whiteout_M3MaterialMap,
25153        ) -> u32;
25154        pub fn whiteout_m3_M3MaterialMap_set_materialIndex(
25155            self_: *mut whiteout_M3MaterialMap,
25156            value: u32,
25157        );
25158        // TextureLayer
25159        pub fn whiteout_m3_M3TextureLayer_new() -> *mut whiteout_M3TextureLayer;
25160        pub fn whiteout_m3_M3TextureLayer_delete(self_: *mut whiteout_M3TextureLayer);
25161        pub fn whiteout_m3_M3TextureLayer_get_id(self_: *mut whiteout_M3TextureLayer) -> u32;
25162        pub fn whiteout_m3_M3TextureLayer_set_id(self_: *mut whiteout_M3TextureLayer, value: u32);
25163        pub fn whiteout_m3_M3TextureLayer_get_texturePath(
25164            self_: *mut whiteout_M3TextureLayer,
25165        ) -> RawCString;
25166        pub fn whiteout_m3_M3TextureLayer_set_texturePath(
25167            self_: *mut whiteout_M3TextureLayer,
25168            value: *const core::ffi::c_char,
25169        );
25170        pub fn whiteout_m3_M3TextureLayer_get_color(
25171            self_: *mut whiteout_M3TextureLayer,
25172        ) -> *mut whiteout_M3AnimRefM3ColorBGRA;
25173        pub fn whiteout_m3_M3TextureLayer_set_color(
25174            self_: *mut whiteout_M3TextureLayer,
25175            value: *const whiteout_M3AnimRefM3ColorBGRA,
25176        );
25177        pub fn whiteout_m3_M3TextureLayer_get_flags(self_: *mut whiteout_M3TextureLayer) -> i32;
25178        pub fn whiteout_m3_M3TextureLayer_set_flags(
25179            self_: *mut whiteout_M3TextureLayer,
25180            value: i32,
25181        );
25182        pub fn whiteout_m3_M3TextureLayer_get_uvMapping(self_: *mut whiteout_M3TextureLayer)
25183            -> i32;
25184        pub fn whiteout_m3_M3TextureLayer_set_uvMapping(
25185            self_: *mut whiteout_M3TextureLayer,
25186            value: i32,
25187        );
25188        pub fn whiteout_m3_M3TextureLayer_get_colorType(self_: *mut whiteout_M3TextureLayer)
25189            -> i32;
25190        pub fn whiteout_m3_M3TextureLayer_set_colorType(
25191            self_: *mut whiteout_M3TextureLayer,
25192            value: i32,
25193        );
25194        pub fn whiteout_m3_M3TextureLayer_get_rgbMultiply(
25195            self_: *mut whiteout_M3TextureLayer,
25196        ) -> *mut whiteout_M3AnimRefF32;
25197        pub fn whiteout_m3_M3TextureLayer_set_rgbMultiply(
25198            self_: *mut whiteout_M3TextureLayer,
25199            value: *const whiteout_M3AnimRefF32,
25200        );
25201        pub fn whiteout_m3_M3TextureLayer_get_rgbAdd(
25202            self_: *mut whiteout_M3TextureLayer,
25203        ) -> *mut whiteout_M3AnimRefF32;
25204        pub fn whiteout_m3_M3TextureLayer_set_rgbAdd(
25205            self_: *mut whiteout_M3TextureLayer,
25206            value: *const whiteout_M3AnimRefF32,
25207        );
25208        pub fn whiteout_m3_M3TextureLayer_get_pocTexture(
25209            self_: *mut whiteout_M3TextureLayer,
25210        ) -> u32;
25211        pub fn whiteout_m3_M3TextureLayer_set_pocTexture(
25212            self_: *mut whiteout_M3TextureLayer,
25213            value: u32,
25214        );
25215        pub fn whiteout_m3_M3TextureLayer_get_noiseAmplitude(
25216            self_: *mut whiteout_M3TextureLayer,
25217        ) -> f32;
25218        pub fn whiteout_m3_M3TextureLayer_set_noiseAmplitude(
25219            self_: *mut whiteout_M3TextureLayer,
25220            value: f32,
25221        );
25222        pub fn whiteout_m3_M3TextureLayer_get_noiseFrequency(
25223            self_: *mut whiteout_M3TextureLayer,
25224        ) -> f32;
25225        pub fn whiteout_m3_M3TextureLayer_set_noiseFrequency(
25226            self_: *mut whiteout_M3TextureLayer,
25227            value: f32,
25228        );
25229        pub fn whiteout_m3_M3TextureLayer_get_textureSource(
25230            self_: *mut whiteout_M3TextureLayer,
25231        ) -> u32;
25232        pub fn whiteout_m3_M3TextureLayer_set_textureSource(
25233            self_: *mut whiteout_M3TextureLayer,
25234            value: u32,
25235        );
25236        pub fn whiteout_m3_M3TextureLayer_get_aviFrameRate(
25237            self_: *mut whiteout_M3TextureLayer,
25238        ) -> u32;
25239        pub fn whiteout_m3_M3TextureLayer_set_aviFrameRate(
25240            self_: *mut whiteout_M3TextureLayer,
25241            value: u32,
25242        );
25243        pub fn whiteout_m3_M3TextureLayer_get_aviStart(self_: *mut whiteout_M3TextureLayer) -> u32;
25244        pub fn whiteout_m3_M3TextureLayer_set_aviStart(
25245            self_: *mut whiteout_M3TextureLayer,
25246            value: u32,
25247        );
25248        pub fn whiteout_m3_M3TextureLayer_get_aviStop(self_: *mut whiteout_M3TextureLayer) -> u32;
25249        pub fn whiteout_m3_M3TextureLayer_set_aviStop(
25250            self_: *mut whiteout_M3TextureLayer,
25251            value: u32,
25252        );
25253        pub fn whiteout_m3_M3TextureLayer_get_aviLoop(self_: *mut whiteout_M3TextureLayer) -> u32;
25254        pub fn whiteout_m3_M3TextureLayer_set_aviLoop(
25255            self_: *mut whiteout_M3TextureLayer,
25256            value: u32,
25257        );
25258        pub fn whiteout_m3_M3TextureLayer_get_aviSync(self_: *mut whiteout_M3TextureLayer) -> u32;
25259        pub fn whiteout_m3_M3TextureLayer_set_aviSync(
25260            self_: *mut whiteout_M3TextureLayer,
25261            value: u32,
25262        );
25263        pub fn whiteout_m3_M3TextureLayer_get_aviPlay(
25264            self_: *mut whiteout_M3TextureLayer,
25265        ) -> *mut whiteout_M3AnimRefU32;
25266        pub fn whiteout_m3_M3TextureLayer_set_aviPlay(
25267            self_: *mut whiteout_M3TextureLayer,
25268            value: *const whiteout_M3AnimRefU32,
25269        );
25270        pub fn whiteout_m3_M3TextureLayer_get_aviRestart(
25271            self_: *mut whiteout_M3TextureLayer,
25272        ) -> *mut whiteout_M3AnimRefU32;
25273        pub fn whiteout_m3_M3TextureLayer_set_aviRestart(
25274            self_: *mut whiteout_M3TextureLayer,
25275            value: *const whiteout_M3AnimRefU32,
25276        );
25277        pub fn whiteout_m3_M3TextureLayer_get_flipbookRows(
25278            self_: *mut whiteout_M3TextureLayer,
25279        ) -> u32;
25280        pub fn whiteout_m3_M3TextureLayer_set_flipbookRows(
25281            self_: *mut whiteout_M3TextureLayer,
25282            value: u32,
25283        );
25284        pub fn whiteout_m3_M3TextureLayer_get_flipbookColumns(
25285            self_: *mut whiteout_M3TextureLayer,
25286        ) -> u32;
25287        pub fn whiteout_m3_M3TextureLayer_set_flipbookColumns(
25288            self_: *mut whiteout_M3TextureLayer,
25289            value: u32,
25290        );
25291        pub fn whiteout_m3_M3TextureLayer_get_currentFrame(
25292            self_: *mut whiteout_M3TextureLayer,
25293        ) -> *mut whiteout_M3AnimRefU16;
25294        pub fn whiteout_m3_M3TextureLayer_set_currentFrame(
25295            self_: *mut whiteout_M3TextureLayer,
25296            value: *const whiteout_M3AnimRefU16,
25297        );
25298        pub fn whiteout_m3_M3TextureLayer_get_uvOffset(
25299            self_: *mut whiteout_M3TextureLayer,
25300        ) -> *mut whiteout_M3AnimRefVector2f;
25301        pub fn whiteout_m3_M3TextureLayer_set_uvOffset(
25302            self_: *mut whiteout_M3TextureLayer,
25303            value: *const whiteout_M3AnimRefVector2f,
25304        );
25305        pub fn whiteout_m3_M3TextureLayer_get_uvAngle(
25306            self_: *mut whiteout_M3TextureLayer,
25307        ) -> *mut whiteout_M3AnimRefVector3f;
25308        pub fn whiteout_m3_M3TextureLayer_set_uvAngle(
25309            self_: *mut whiteout_M3TextureLayer,
25310            value: *const whiteout_M3AnimRefVector3f,
25311        );
25312        pub fn whiteout_m3_M3TextureLayer_get_uvTiling(
25313            self_: *mut whiteout_M3TextureLayer,
25314        ) -> *mut whiteout_M3AnimRefVector2f;
25315        pub fn whiteout_m3_M3TextureLayer_set_uvTiling(
25316            self_: *mut whiteout_M3TextureLayer,
25317            value: *const whiteout_M3AnimRefVector2f,
25318        );
25319        pub fn whiteout_m3_M3TextureLayer_get_wOffset(
25320            self_: *mut whiteout_M3TextureLayer,
25321        ) -> *mut whiteout_M3AnimRefF32;
25322        pub fn whiteout_m3_M3TextureLayer_set_wOffset(
25323            self_: *mut whiteout_M3TextureLayer,
25324            value: *const whiteout_M3AnimRefF32,
25325        );
25326        pub fn whiteout_m3_M3TextureLayer_get_wTiling(
25327            self_: *mut whiteout_M3TextureLayer,
25328        ) -> *mut whiteout_M3AnimRefF32;
25329        pub fn whiteout_m3_M3TextureLayer_set_wTiling(
25330            self_: *mut whiteout_M3TextureLayer,
25331            value: *const whiteout_M3AnimRefF32,
25332        );
25333        pub fn whiteout_m3_M3TextureLayer_get_mapAlpha(
25334            self_: *mut whiteout_M3TextureLayer,
25335        ) -> *mut whiteout_M3AnimRefF32;
25336        pub fn whiteout_m3_M3TextureLayer_set_mapAlpha(
25337            self_: *mut whiteout_M3TextureLayer,
25338            value: *const whiteout_M3AnimRefF32,
25339        );
25340        pub fn whiteout_m3_M3TextureLayer_get_triplanarOffset(
25341            self_: *mut whiteout_M3TextureLayer,
25342        ) -> *mut whiteout_M3AnimRefVector3f;
25343        pub fn whiteout_m3_M3TextureLayer_set_triplanarOffset(
25344            self_: *mut whiteout_M3TextureLayer,
25345            value: *const whiteout_M3AnimRefVector3f,
25346        );
25347        pub fn whiteout_m3_M3TextureLayer_get_triplanarScale(
25348            self_: *mut whiteout_M3TextureLayer,
25349        ) -> *mut whiteout_M3AnimRefVector3f;
25350        pub fn whiteout_m3_M3TextureLayer_set_triplanarScale(
25351            self_: *mut whiteout_M3TextureLayer,
25352            value: *const whiteout_M3AnimRefVector3f,
25353        );
25354        pub fn whiteout_m3_M3TextureLayer_get_uvSourceRelated(
25355            self_: *mut whiteout_M3TextureLayer,
25356        ) -> u32;
25357        pub fn whiteout_m3_M3TextureLayer_set_uvSourceRelated(
25358            self_: *mut whiteout_M3TextureLayer,
25359            value: u32,
25360        );
25361        pub fn whiteout_m3_M3TextureLayer_get_fresnelMode(
25362            self_: *mut whiteout_M3TextureLayer,
25363        ) -> i32;
25364        pub fn whiteout_m3_M3TextureLayer_set_fresnelMode(
25365            self_: *mut whiteout_M3TextureLayer,
25366            value: i32,
25367        );
25368        pub fn whiteout_m3_M3TextureLayer_get_fresnelExponent(
25369            self_: *mut whiteout_M3TextureLayer,
25370        ) -> f32;
25371        pub fn whiteout_m3_M3TextureLayer_set_fresnelExponent(
25372            self_: *mut whiteout_M3TextureLayer,
25373            value: f32,
25374        );
25375        pub fn whiteout_m3_M3TextureLayer_get_fresnelMin(
25376            self_: *mut whiteout_M3TextureLayer,
25377        ) -> f32;
25378        pub fn whiteout_m3_M3TextureLayer_set_fresnelMin(
25379            self_: *mut whiteout_M3TextureLayer,
25380            value: f32,
25381        );
25382        pub fn whiteout_m3_M3TextureLayer_get_fresnelMax(
25383            self_: *mut whiteout_M3TextureLayer,
25384        ) -> f32;
25385        pub fn whiteout_m3_M3TextureLayer_set_fresnelMax(
25386            self_: *mut whiteout_M3TextureLayer,
25387            value: f32,
25388        );
25389        pub fn whiteout_m3_M3TextureLayer_get_fresnelTranslation(
25390            self_: *mut whiteout_M3TextureLayer,
25391        ) -> *mut core::ffi::c_void;
25392        pub fn whiteout_m3_M3TextureLayer_set_fresnelTranslation(
25393            self_: *mut whiteout_M3TextureLayer,
25394            value: *const core::ffi::c_void,
25395        );
25396        pub fn whiteout_m3_M3TextureLayer_get_fresnelMask(
25397            self_: *mut whiteout_M3TextureLayer,
25398        ) -> *mut core::ffi::c_void;
25399        pub fn whiteout_m3_M3TextureLayer_set_fresnelMask(
25400            self_: *mut whiteout_M3TextureLayer,
25401            value: *const core::ffi::c_void,
25402        );
25403        pub fn whiteout_m3_M3TextureLayer_get_fresnelRotation(
25404            self_: *mut whiteout_M3TextureLayer,
25405        ) -> *mut core::ffi::c_void;
25406        pub fn whiteout_m3_M3TextureLayer_set_fresnelRotation(
25407            self_: *mut whiteout_M3TextureLayer,
25408            value: *const core::ffi::c_void,
25409        );
25410        pub fn whiteout_m3_M3TextureLayer_get_uvDensity(self_: *mut whiteout_M3TextureLayer)
25411            -> u32;
25412        pub fn whiteout_m3_M3TextureLayer_set_uvDensity(
25413            self_: *mut whiteout_M3TextureLayer,
25414            value: u32,
25415        );
25416        // StandardMaterial
25417        pub fn whiteout_m3_M3StandardMaterial_new() -> *mut whiteout_M3StandardMaterial;
25418        pub fn whiteout_m3_M3StandardMaterial_delete(self_: *mut whiteout_M3StandardMaterial);
25419        pub fn whiteout_m3_M3StandardMaterial_get_name(
25420            self_: *mut whiteout_M3StandardMaterial,
25421        ) -> RawCString;
25422        pub fn whiteout_m3_M3StandardMaterial_set_name(
25423            self_: *mut whiteout_M3StandardMaterial,
25424            value: *const core::ffi::c_char,
25425        );
25426        pub fn whiteout_m3_M3StandardMaterial_get_additionalFlags(
25427            self_: *mut whiteout_M3StandardMaterial,
25428        ) -> i32;
25429        pub fn whiteout_m3_M3StandardMaterial_set_additionalFlags(
25430            self_: *mut whiteout_M3StandardMaterial,
25431            value: i32,
25432        );
25433        pub fn whiteout_m3_M3StandardMaterial_get_flags(
25434            self_: *mut whiteout_M3StandardMaterial,
25435        ) -> i32;
25436        pub fn whiteout_m3_M3StandardMaterial_set_flags(
25437            self_: *mut whiteout_M3StandardMaterial,
25438            value: i32,
25439        );
25440        pub fn whiteout_m3_M3StandardMaterial_get_blendMode(
25441            self_: *mut whiteout_M3StandardMaterial,
25442        ) -> i32;
25443        pub fn whiteout_m3_M3StandardMaterial_set_blendMode(
25444            self_: *mut whiteout_M3StandardMaterial,
25445            value: i32,
25446        );
25447        pub fn whiteout_m3_M3StandardMaterial_get_priority(
25448            self_: *mut whiteout_M3StandardMaterial,
25449        ) -> i32;
25450        pub fn whiteout_m3_M3StandardMaterial_set_priority(
25451            self_: *mut whiteout_M3StandardMaterial,
25452            value: i32,
25453        );
25454        pub fn whiteout_m3_M3StandardMaterial_get_rttChannels(
25455            self_: *mut whiteout_M3StandardMaterial,
25456        ) -> u32;
25457        pub fn whiteout_m3_M3StandardMaterial_set_rttChannels(
25458            self_: *mut whiteout_M3StandardMaterial,
25459            value: u32,
25460        );
25461        pub fn whiteout_m3_M3StandardMaterial_get_specularExponent(
25462            self_: *mut whiteout_M3StandardMaterial,
25463        ) -> f32;
25464        pub fn whiteout_m3_M3StandardMaterial_set_specularExponent(
25465            self_: *mut whiteout_M3StandardMaterial,
25466            value: f32,
25467        );
25468        pub fn whiteout_m3_M3StandardMaterial_get_depthBlendFalloff(
25469            self_: *mut whiteout_M3StandardMaterial,
25470        ) -> f32;
25471        pub fn whiteout_m3_M3StandardMaterial_set_depthBlendFalloff(
25472            self_: *mut whiteout_M3StandardMaterial,
25473            value: f32,
25474        );
25475        pub fn whiteout_m3_M3StandardMaterial_get_alphaTestThreshold(
25476            self_: *mut whiteout_M3StandardMaterial,
25477        ) -> u32;
25478        pub fn whiteout_m3_M3StandardMaterial_set_alphaTestThreshold(
25479            self_: *mut whiteout_M3StandardMaterial,
25480            value: u32,
25481        );
25482        pub fn whiteout_m3_M3StandardMaterial_get_hdrSpecularMultiplier(
25483            self_: *mut whiteout_M3StandardMaterial,
25484        ) -> f32;
25485        pub fn whiteout_m3_M3StandardMaterial_set_hdrSpecularMultiplier(
25486            self_: *mut whiteout_M3StandardMaterial,
25487            value: f32,
25488        );
25489        pub fn whiteout_m3_M3StandardMaterial_get_hdrEmissiveMultiplier(
25490            self_: *mut whiteout_M3StandardMaterial,
25491        ) -> f32;
25492        pub fn whiteout_m3_M3StandardMaterial_set_hdrEmissiveMultiplier(
25493            self_: *mut whiteout_M3StandardMaterial,
25494            value: f32,
25495        );
25496        pub fn whiteout_m3_M3StandardMaterial_get_hdrEnvironmentConstant(
25497            self_: *mut whiteout_M3StandardMaterial,
25498        ) -> f32;
25499        pub fn whiteout_m3_M3StandardMaterial_set_hdrEnvironmentConstant(
25500            self_: *mut whiteout_M3StandardMaterial,
25501            value: f32,
25502        );
25503        pub fn whiteout_m3_M3StandardMaterial_get_hdrEnvironmentDiffuse(
25504            self_: *mut whiteout_M3StandardMaterial,
25505        ) -> f32;
25506        pub fn whiteout_m3_M3StandardMaterial_set_hdrEnvironmentDiffuse(
25507            self_: *mut whiteout_M3StandardMaterial,
25508            value: f32,
25509        );
25510        pub fn whiteout_m3_M3StandardMaterial_get_hdrEnvironmentSpecular(
25511            self_: *mut whiteout_M3StandardMaterial,
25512        ) -> f32;
25513        pub fn whiteout_m3_M3StandardMaterial_set_hdrEnvironmentSpecular(
25514            self_: *mut whiteout_M3StandardMaterial,
25515            value: f32,
25516        );
25517        pub fn whiteout_m3_M3StandardMaterial_get_materialClass(
25518            self_: *mut whiteout_M3StandardMaterial,
25519        ) -> i32;
25520        pub fn whiteout_m3_M3StandardMaterial_set_materialClass(
25521            self_: *mut whiteout_M3StandardMaterial,
25522            value: i32,
25523        );
25524        pub fn whiteout_m3_M3StandardMaterial_get_layerBlendMode(
25525            self_: *mut whiteout_M3StandardMaterial,
25526        ) -> i32;
25527        pub fn whiteout_m3_M3StandardMaterial_set_layerBlendMode(
25528            self_: *mut whiteout_M3StandardMaterial,
25529            value: i32,
25530        );
25531        pub fn whiteout_m3_M3StandardMaterial_get_emissiveBlendMode1(
25532            self_: *mut whiteout_M3StandardMaterial,
25533        ) -> i32;
25534        pub fn whiteout_m3_M3StandardMaterial_set_emissiveBlendMode1(
25535            self_: *mut whiteout_M3StandardMaterial,
25536            value: i32,
25537        );
25538        pub fn whiteout_m3_M3StandardMaterial_get_emissiveBlendMode2(
25539            self_: *mut whiteout_M3StandardMaterial,
25540        ) -> i32;
25541        pub fn whiteout_m3_M3StandardMaterial_set_emissiveBlendMode2(
25542            self_: *mut whiteout_M3StandardMaterial,
25543            value: i32,
25544        );
25545        pub fn whiteout_m3_M3StandardMaterial_get_specularMode(
25546            self_: *mut whiteout_M3StandardMaterial,
25547        ) -> i32;
25548        pub fn whiteout_m3_M3StandardMaterial_set_specularMode(
25549            self_: *mut whiteout_M3StandardMaterial,
25550            value: i32,
25551        );
25552        pub fn whiteout_m3_M3StandardMaterial_get_parallaxHeight(
25553            self_: *mut whiteout_M3StandardMaterial,
25554        ) -> *mut whiteout_M3AnimRefF32;
25555        pub fn whiteout_m3_M3StandardMaterial_set_parallaxHeight(
25556            self_: *mut whiteout_M3StandardMaterial,
25557            value: *const whiteout_M3AnimRefF32,
25558        );
25559        pub fn whiteout_m3_M3StandardMaterial_get_motionBlurAmount(
25560            self_: *mut whiteout_M3StandardMaterial,
25561        ) -> *mut whiteout_M3AnimRefF32;
25562        pub fn whiteout_m3_M3StandardMaterial_set_motionBlurAmount(
25563            self_: *mut whiteout_M3StandardMaterial,
25564            value: *const whiteout_M3AnimRefF32,
25565        );
25566        pub fn whiteout_m3_M3StandardMaterial_get_normalBlendFactors_count(
25567            self_: *mut whiteout_M3StandardMaterial,
25568        ) -> usize;
25569        pub fn whiteout_m3_M3StandardMaterial_resize_normalBlendFactors(
25570            self_: *mut whiteout_M3StandardMaterial,
25571            count: usize,
25572        );
25573        pub fn whiteout_m3_M3StandardMaterial_get_normalBlendFactors_at(
25574            self_: *mut whiteout_M3StandardMaterial,
25575            index: usize,
25576        ) -> *mut whiteout_M3AnimRefF32;
25577        // DisplacementMaterial
25578        pub fn whiteout_m3_M3DisplacementMaterial_new() -> *mut whiteout_M3DisplacementMaterial;
25579        pub fn whiteout_m3_M3DisplacementMaterial_delete(
25580            self_: *mut whiteout_M3DisplacementMaterial,
25581        );
25582        pub fn whiteout_m3_M3DisplacementMaterial_get_name(
25583            self_: *mut whiteout_M3DisplacementMaterial,
25584        ) -> RawCString;
25585        pub fn whiteout_m3_M3DisplacementMaterial_set_name(
25586            self_: *mut whiteout_M3DisplacementMaterial,
25587            value: *const core::ffi::c_char,
25588        );
25589        pub fn whiteout_m3_M3DisplacementMaterial_get_unknown(
25590            self_: *mut whiteout_M3DisplacementMaterial,
25591        ) -> u32;
25592        pub fn whiteout_m3_M3DisplacementMaterial_set_unknown(
25593            self_: *mut whiteout_M3DisplacementMaterial,
25594            value: u32,
25595        );
25596        pub fn whiteout_m3_M3DisplacementMaterial_get_strength(
25597            self_: *mut whiteout_M3DisplacementMaterial,
25598        ) -> *mut whiteout_M3AnimRefF32;
25599        pub fn whiteout_m3_M3DisplacementMaterial_set_strength(
25600            self_: *mut whiteout_M3DisplacementMaterial,
25601            value: *const whiteout_M3AnimRefF32,
25602        );
25603        pub fn whiteout_m3_M3DisplacementMaterial_get_priority(
25604            self_: *mut whiteout_M3DisplacementMaterial,
25605        ) -> u32;
25606        pub fn whiteout_m3_M3DisplacementMaterial_set_priority(
25607            self_: *mut whiteout_M3DisplacementMaterial,
25608            value: u32,
25609        );
25610        // CompositeSection
25611        pub fn whiteout_m3_M3CompositeSection_new() -> *mut whiteout_M3CompositeSection;
25612        pub fn whiteout_m3_M3CompositeSection_delete(self_: *mut whiteout_M3CompositeSection);
25613        pub fn whiteout_m3_M3CompositeSection_get_materialIndex(
25614            self_: *mut whiteout_M3CompositeSection,
25615        ) -> u32;
25616        pub fn whiteout_m3_M3CompositeSection_set_materialIndex(
25617            self_: *mut whiteout_M3CompositeSection,
25618            value: u32,
25619        );
25620        pub fn whiteout_m3_M3CompositeSection_get_mapMultiplier(
25621            self_: *mut whiteout_M3CompositeSection,
25622        ) -> *mut whiteout_M3AnimRefF32;
25623        pub fn whiteout_m3_M3CompositeSection_set_mapMultiplier(
25624            self_: *mut whiteout_M3CompositeSection,
25625            value: *const whiteout_M3AnimRefF32,
25626        );
25627        // CompositeMaterial
25628        pub fn whiteout_m3_M3CompositeMaterial_new() -> *mut whiteout_M3CompositeMaterial;
25629        pub fn whiteout_m3_M3CompositeMaterial_delete(self_: *mut whiteout_M3CompositeMaterial);
25630        pub fn whiteout_m3_M3CompositeMaterial_get_name(
25631            self_: *mut whiteout_M3CompositeMaterial,
25632        ) -> RawCString;
25633        pub fn whiteout_m3_M3CompositeMaterial_set_name(
25634            self_: *mut whiteout_M3CompositeMaterial,
25635            value: *const core::ffi::c_char,
25636        );
25637        pub fn whiteout_m3_M3CompositeMaterial_get_priority(
25638            self_: *mut whiteout_M3CompositeMaterial,
25639        ) -> u32;
25640        pub fn whiteout_m3_M3CompositeMaterial_set_priority(
25641            self_: *mut whiteout_M3CompositeMaterial,
25642            value: u32,
25643        );
25644        pub fn whiteout_m3_M3CompositeMaterial_get_sections_count(
25645            self_: *mut whiteout_M3CompositeMaterial,
25646        ) -> usize;
25647        pub fn whiteout_m3_M3CompositeMaterial_resize_sections(
25648            self_: *mut whiteout_M3CompositeMaterial,
25649            count: usize,
25650        );
25651        pub fn whiteout_m3_M3CompositeMaterial_get_sections_at(
25652            self_: *mut whiteout_M3CompositeMaterial,
25653            index: usize,
25654        ) -> *mut whiteout_M3CompositeSection;
25655        // TerrainMaterial
25656        pub fn whiteout_m3_M3TerrainMaterial_new() -> *mut whiteout_M3TerrainMaterial;
25657        pub fn whiteout_m3_M3TerrainMaterial_delete(self_: *mut whiteout_M3TerrainMaterial);
25658        pub fn whiteout_m3_M3TerrainMaterial_get_name(
25659            self_: *mut whiteout_M3TerrainMaterial,
25660        ) -> RawCString;
25661        pub fn whiteout_m3_M3TerrainMaterial_set_name(
25662            self_: *mut whiteout_M3TerrainMaterial,
25663            value: *const core::ffi::c_char,
25664        );
25665        pub fn whiteout_m3_M3TerrainMaterial_get_unknown(
25666            self_: *mut whiteout_M3TerrainMaterial,
25667        ) -> u32;
25668        pub fn whiteout_m3_M3TerrainMaterial_set_unknown(
25669            self_: *mut whiteout_M3TerrainMaterial,
25670            value: u32,
25671        );
25672        // VolumeMaterial
25673        pub fn whiteout_m3_M3VolumeMaterial_new() -> *mut whiteout_M3VolumeMaterial;
25674        pub fn whiteout_m3_M3VolumeMaterial_delete(self_: *mut whiteout_M3VolumeMaterial);
25675        pub fn whiteout_m3_M3VolumeMaterial_get_name(
25676            self_: *mut whiteout_M3VolumeMaterial,
25677        ) -> RawCString;
25678        pub fn whiteout_m3_M3VolumeMaterial_set_name(
25679            self_: *mut whiteout_M3VolumeMaterial,
25680            value: *const core::ffi::c_char,
25681        );
25682        pub fn whiteout_m3_M3VolumeMaterial_get_blendMode(
25683            self_: *mut whiteout_M3VolumeMaterial,
25684        ) -> u32;
25685        pub fn whiteout_m3_M3VolumeMaterial_set_blendMode(
25686            self_: *mut whiteout_M3VolumeMaterial,
25687            value: u32,
25688        );
25689        pub fn whiteout_m3_M3VolumeMaterial_get_falloffType(
25690            self_: *mut whiteout_M3VolumeMaterial,
25691        ) -> i32;
25692        pub fn whiteout_m3_M3VolumeMaterial_set_falloffType(
25693            self_: *mut whiteout_M3VolumeMaterial,
25694            value: i32,
25695        );
25696        pub fn whiteout_m3_M3VolumeMaterial_get_density(
25697            self_: *mut whiteout_M3VolumeMaterial,
25698        ) -> *mut whiteout_M3AnimRefF32;
25699        pub fn whiteout_m3_M3VolumeMaterial_set_density(
25700            self_: *mut whiteout_M3VolumeMaterial,
25701            value: *const whiteout_M3AnimRefF32,
25702        );
25703        pub fn whiteout_m3_M3VolumeMaterial_get_alphaThreshold(
25704            self_: *mut whiteout_M3VolumeMaterial,
25705        ) -> u32;
25706        pub fn whiteout_m3_M3VolumeMaterial_set_alphaThreshold(
25707            self_: *mut whiteout_M3VolumeMaterial,
25708            value: u32,
25709        );
25710        // HairMaterial
25711        pub fn whiteout_m3_M3HairMaterial_new() -> *mut whiteout_M3HairMaterial;
25712        pub fn whiteout_m3_M3HairMaterial_delete(self_: *mut whiteout_M3HairMaterial);
25713        pub fn whiteout_m3_M3HairMaterial_get_name(
25714            self_: *mut whiteout_M3HairMaterial,
25715        ) -> RawCString;
25716        pub fn whiteout_m3_M3HairMaterial_set_name(
25717            self_: *mut whiteout_M3HairMaterial,
25718            value: *const core::ffi::c_char,
25719        );
25720        pub fn whiteout_m3_M3HairMaterial_get_shiftPrimary(
25721            self_: *mut whiteout_M3HairMaterial,
25722        ) -> f32;
25723        pub fn whiteout_m3_M3HairMaterial_set_shiftPrimary(
25724            self_: *mut whiteout_M3HairMaterial,
25725            value: f32,
25726        );
25727        pub fn whiteout_m3_M3HairMaterial_get_shiftSecondary(
25728            self_: *mut whiteout_M3HairMaterial,
25729        ) -> f32;
25730        pub fn whiteout_m3_M3HairMaterial_set_shiftSecondary(
25731            self_: *mut whiteout_M3HairMaterial,
25732            value: f32,
25733        );
25734        pub fn whiteout_m3_M3HairMaterial_get_colorDiffuse(
25735            self_: *mut whiteout_M3HairMaterial,
25736        ) -> *mut whiteout_M3AnimRefM3ColorBGRA;
25737        pub fn whiteout_m3_M3HairMaterial_set_colorDiffuse(
25738            self_: *mut whiteout_M3HairMaterial,
25739            value: *const whiteout_M3AnimRefM3ColorBGRA,
25740        );
25741        pub fn whiteout_m3_M3HairMaterial_get_colorSpec(
25742            self_: *mut whiteout_M3HairMaterial,
25743        ) -> *mut whiteout_M3AnimRefM3ColorBGRA;
25744        pub fn whiteout_m3_M3HairMaterial_set_colorSpec(
25745            self_: *mut whiteout_M3HairMaterial,
25746            value: *const whiteout_M3AnimRefM3ColorBGRA,
25747        );
25748        pub fn whiteout_m3_M3HairMaterial_get_specExponent0(
25749            self_: *mut whiteout_M3HairMaterial,
25750        ) -> f32;
25751        pub fn whiteout_m3_M3HairMaterial_set_specExponent0(
25752            self_: *mut whiteout_M3HairMaterial,
25753            value: f32,
25754        );
25755        pub fn whiteout_m3_M3HairMaterial_get_specExponent1(
25756            self_: *mut whiteout_M3HairMaterial,
25757        ) -> f32;
25758        pub fn whiteout_m3_M3HairMaterial_set_specExponent1(
25759            self_: *mut whiteout_M3HairMaterial,
25760            value: f32,
25761        );
25762        // VolumeNoiseMaterial
25763        pub fn whiteout_m3_M3VolumeNoiseMaterial_new() -> *mut whiteout_M3VolumeNoiseMaterial;
25764        pub fn whiteout_m3_M3VolumeNoiseMaterial_delete(self_: *mut whiteout_M3VolumeNoiseMaterial);
25765        pub fn whiteout_m3_M3VolumeNoiseMaterial_get_name(
25766            self_: *mut whiteout_M3VolumeNoiseMaterial,
25767        ) -> RawCString;
25768        pub fn whiteout_m3_M3VolumeNoiseMaterial_set_name(
25769            self_: *mut whiteout_M3VolumeNoiseMaterial,
25770            value: *const core::ffi::c_char,
25771        );
25772        pub fn whiteout_m3_M3VolumeNoiseMaterial_get_falloffType(
25773            self_: *mut whiteout_M3VolumeNoiseMaterial,
25774        ) -> i32;
25775        pub fn whiteout_m3_M3VolumeNoiseMaterial_set_falloffType(
25776            self_: *mut whiteout_M3VolumeNoiseMaterial,
25777            value: i32,
25778        );
25779        pub fn whiteout_m3_M3VolumeNoiseMaterial_get_drawTransparency(
25780            self_: *mut whiteout_M3VolumeNoiseMaterial,
25781        ) -> i32;
25782        pub fn whiteout_m3_M3VolumeNoiseMaterial_set_drawTransparency(
25783            self_: *mut whiteout_M3VolumeNoiseMaterial,
25784            value: i32,
25785        );
25786        pub fn whiteout_m3_M3VolumeNoiseMaterial_get_density(
25787            self_: *mut whiteout_M3VolumeNoiseMaterial,
25788        ) -> *mut whiteout_M3AnimRefF32;
25789        pub fn whiteout_m3_M3VolumeNoiseMaterial_set_density(
25790            self_: *mut whiteout_M3VolumeNoiseMaterial,
25791            value: *const whiteout_M3AnimRefF32,
25792        );
25793        pub fn whiteout_m3_M3VolumeNoiseMaterial_get_nearPlane(
25794            self_: *mut whiteout_M3VolumeNoiseMaterial,
25795        ) -> *mut whiteout_M3AnimRefF32;
25796        pub fn whiteout_m3_M3VolumeNoiseMaterial_set_nearPlane(
25797            self_: *mut whiteout_M3VolumeNoiseMaterial,
25798            value: *const whiteout_M3AnimRefF32,
25799        );
25800        pub fn whiteout_m3_M3VolumeNoiseMaterial_get_falloff(
25801            self_: *mut whiteout_M3VolumeNoiseMaterial,
25802        ) -> *mut whiteout_M3AnimRefF32;
25803        pub fn whiteout_m3_M3VolumeNoiseMaterial_set_falloff(
25804            self_: *mut whiteout_M3VolumeNoiseMaterial,
25805            value: *const whiteout_M3AnimRefF32,
25806        );
25807        pub fn whiteout_m3_M3VolumeNoiseMaterial_get_scrollRate(
25808            self_: *mut whiteout_M3VolumeNoiseMaterial,
25809        ) -> *mut whiteout_M3AnimRefVector3f;
25810        pub fn whiteout_m3_M3VolumeNoiseMaterial_set_scrollRate(
25811            self_: *mut whiteout_M3VolumeNoiseMaterial,
25812            value: *const whiteout_M3AnimRefVector3f,
25813        );
25814        pub fn whiteout_m3_M3VolumeNoiseMaterial_get_position(
25815            self_: *mut whiteout_M3VolumeNoiseMaterial,
25816        ) -> *mut whiteout_M3AnimRefVector3f;
25817        pub fn whiteout_m3_M3VolumeNoiseMaterial_set_position(
25818            self_: *mut whiteout_M3VolumeNoiseMaterial,
25819            value: *const whiteout_M3AnimRefVector3f,
25820        );
25821        pub fn whiteout_m3_M3VolumeNoiseMaterial_get_scale(
25822            self_: *mut whiteout_M3VolumeNoiseMaterial,
25823        ) -> *mut whiteout_M3AnimRefVector3f;
25824        pub fn whiteout_m3_M3VolumeNoiseMaterial_set_scale(
25825            self_: *mut whiteout_M3VolumeNoiseMaterial,
25826            value: *const whiteout_M3AnimRefVector3f,
25827        );
25828        pub fn whiteout_m3_M3VolumeNoiseMaterial_get_rotation(
25829            self_: *mut whiteout_M3VolumeNoiseMaterial,
25830        ) -> *mut whiteout_M3AnimRefVector3f;
25831        pub fn whiteout_m3_M3VolumeNoiseMaterial_set_rotation(
25832            self_: *mut whiteout_M3VolumeNoiseMaterial,
25833            value: *const whiteout_M3AnimRefVector3f,
25834        );
25835        pub fn whiteout_m3_M3VolumeNoiseMaterial_get_alphaThreshold(
25836            self_: *mut whiteout_M3VolumeNoiseMaterial,
25837        ) -> u32;
25838        pub fn whiteout_m3_M3VolumeNoiseMaterial_set_alphaThreshold(
25839            self_: *mut whiteout_M3VolumeNoiseMaterial,
25840            value: u32,
25841        );
25842        pub fn whiteout_m3_M3VolumeNoiseMaterial_get_flags(
25843            self_: *mut whiteout_M3VolumeNoiseMaterial,
25844        ) -> i32;
25845        pub fn whiteout_m3_M3VolumeNoiseMaterial_set_flags(
25846            self_: *mut whiteout_M3VolumeNoiseMaterial,
25847            value: i32,
25848        );
25849        // CreepMaterial
25850        pub fn whiteout_m3_M3CreepMaterial_new() -> *mut whiteout_M3CreepMaterial;
25851        pub fn whiteout_m3_M3CreepMaterial_delete(self_: *mut whiteout_M3CreepMaterial);
25852        pub fn whiteout_m3_M3CreepMaterial_get_name(
25853            self_: *mut whiteout_M3CreepMaterial,
25854        ) -> RawCString;
25855        pub fn whiteout_m3_M3CreepMaterial_set_name(
25856            self_: *mut whiteout_M3CreepMaterial,
25857            value: *const core::ffi::c_char,
25858        );
25859        pub fn whiteout_m3_M3CreepMaterial_get_creepLow(
25860            self_: *mut whiteout_M3CreepMaterial,
25861        ) -> u32;
25862        pub fn whiteout_m3_M3CreepMaterial_set_creepLow(
25863            self_: *mut whiteout_M3CreepMaterial,
25864            value: u32,
25865        );
25866        // STBMaterial
25867        pub fn whiteout_m3_M3STBMaterial_new() -> *mut whiteout_M3STBMaterial;
25868        pub fn whiteout_m3_M3STBMaterial_delete(self_: *mut whiteout_M3STBMaterial);
25869        pub fn whiteout_m3_M3STBMaterial_get_name(self_: *mut whiteout_M3STBMaterial)
25870            -> RawCString;
25871        pub fn whiteout_m3_M3STBMaterial_set_name(
25872            self_: *mut whiteout_M3STBMaterial,
25873            value: *const core::ffi::c_char,
25874        );
25875        // ReflectionMaterial
25876        pub fn whiteout_m3_M3ReflectionMaterial_new() -> *mut whiteout_M3ReflectionMaterial;
25877        pub fn whiteout_m3_M3ReflectionMaterial_delete(self_: *mut whiteout_M3ReflectionMaterial);
25878        pub fn whiteout_m3_M3ReflectionMaterial_get_name(
25879            self_: *mut whiteout_M3ReflectionMaterial,
25880        ) -> RawCString;
25881        pub fn whiteout_m3_M3ReflectionMaterial_set_name(
25882            self_: *mut whiteout_M3ReflectionMaterial,
25883            value: *const core::ffi::c_char,
25884        );
25885        pub fn whiteout_m3_M3ReflectionMaterial_get_unknown(
25886            self_: *mut whiteout_M3ReflectionMaterial,
25887        ) -> u32;
25888        pub fn whiteout_m3_M3ReflectionMaterial_set_unknown(
25889            self_: *mut whiteout_M3ReflectionMaterial,
25890            value: u32,
25891        );
25892        pub fn whiteout_m3_M3ReflectionMaterial_get_reflectionStrength(
25893            self_: *mut whiteout_M3ReflectionMaterial,
25894        ) -> *mut whiteout_M3AnimRefF32;
25895        pub fn whiteout_m3_M3ReflectionMaterial_set_reflectionStrength(
25896            self_: *mut whiteout_M3ReflectionMaterial,
25897            value: *const whiteout_M3AnimRefF32,
25898        );
25899        pub fn whiteout_m3_M3ReflectionMaterial_get_displacementStrength(
25900            self_: *mut whiteout_M3ReflectionMaterial,
25901        ) -> *mut whiteout_M3AnimRefF32;
25902        pub fn whiteout_m3_M3ReflectionMaterial_set_displacementStrength(
25903            self_: *mut whiteout_M3ReflectionMaterial,
25904            value: *const whiteout_M3AnimRefF32,
25905        );
25906        pub fn whiteout_m3_M3ReflectionMaterial_get_reflectionOffset(
25907            self_: *mut whiteout_M3ReflectionMaterial,
25908        ) -> *mut whiteout_M3AnimRefF32;
25909        pub fn whiteout_m3_M3ReflectionMaterial_set_reflectionOffset(
25910            self_: *mut whiteout_M3ReflectionMaterial,
25911            value: *const whiteout_M3AnimRefF32,
25912        );
25913        pub fn whiteout_m3_M3ReflectionMaterial_get_blurAngle(
25914            self_: *mut whiteout_M3ReflectionMaterial,
25915        ) -> *mut whiteout_M3AnimRefF32;
25916        pub fn whiteout_m3_M3ReflectionMaterial_set_blurAngle(
25917            self_: *mut whiteout_M3ReflectionMaterial,
25918            value: *const whiteout_M3AnimRefF32,
25919        );
25920        pub fn whiteout_m3_M3ReflectionMaterial_get_blurDistanceMax(
25921            self_: *mut whiteout_M3ReflectionMaterial,
25922        ) -> *mut whiteout_M3AnimRefF32;
25923        pub fn whiteout_m3_M3ReflectionMaterial_set_blurDistanceMax(
25924            self_: *mut whiteout_M3ReflectionMaterial,
25925            value: *const whiteout_M3AnimRefF32,
25926        );
25927        pub fn whiteout_m3_M3ReflectionMaterial_get_flags(
25928            self_: *mut whiteout_M3ReflectionMaterial,
25929        ) -> i32;
25930        pub fn whiteout_m3_M3ReflectionMaterial_set_flags(
25931            self_: *mut whiteout_M3ReflectionMaterial,
25932            value: i32,
25933        );
25934        pub fn whiteout_m3_M3ReflectionMaterial_get_unknown2(
25935            self_: *mut whiteout_M3ReflectionMaterial,
25936        ) -> u32;
25937        pub fn whiteout_m3_M3ReflectionMaterial_set_unknown2(
25938            self_: *mut whiteout_M3ReflectionMaterial,
25939            value: u32,
25940        );
25941        // SubFlare
25942        pub fn whiteout_m3_M3SubFlare_new() -> *mut whiteout_M3SubFlare;
25943        pub fn whiteout_m3_M3SubFlare_delete(self_: *mut whiteout_M3SubFlare);
25944        pub fn whiteout_m3_M3SubFlare_get_index(self_: *mut whiteout_M3SubFlare) -> u32;
25945        pub fn whiteout_m3_M3SubFlare_set_index(self_: *mut whiteout_M3SubFlare, value: u32);
25946        pub fn whiteout_m3_M3SubFlare_get_position(self_: *mut whiteout_M3SubFlare) -> f32;
25947        pub fn whiteout_m3_M3SubFlare_set_position(self_: *mut whiteout_M3SubFlare, value: f32);
25948        pub fn whiteout_m3_M3SubFlare_get_sizeXY(
25949            self_: *mut whiteout_M3SubFlare,
25950        ) -> *mut core::ffi::c_void;
25951        pub fn whiteout_m3_M3SubFlare_set_sizeXY(
25952            self_: *mut whiteout_M3SubFlare,
25953            value: *const core::ffi::c_void,
25954        );
25955        pub fn whiteout_m3_M3SubFlare_get_scaleXY(
25956            self_: *mut whiteout_M3SubFlare,
25957        ) -> *mut core::ffi::c_void;
25958        pub fn whiteout_m3_M3SubFlare_set_scaleXY(
25959            self_: *mut whiteout_M3SubFlare,
25960            value: *const core::ffi::c_void,
25961        );
25962        pub fn whiteout_m3_M3SubFlare_get_fadeIn(
25963            self_: *mut whiteout_M3SubFlare,
25964        ) -> *mut core::ffi::c_void;
25965        pub fn whiteout_m3_M3SubFlare_set_fadeIn(
25966            self_: *mut whiteout_M3SubFlare,
25967            value: *const core::ffi::c_void,
25968        );
25969        pub fn whiteout_m3_M3SubFlare_get_fadeOut(
25970            self_: *mut whiteout_M3SubFlare,
25971        ) -> *mut core::ffi::c_void;
25972        pub fn whiteout_m3_M3SubFlare_set_fadeOut(
25973            self_: *mut whiteout_M3SubFlare,
25974            value: *const core::ffi::c_void,
25975        );
25976        pub fn whiteout_m3_M3SubFlare_get_colorAlpha(
25977            self_: *mut whiteout_M3SubFlare,
25978        ) -> *mut whiteout_M3ColorBGRA;
25979        pub fn whiteout_m3_M3SubFlare_set_colorAlpha(
25980            self_: *mut whiteout_M3SubFlare,
25981            value: *const whiteout_M3ColorBGRA,
25982        );
25983        pub fn whiteout_m3_M3SubFlare_get_faceCenter(self_: *mut whiteout_M3SubFlare) -> u32;
25984        pub fn whiteout_m3_M3SubFlare_set_faceCenter(self_: *mut whiteout_M3SubFlare, value: u32);
25985        pub fn whiteout_m3_M3SubFlare_get_offset(
25986            self_: *mut whiteout_M3SubFlare,
25987        ) -> *mut core::ffi::c_void;
25988        pub fn whiteout_m3_M3SubFlare_set_offset(
25989            self_: *mut whiteout_M3SubFlare,
25990            value: *const core::ffi::c_void,
25991        );
25992        // LensFlare
25993        pub fn whiteout_m3_M3LensFlare_new() -> *mut whiteout_M3LensFlare;
25994        pub fn whiteout_m3_M3LensFlare_delete(self_: *mut whiteout_M3LensFlare);
25995        pub fn whiteout_m3_M3LensFlare_get_name(self_: *mut whiteout_M3LensFlare) -> RawCString;
25996        pub fn whiteout_m3_M3LensFlare_set_name(
25997            self_: *mut whiteout_M3LensFlare,
25998            value: *const core::ffi::c_char,
25999        );
26000        pub fn whiteout_m3_M3LensFlare_get_subFlares_count(
26001            self_: *mut whiteout_M3LensFlare,
26002        ) -> usize;
26003        pub fn whiteout_m3_M3LensFlare_resize_subFlares(
26004            self_: *mut whiteout_M3LensFlare,
26005            count: usize,
26006        );
26007        pub fn whiteout_m3_M3LensFlare_get_subFlares_at(
26008            self_: *mut whiteout_M3LensFlare,
26009            index: usize,
26010        ) -> *mut whiteout_M3SubFlare;
26011        pub fn whiteout_m3_M3LensFlare_get_columns(self_: *mut whiteout_M3LensFlare) -> u32;
26012        pub fn whiteout_m3_M3LensFlare_set_columns(self_: *mut whiteout_M3LensFlare, value: u32);
26013        pub fn whiteout_m3_M3LensFlare_get_rows(self_: *mut whiteout_M3LensFlare) -> u32;
26014        pub fn whiteout_m3_M3LensFlare_set_rows(self_: *mut whiteout_M3LensFlare, value: u32);
26015        pub fn whiteout_m3_M3LensFlare_get_distanceFade(self_: *mut whiteout_M3LensFlare) -> f32;
26016        pub fn whiteout_m3_M3LensFlare_set_distanceFade(
26017            self_: *mut whiteout_M3LensFlare,
26018            value: f32,
26019        );
26020        pub fn whiteout_m3_M3LensFlare_get_libName(self_: *mut whiteout_M3LensFlare) -> RawCString;
26021        pub fn whiteout_m3_M3LensFlare_set_libName(
26022            self_: *mut whiteout_M3LensFlare,
26023            value: *const core::ffi::c_char,
26024        );
26025        pub fn whiteout_m3_M3LensFlare_get_intensity(
26026            self_: *mut whiteout_M3LensFlare,
26027        ) -> *mut whiteout_M3AnimRefF32;
26028        pub fn whiteout_m3_M3LensFlare_set_intensity(
26029            self_: *mut whiteout_M3LensFlare,
26030            value: *const whiteout_M3AnimRefF32,
26031        );
26032        pub fn whiteout_m3_M3LensFlare_get_color(
26033            self_: *mut whiteout_M3LensFlare,
26034        ) -> *mut whiteout_M3AnimRefM3ColorBGRA;
26035        pub fn whiteout_m3_M3LensFlare_set_color(
26036            self_: *mut whiteout_M3LensFlare,
26037            value: *const whiteout_M3AnimRefM3ColorBGRA,
26038        );
26039        pub fn whiteout_m3_M3LensFlare_get_hdr(
26040            self_: *mut whiteout_M3LensFlare,
26041        ) -> *mut whiteout_M3AnimRefF32;
26042        pub fn whiteout_m3_M3LensFlare_set_hdr(
26043            self_: *mut whiteout_M3LensFlare,
26044            value: *const whiteout_M3AnimRefF32,
26045        );
26046        pub fn whiteout_m3_M3LensFlare_get_size(
26047            self_: *mut whiteout_M3LensFlare,
26048        ) -> *mut whiteout_M3AnimRefF32;
26049        pub fn whiteout_m3_M3LensFlare_set_size(
26050            self_: *mut whiteout_M3LensFlare,
26051            value: *const whiteout_M3AnimRefF32,
26052        );
26053        // MaterialAddData
26054        pub fn whiteout_m3_M3MaterialAddData_new() -> *mut whiteout_M3MaterialAddData;
26055        pub fn whiteout_m3_M3MaterialAddData_delete(self_: *mut whiteout_M3MaterialAddData);
26056        pub fn whiteout_m3_M3MaterialAddData_get_keyName(
26057            self_: *mut whiteout_M3MaterialAddData,
26058        ) -> RawCString;
26059        pub fn whiteout_m3_M3MaterialAddData_set_keyName(
26060            self_: *mut whiteout_M3MaterialAddData,
26061            value: *const core::ffi::c_char,
26062        );
26063        pub fn whiteout_m3_M3MaterialAddData_get_keyHash_count(
26064            self_: *mut whiteout_M3MaterialAddData,
26065        ) -> usize;
26066        pub fn whiteout_m3_M3MaterialAddData_resize_keyHash(
26067            self_: *mut whiteout_M3MaterialAddData,
26068            count: usize,
26069        );
26070        pub fn whiteout_m3_M3MaterialAddData_get_keyHash_data(
26071            self_: *mut whiteout_M3MaterialAddData,
26072        ) -> *const u32;
26073        pub fn whiteout_m3_M3MaterialAddData_assign_keyHash(
26074            self_: *mut whiteout_M3MaterialAddData,
26075            data: *const u32,
26076            count: usize,
26077        );
26078        pub fn whiteout_m3_M3MaterialAddData_get_extraHash_count(
26079            self_: *mut whiteout_M3MaterialAddData,
26080        ) -> usize;
26081        pub fn whiteout_m3_M3MaterialAddData_resize_extraHash(
26082            self_: *mut whiteout_M3MaterialAddData,
26083            count: usize,
26084        );
26085        pub fn whiteout_m3_M3MaterialAddData_get_extraHash_data(
26086            self_: *mut whiteout_M3MaterialAddData,
26087        ) -> *const u32;
26088        pub fn whiteout_m3_M3MaterialAddData_assign_extraHash(
26089            self_: *mut whiteout_M3MaterialAddData,
26090            data: *const u32,
26091            count: usize,
26092        );
26093        pub fn whiteout_m3_M3MaterialAddData_get_valuePath(
26094            self_: *mut whiteout_M3MaterialAddData,
26095        ) -> RawCString;
26096        pub fn whiteout_m3_M3MaterialAddData_set_valuePath(
26097            self_: *mut whiteout_M3MaterialAddData,
26098            value: *const core::ffi::c_char,
26099        );
26100        pub fn whiteout_m3_M3MaterialAddData_get_frequency(
26101            self_: *mut whiteout_M3MaterialAddData,
26102        ) -> f32;
26103        pub fn whiteout_m3_M3MaterialAddData_set_frequency(
26104            self_: *mut whiteout_M3MaterialAddData,
26105            value: f32,
26106        );
26107        pub fn whiteout_m3_M3MaterialAddData_get_intensity(
26108            self_: *mut whiteout_M3MaterialAddData,
26109        ) -> f32;
26110        pub fn whiteout_m3_M3MaterialAddData_set_intensity(
26111            self_: *mut whiteout_M3MaterialAddData,
26112            value: f32,
26113        );
26114        pub fn whiteout_m3_M3MaterialAddData_get_holdTime(
26115            self_: *mut whiteout_M3MaterialAddData,
26116        ) -> f32;
26117        pub fn whiteout_m3_M3MaterialAddData_set_holdTime(
26118            self_: *mut whiteout_M3MaterialAddData,
26119            value: f32,
26120        );
26121        pub fn whiteout_m3_M3MaterialAddData_get_randomHash(
26122            self_: *mut whiteout_M3MaterialAddData,
26123        ) -> u32;
26124        pub fn whiteout_m3_M3MaterialAddData_set_randomHash(
26125            self_: *mut whiteout_M3MaterialAddData,
26126            value: u32,
26127        );
26128        pub fn whiteout_m3_M3MaterialAddData_get_animationType(
26129            self_: *mut whiteout_M3MaterialAddData,
26130        ) -> u32;
26131        pub fn whiteout_m3_M3MaterialAddData_set_animationType(
26132            self_: *mut whiteout_M3MaterialAddData,
26133            value: u32,
26134        );
26135        pub fn whiteout_m3_M3MaterialAddData_get_padding0(
26136            self_: *mut whiteout_M3MaterialAddData,
26137        ) -> u32;
26138        pub fn whiteout_m3_M3MaterialAddData_set_padding0(
26139            self_: *mut whiteout_M3MaterialAddData,
26140            value: u32,
26141        );
26142        pub fn whiteout_m3_M3MaterialAddData_get_loopCount(
26143            self_: *mut whiteout_M3MaterialAddData,
26144        ) -> i32;
26145        pub fn whiteout_m3_M3MaterialAddData_set_loopCount(
26146            self_: *mut whiteout_M3MaterialAddData,
26147            value: i32,
26148        );
26149        pub fn whiteout_m3_M3MaterialAddData_get_flags(
26150            self_: *mut whiteout_M3MaterialAddData,
26151        ) -> u32;
26152        pub fn whiteout_m3_M3MaterialAddData_set_flags(
26153            self_: *mut whiteout_M3MaterialAddData,
26154            value: u32,
26155        );
26156        pub fn whiteout_m3_M3MaterialAddData_get_subType(
26157            self_: *mut whiteout_M3MaterialAddData,
26158        ) -> u32;
26159        pub fn whiteout_m3_M3MaterialAddData_set_subType(
26160            self_: *mut whiteout_M3MaterialAddData,
26161            value: u32,
26162        );
26163        pub fn whiteout_m3_M3MaterialAddData_get_configA(
26164            self_: *mut whiteout_M3MaterialAddData,
26165        ) -> u32;
26166        pub fn whiteout_m3_M3MaterialAddData_set_configA(
26167            self_: *mut whiteout_M3MaterialAddData,
26168            value: u32,
26169        );
26170        pub fn whiteout_m3_M3MaterialAddData_get_configB(
26171            self_: *mut whiteout_M3MaterialAddData,
26172        ) -> u32;
26173        pub fn whiteout_m3_M3MaterialAddData_set_configB(
26174            self_: *mut whiteout_M3MaterialAddData,
26175            value: u32,
26176        );
26177        pub fn whiteout_m3_M3MaterialAddData_get_extraId0(
26178            self_: *mut whiteout_M3MaterialAddData,
26179        ) -> u32;
26180        pub fn whiteout_m3_M3MaterialAddData_set_extraId0(
26181            self_: *mut whiteout_M3MaterialAddData,
26182            value: u32,
26183        );
26184        pub fn whiteout_m3_M3MaterialAddData_get_extraId1(
26185            self_: *mut whiteout_M3MaterialAddData,
26186        ) -> u32;
26187        pub fn whiteout_m3_M3MaterialAddData_set_extraId1(
26188            self_: *mut whiteout_M3MaterialAddData,
26189            value: u32,
26190        );
26191        // Bone
26192        pub fn whiteout_m3_M3Bone_new() -> *mut whiteout_M3Bone;
26193        pub fn whiteout_m3_M3Bone_delete(self_: *mut whiteout_M3Bone);
26194        pub fn whiteout_m3_M3Bone_get_unknown(self_: *mut whiteout_M3Bone) -> u32;
26195        pub fn whiteout_m3_M3Bone_set_unknown(self_: *mut whiteout_M3Bone, value: u32);
26196        pub fn whiteout_m3_M3Bone_get_name(self_: *mut whiteout_M3Bone) -> RawCString;
26197        pub fn whiteout_m3_M3Bone_set_name(
26198            self_: *mut whiteout_M3Bone,
26199            value: *const core::ffi::c_char,
26200        );
26201        pub fn whiteout_m3_M3Bone_get_flags(self_: *mut whiteout_M3Bone) -> i32;
26202        pub fn whiteout_m3_M3Bone_set_flags(self_: *mut whiteout_M3Bone, value: i32);
26203        pub fn whiteout_m3_M3Bone_get_parentIndex(self_: *mut whiteout_M3Bone) -> u16;
26204        pub fn whiteout_m3_M3Bone_set_parentIndex(self_: *mut whiteout_M3Bone, value: u16);
26205        pub fn whiteout_m3_M3Bone_get_padding(self_: *mut whiteout_M3Bone) -> u16;
26206        pub fn whiteout_m3_M3Bone_set_padding(self_: *mut whiteout_M3Bone, value: u16);
26207        pub fn whiteout_m3_M3Bone_get_position(
26208            self_: *mut whiteout_M3Bone,
26209        ) -> *mut whiteout_M3AnimRefVector3f;
26210        pub fn whiteout_m3_M3Bone_set_position(
26211            self_: *mut whiteout_M3Bone,
26212            value: *const whiteout_M3AnimRefVector3f,
26213        );
26214        pub fn whiteout_m3_M3Bone_get_rotation(
26215            self_: *mut whiteout_M3Bone,
26216        ) -> *mut whiteout_M3AnimRefQuaternion;
26217        pub fn whiteout_m3_M3Bone_set_rotation(
26218            self_: *mut whiteout_M3Bone,
26219            value: *const whiteout_M3AnimRefQuaternion,
26220        );
26221        pub fn whiteout_m3_M3Bone_get_scale(
26222            self_: *mut whiteout_M3Bone,
26223        ) -> *mut whiteout_M3AnimRefVector3f;
26224        pub fn whiteout_m3_M3Bone_set_scale(
26225            self_: *mut whiteout_M3Bone,
26226            value: *const whiteout_M3AnimRefVector3f,
26227        );
26228        pub fn whiteout_m3_M3Bone_get_visibility(
26229            self_: *mut whiteout_M3Bone,
26230        ) -> *mut whiteout_M3AnimRefU32;
26231        pub fn whiteout_m3_M3Bone_set_visibility(
26232            self_: *mut whiteout_M3Bone,
26233            value: *const whiteout_M3AnimRefU32,
26234        );
26235        // Region
26236        pub fn whiteout_m3_M3Region_new() -> *mut whiteout_M3Region;
26237        pub fn whiteout_m3_M3Region_delete(self_: *mut whiteout_M3Region);
26238        pub fn whiteout_m3_M3Region_get_index(self_: *mut whiteout_M3Region) -> u32;
26239        pub fn whiteout_m3_M3Region_set_index(self_: *mut whiteout_M3Region, value: u32);
26240        pub fn whiteout_m3_M3Region_get_unknown(self_: *mut whiteout_M3Region) -> u32;
26241        pub fn whiteout_m3_M3Region_set_unknown(self_: *mut whiteout_M3Region, value: u32);
26242        pub fn whiteout_m3_M3Region_get_firstVertex(self_: *mut whiteout_M3Region) -> u32;
26243        pub fn whiteout_m3_M3Region_set_firstVertex(self_: *mut whiteout_M3Region, value: u32);
26244        pub fn whiteout_m3_M3Region_get_vertexCount(self_: *mut whiteout_M3Region) -> u32;
26245        pub fn whiteout_m3_M3Region_set_vertexCount(self_: *mut whiteout_M3Region, value: u32);
26246        pub fn whiteout_m3_M3Region_get_firstIndex(self_: *mut whiteout_M3Region) -> u32;
26247        pub fn whiteout_m3_M3Region_set_firstIndex(self_: *mut whiteout_M3Region, value: u32);
26248        pub fn whiteout_m3_M3Region_get_indexCount(self_: *mut whiteout_M3Region) -> u32;
26249        pub fn whiteout_m3_M3Region_set_indexCount(self_: *mut whiteout_M3Region, value: u32);
26250        pub fn whiteout_m3_M3Region_get_unknown2(self_: *mut whiteout_M3Region) -> u16;
26251        pub fn whiteout_m3_M3Region_set_unknown2(self_: *mut whiteout_M3Region, value: u16);
26252        pub fn whiteout_m3_M3Region_get_firstBoneLookup(self_: *mut whiteout_M3Region) -> u16;
26253        pub fn whiteout_m3_M3Region_set_firstBoneLookup(self_: *mut whiteout_M3Region, value: u16);
26254        pub fn whiteout_m3_M3Region_get_boneLookupCount(self_: *mut whiteout_M3Region) -> u16;
26255        pub fn whiteout_m3_M3Region_set_boneLookupCount(self_: *mut whiteout_M3Region, value: u16);
26256        pub fn whiteout_m3_M3Region_get_padding(self_: *mut whiteout_M3Region) -> u16;
26257        pub fn whiteout_m3_M3Region_set_padding(self_: *mut whiteout_M3Region, value: u16);
26258        pub fn whiteout_m3_M3Region_get_boneWeightPairs(self_: *mut whiteout_M3Region) -> u8;
26259        pub fn whiteout_m3_M3Region_set_boneWeightPairs(self_: *mut whiteout_M3Region, value: u8);
26260        pub fn whiteout_m3_M3Region_get_boneIndexPairs(self_: *mut whiteout_M3Region) -> u8;
26261        pub fn whiteout_m3_M3Region_set_boneIndexPairs(self_: *mut whiteout_M3Region, value: u8);
26262        pub fn whiteout_m3_M3Region_get_rootBone(self_: *mut whiteout_M3Region) -> u16;
26263        pub fn whiteout_m3_M3Region_set_rootBone(self_: *mut whiteout_M3Region, value: u16);
26264        pub fn whiteout_m3_M3Region_get_flags(self_: *mut whiteout_M3Region) -> i32;
26265        pub fn whiteout_m3_M3Region_set_flags(self_: *mut whiteout_M3Region, value: i32);
26266        pub fn whiteout_m3_M3Region_get_uvScale(self_: *mut whiteout_M3Region) -> f32;
26267        pub fn whiteout_m3_M3Region_set_uvScale(self_: *mut whiteout_M3Region, value: f32);
26268        pub fn whiteout_m3_M3Region_get_uvOffset(self_: *mut whiteout_M3Region) -> f32;
26269        pub fn whiteout_m3_M3Region_set_uvOffset(self_: *mut whiteout_M3Region, value: f32);
26270        // Batch
26271        pub fn whiteout_m3_M3Batch_new() -> *mut whiteout_M3Batch;
26272        pub fn whiteout_m3_M3Batch_delete(self_: *mut whiteout_M3Batch);
26273        pub fn whiteout_m3_M3Batch_get_unknown(self_: *mut whiteout_M3Batch) -> u32;
26274        pub fn whiteout_m3_M3Batch_set_unknown(self_: *mut whiteout_M3Batch, value: u32);
26275        pub fn whiteout_m3_M3Batch_get_regionIndex(self_: *mut whiteout_M3Batch) -> u16;
26276        pub fn whiteout_m3_M3Batch_set_regionIndex(self_: *mut whiteout_M3Batch, value: u16);
26277        pub fn whiteout_m3_M3Batch_get_unknown2(self_: *mut whiteout_M3Batch) -> u32;
26278        pub fn whiteout_m3_M3Batch_set_unknown2(self_: *mut whiteout_M3Batch, value: u32);
26279        pub fn whiteout_m3_M3Batch_get_materialIndex(self_: *mut whiteout_M3Batch) -> u16;
26280        pub fn whiteout_m3_M3Batch_set_materialIndex(self_: *mut whiteout_M3Batch, value: u16);
26281        pub fn whiteout_m3_M3Batch_get_boneCount(self_: *mut whiteout_M3Batch) -> u16;
26282        pub fn whiteout_m3_M3Batch_set_boneCount(self_: *mut whiteout_M3Batch, value: u16);
26283        // MeshSection
26284        pub fn whiteout_m3_M3MeshSection_new() -> *mut whiteout_M3MeshSection;
26285        pub fn whiteout_m3_M3MeshSection_delete(self_: *mut whiteout_M3MeshSection);
26286        pub fn whiteout_m3_M3MeshSection_get_nodeIndex(self_: *mut whiteout_M3MeshSection) -> u32;
26287        pub fn whiteout_m3_M3MeshSection_set_nodeIndex(
26288            self_: *mut whiteout_M3MeshSection,
26289            value: u32,
26290        );
26291        pub fn whiteout_m3_M3MeshSection_get_bounds(
26292            self_: *mut whiteout_M3MeshSection,
26293        ) -> *mut whiteout_M3AnimRefM3Extent;
26294        pub fn whiteout_m3_M3MeshSection_set_bounds(
26295            self_: *mut whiteout_M3MeshSection,
26296            value: *const whiteout_M3AnimRefM3Extent,
26297        );
26298        // MeshDivision
26299        pub fn whiteout_m3_M3MeshDivision_new() -> *mut whiteout_M3MeshDivision;
26300        pub fn whiteout_m3_M3MeshDivision_delete(self_: *mut whiteout_M3MeshDivision);
26301        pub fn whiteout_m3_M3MeshDivision_get_faces_count(
26302            self_: *mut whiteout_M3MeshDivision,
26303        ) -> usize;
26304        pub fn whiteout_m3_M3MeshDivision_resize_faces(
26305            self_: *mut whiteout_M3MeshDivision,
26306            count: usize,
26307        );
26308        pub fn whiteout_m3_M3MeshDivision_get_faces_data(
26309            self_: *mut whiteout_M3MeshDivision,
26310        ) -> *const u16;
26311        pub fn whiteout_m3_M3MeshDivision_assign_faces(
26312            self_: *mut whiteout_M3MeshDivision,
26313            data: *const u16,
26314            count: usize,
26315        );
26316        pub fn whiteout_m3_M3MeshDivision_get_regions_count(
26317            self_: *mut whiteout_M3MeshDivision,
26318        ) -> usize;
26319        pub fn whiteout_m3_M3MeshDivision_resize_regions(
26320            self_: *mut whiteout_M3MeshDivision,
26321            count: usize,
26322        );
26323        pub fn whiteout_m3_M3MeshDivision_get_regions_at(
26324            self_: *mut whiteout_M3MeshDivision,
26325            index: usize,
26326        ) -> *mut whiteout_M3Region;
26327        pub fn whiteout_m3_M3MeshDivision_get_batches_count(
26328            self_: *mut whiteout_M3MeshDivision,
26329        ) -> usize;
26330        pub fn whiteout_m3_M3MeshDivision_resize_batches(
26331            self_: *mut whiteout_M3MeshDivision,
26332            count: usize,
26333        );
26334        pub fn whiteout_m3_M3MeshDivision_get_batches_at(
26335            self_: *mut whiteout_M3MeshDivision,
26336            index: usize,
26337        ) -> *mut whiteout_M3Batch;
26338        pub fn whiteout_m3_M3MeshDivision_get_msec_count(
26339            self_: *mut whiteout_M3MeshDivision,
26340        ) -> usize;
26341        pub fn whiteout_m3_M3MeshDivision_resize_msec(
26342            self_: *mut whiteout_M3MeshDivision,
26343            count: usize,
26344        );
26345        pub fn whiteout_m3_M3MeshDivision_get_msec_at(
26346            self_: *mut whiteout_M3MeshDivision,
26347            index: usize,
26348        ) -> *mut whiteout_M3MeshSection;
26349        pub fn whiteout_m3_M3MeshDivision_get_instances(self_: *mut whiteout_M3MeshDivision)
26350            -> u32;
26351        pub fn whiteout_m3_M3MeshDivision_set_instances(
26352            self_: *mut whiteout_M3MeshDivision,
26353            value: u32,
26354        );
26355        // InitialReference
26356        pub fn whiteout_m3_M3InitialReference_new() -> *mut whiteout_M3InitialReference;
26357        pub fn whiteout_m3_M3InitialReference_delete(self_: *mut whiteout_M3InitialReference);
26358        // AttachmentPoint
26359        pub fn whiteout_m3_M3AttachmentPoint_new() -> *mut whiteout_M3AttachmentPoint;
26360        pub fn whiteout_m3_M3AttachmentPoint_delete(self_: *mut whiteout_M3AttachmentPoint);
26361        pub fn whiteout_m3_M3AttachmentPoint_get_unknown(
26362            self_: *mut whiteout_M3AttachmentPoint,
26363        ) -> u32;
26364        pub fn whiteout_m3_M3AttachmentPoint_set_unknown(
26365            self_: *mut whiteout_M3AttachmentPoint,
26366            value: u32,
26367        );
26368        pub fn whiteout_m3_M3AttachmentPoint_get_name(
26369            self_: *mut whiteout_M3AttachmentPoint,
26370        ) -> RawCString;
26371        pub fn whiteout_m3_M3AttachmentPoint_set_name(
26372            self_: *mut whiteout_M3AttachmentPoint,
26373            value: *const core::ffi::c_char,
26374        );
26375        pub fn whiteout_m3_M3AttachmentPoint_get_boneIndex(
26376            self_: *mut whiteout_M3AttachmentPoint,
26377        ) -> u32;
26378        pub fn whiteout_m3_M3AttachmentPoint_set_boneIndex(
26379            self_: *mut whiteout_M3AttachmentPoint,
26380            value: u32,
26381        );
26382        // HitTestShape
26383        pub fn whiteout_m3_M3HitTestShape_new() -> *mut whiteout_M3HitTestShape;
26384        pub fn whiteout_m3_M3HitTestShape_delete(self_: *mut whiteout_M3HitTestShape);
26385        pub fn whiteout_m3_M3HitTestShape_get_shapeType(self_: *mut whiteout_M3HitTestShape)
26386            -> i32;
26387        pub fn whiteout_m3_M3HitTestShape_set_shapeType(
26388            self_: *mut whiteout_M3HitTestShape,
26389            value: i32,
26390        );
26391        pub fn whiteout_m3_M3HitTestShape_get_boneIndex(self_: *mut whiteout_M3HitTestShape)
26392            -> u16;
26393        pub fn whiteout_m3_M3HitTestShape_set_boneIndex(
26394            self_: *mut whiteout_M3HitTestShape,
26395            value: u16,
26396        );
26397        pub fn whiteout_m3_M3HitTestShape_get_padding(self_: *mut whiteout_M3HitTestShape) -> u16;
26398        pub fn whiteout_m3_M3HitTestShape_set_padding(
26399            self_: *mut whiteout_M3HitTestShape,
26400            value: u16,
26401        );
26402        pub fn whiteout_m3_M3HitTestShape_get_vertexPositions_count(
26403            self_: *mut whiteout_M3HitTestShape,
26404        ) -> usize;
26405        pub fn whiteout_m3_M3HitTestShape_resize_vertexPositions(
26406            self_: *mut whiteout_M3HitTestShape,
26407            count: usize,
26408        );
26409        pub fn whiteout_m3_M3HitTestShape_get_vertexPositions_data(
26410            self_: *mut whiteout_M3HitTestShape,
26411        ) -> *const f32;
26412        pub fn whiteout_m3_M3HitTestShape_assign_vertexPositions(
26413            self_: *mut whiteout_M3HitTestShape,
26414            data: *const f32,
26415            count: usize,
26416        );
26417        pub fn whiteout_m3_M3HitTestShape_get_faceIndices_count(
26418            self_: *mut whiteout_M3HitTestShape,
26419        ) -> usize;
26420        pub fn whiteout_m3_M3HitTestShape_resize_faceIndices(
26421            self_: *mut whiteout_M3HitTestShape,
26422            count: usize,
26423        );
26424        pub fn whiteout_m3_M3HitTestShape_get_faceIndices_data(
26425            self_: *mut whiteout_M3HitTestShape,
26426        ) -> *const u16;
26427        pub fn whiteout_m3_M3HitTestShape_assign_faceIndices(
26428            self_: *mut whiteout_M3HitTestShape,
26429            data: *const u16,
26430            count: usize,
26431        );
26432        pub fn whiteout_m3_M3HitTestShape_get_sizeX(self_: *mut whiteout_M3HitTestShape) -> f32;
26433        pub fn whiteout_m3_M3HitTestShape_set_sizeX(
26434            self_: *mut whiteout_M3HitTestShape,
26435            value: f32,
26436        );
26437        pub fn whiteout_m3_M3HitTestShape_get_sizeY(self_: *mut whiteout_M3HitTestShape) -> f32;
26438        pub fn whiteout_m3_M3HitTestShape_set_sizeY(
26439            self_: *mut whiteout_M3HitTestShape,
26440            value: f32,
26441        );
26442        pub fn whiteout_m3_M3HitTestShape_get_sizeZ(self_: *mut whiteout_M3HitTestShape) -> f32;
26443        pub fn whiteout_m3_M3HitTestShape_set_sizeZ(
26444            self_: *mut whiteout_M3HitTestShape,
26445            value: f32,
26446        );
26447        // AttachmentVolume
26448        pub fn whiteout_m3_M3AttachmentVolume_new() -> *mut whiteout_M3AttachmentVolume;
26449        pub fn whiteout_m3_M3AttachmentVolume_delete(self_: *mut whiteout_M3AttachmentVolume);
26450        pub fn whiteout_m3_M3AttachmentVolume_get_bone1(
26451            self_: *mut whiteout_M3AttachmentVolume,
26452        ) -> u32;
26453        pub fn whiteout_m3_M3AttachmentVolume_set_bone1(
26454            self_: *mut whiteout_M3AttachmentVolume,
26455            value: u32,
26456        );
26457        pub fn whiteout_m3_M3AttachmentVolume_get_bone2(
26458            self_: *mut whiteout_M3AttachmentVolume,
26459        ) -> u32;
26460        pub fn whiteout_m3_M3AttachmentVolume_set_bone2(
26461            self_: *mut whiteout_M3AttachmentVolume,
26462            value: u32,
26463        );
26464        pub fn whiteout_m3_M3AttachmentVolume_get_shapeType(
26465            self_: *mut whiteout_M3AttachmentVolume,
26466        ) -> i32;
26467        pub fn whiteout_m3_M3AttachmentVolume_set_shapeType(
26468            self_: *mut whiteout_M3AttachmentVolume,
26469            value: i32,
26470        );
26471        pub fn whiteout_m3_M3AttachmentVolume_get_boneIndex(
26472            self_: *mut whiteout_M3AttachmentVolume,
26473        ) -> u16;
26474        pub fn whiteout_m3_M3AttachmentVolume_set_boneIndex(
26475            self_: *mut whiteout_M3AttachmentVolume,
26476            value: u16,
26477        );
26478        pub fn whiteout_m3_M3AttachmentVolume_get_padding(
26479            self_: *mut whiteout_M3AttachmentVolume,
26480        ) -> u16;
26481        pub fn whiteout_m3_M3AttachmentVolume_set_padding(
26482            self_: *mut whiteout_M3AttachmentVolume,
26483            value: u16,
26484        );
26485        pub fn whiteout_m3_M3AttachmentVolume_get_vertexPositions_count(
26486            self_: *mut whiteout_M3AttachmentVolume,
26487        ) -> usize;
26488        pub fn whiteout_m3_M3AttachmentVolume_resize_vertexPositions(
26489            self_: *mut whiteout_M3AttachmentVolume,
26490            count: usize,
26491        );
26492        pub fn whiteout_m3_M3AttachmentVolume_get_vertexPositions_data(
26493            self_: *mut whiteout_M3AttachmentVolume,
26494        ) -> *const f32;
26495        pub fn whiteout_m3_M3AttachmentVolume_assign_vertexPositions(
26496            self_: *mut whiteout_M3AttachmentVolume,
26497            data: *const f32,
26498            count: usize,
26499        );
26500        pub fn whiteout_m3_M3AttachmentVolume_get_faceIndices_count(
26501            self_: *mut whiteout_M3AttachmentVolume,
26502        ) -> usize;
26503        pub fn whiteout_m3_M3AttachmentVolume_resize_faceIndices(
26504            self_: *mut whiteout_M3AttachmentVolume,
26505            count: usize,
26506        );
26507        pub fn whiteout_m3_M3AttachmentVolume_get_faceIndices_data(
26508            self_: *mut whiteout_M3AttachmentVolume,
26509        ) -> *const u16;
26510        pub fn whiteout_m3_M3AttachmentVolume_assign_faceIndices(
26511            self_: *mut whiteout_M3AttachmentVolume,
26512            data: *const u16,
26513            count: usize,
26514        );
26515        pub fn whiteout_m3_M3AttachmentVolume_get_sizeX(
26516            self_: *mut whiteout_M3AttachmentVolume,
26517        ) -> f32;
26518        pub fn whiteout_m3_M3AttachmentVolume_set_sizeX(
26519            self_: *mut whiteout_M3AttachmentVolume,
26520            value: f32,
26521        );
26522        pub fn whiteout_m3_M3AttachmentVolume_get_sizeY(
26523            self_: *mut whiteout_M3AttachmentVolume,
26524        ) -> f32;
26525        pub fn whiteout_m3_M3AttachmentVolume_set_sizeY(
26526            self_: *mut whiteout_M3AttachmentVolume,
26527            value: f32,
26528        );
26529        pub fn whiteout_m3_M3AttachmentVolume_get_sizeZ(
26530            self_: *mut whiteout_M3AttachmentVolume,
26531        ) -> f32;
26532        pub fn whiteout_m3_M3AttachmentVolume_set_sizeZ(
26533            self_: *mut whiteout_M3AttachmentVolume,
26534            value: f32,
26535        );
26536        // TriggerData
26537        pub fn whiteout_m3_M3TriggerData_new() -> *mut whiteout_M3TriggerData;
26538        pub fn whiteout_m3_M3TriggerData_delete(self_: *mut whiteout_M3TriggerData);
26539        pub fn whiteout_m3_M3TriggerData_get_dataIndices_count(
26540            self_: *mut whiteout_M3TriggerData,
26541        ) -> usize;
26542        pub fn whiteout_m3_M3TriggerData_resize_dataIndices(
26543            self_: *mut whiteout_M3TriggerData,
26544            count: usize,
26545        );
26546        pub fn whiteout_m3_M3TriggerData_get_dataIndices_data(
26547            self_: *mut whiteout_M3TriggerData,
26548        ) -> *const u32;
26549        pub fn whiteout_m3_M3TriggerData_assign_dataIndices(
26550            self_: *mut whiteout_M3TriggerData,
26551            data: *const u32,
26552            count: usize,
26553        );
26554        pub fn whiteout_m3_M3TriggerData_get_name(self_: *mut whiteout_M3TriggerData)
26555            -> RawCString;
26556        pub fn whiteout_m3_M3TriggerData_set_name(
26557            self_: *mut whiteout_M3TriggerData,
26558            value: *const core::ffi::c_char,
26559        );
26560        // TurretBehavior
26561        pub fn whiteout_m3_M3TurretBehavior_new() -> *mut whiteout_M3TurretBehavior;
26562        pub fn whiteout_m3_M3TurretBehavior_delete(self_: *mut whiteout_M3TurretBehavior);
26563        pub fn whiteout_m3_M3TurretBehavior_get_unknown1(
26564            self_: *mut whiteout_M3TurretBehavior,
26565        ) -> *mut core::ffi::c_void;
26566        pub fn whiteout_m3_M3TurretBehavior_set_unknown1(
26567            self_: *mut whiteout_M3TurretBehavior,
26568            value: *const core::ffi::c_void,
26569        );
26570        pub fn whiteout_m3_M3TurretBehavior_get_unknown2(
26571            self_: *mut whiteout_M3TurretBehavior,
26572        ) -> *mut core::ffi::c_void;
26573        pub fn whiteout_m3_M3TurretBehavior_set_unknown2(
26574            self_: *mut whiteout_M3TurretBehavior,
26575            value: *const core::ffi::c_void,
26576        );
26577        pub fn whiteout_m3_M3TurretBehavior_get_boneIndex(
26578            self_: *mut whiteout_M3TurretBehavior,
26579        ) -> u16;
26580        pub fn whiteout_m3_M3TurretBehavior_set_boneIndex(
26581            self_: *mut whiteout_M3TurretBehavior,
26582            value: u16,
26583        );
26584        pub fn whiteout_m3_M3TurretBehavior_get_useAsMainTurret(
26585            self_: *mut whiteout_M3TurretBehavior,
26586        ) -> u8;
26587        pub fn whiteout_m3_M3TurretBehavior_set_useAsMainTurret(
26588            self_: *mut whiteout_M3TurretBehavior,
26589            value: u8,
26590        );
26591        pub fn whiteout_m3_M3TurretBehavior_get_turretGroupId(
26592            self_: *mut whiteout_M3TurretBehavior,
26593        ) -> u8;
26594        pub fn whiteout_m3_M3TurretBehavior_set_turretGroupId(
26595            self_: *mut whiteout_M3TurretBehavior,
26596            value: u8,
26597        );
26598        pub fn whiteout_m3_M3TurretBehavior_get_yawLimited(
26599            self_: *mut whiteout_M3TurretBehavior,
26600        ) -> u32;
26601        pub fn whiteout_m3_M3TurretBehavior_set_yawLimited(
26602            self_: *mut whiteout_M3TurretBehavior,
26603            value: u32,
26604        );
26605        pub fn whiteout_m3_M3TurretBehavior_get_yawMin(
26606            self_: *mut whiteout_M3TurretBehavior,
26607        ) -> f32;
26608        pub fn whiteout_m3_M3TurretBehavior_set_yawMin(
26609            self_: *mut whiteout_M3TurretBehavior,
26610            value: f32,
26611        );
26612        pub fn whiteout_m3_M3TurretBehavior_get_yawMax(
26613            self_: *mut whiteout_M3TurretBehavior,
26614        ) -> f32;
26615        pub fn whiteout_m3_M3TurretBehavior_set_yawMax(
26616            self_: *mut whiteout_M3TurretBehavior,
26617            value: f32,
26618        );
26619        pub fn whiteout_m3_M3TurretBehavior_get_yawWeight(
26620            self_: *mut whiteout_M3TurretBehavior,
26621        ) -> f32;
26622        pub fn whiteout_m3_M3TurretBehavior_set_yawWeight(
26623            self_: *mut whiteout_M3TurretBehavior,
26624            value: f32,
26625        );
26626        pub fn whiteout_m3_M3TurretBehavior_get_pitchLimited(
26627            self_: *mut whiteout_M3TurretBehavior,
26628        ) -> u32;
26629        pub fn whiteout_m3_M3TurretBehavior_set_pitchLimited(
26630            self_: *mut whiteout_M3TurretBehavior,
26631            value: u32,
26632        );
26633        pub fn whiteout_m3_M3TurretBehavior_get_pitchMin(
26634            self_: *mut whiteout_M3TurretBehavior,
26635        ) -> f32;
26636        pub fn whiteout_m3_M3TurretBehavior_set_pitchMin(
26637            self_: *mut whiteout_M3TurretBehavior,
26638            value: f32,
26639        );
26640        pub fn whiteout_m3_M3TurretBehavior_get_pitchMax(
26641            self_: *mut whiteout_M3TurretBehavior,
26642        ) -> f32;
26643        pub fn whiteout_m3_M3TurretBehavior_set_pitchMax(
26644            self_: *mut whiteout_M3TurretBehavior,
26645            value: f32,
26646        );
26647        pub fn whiteout_m3_M3TurretBehavior_get_pitchWeight(
26648            self_: *mut whiteout_M3TurretBehavior,
26649        ) -> f32;
26650        pub fn whiteout_m3_M3TurretBehavior_set_pitchWeight(
26651            self_: *mut whiteout_M3TurretBehavior,
26652            value: f32,
26653        );
26654        pub fn whiteout_m3_M3TurretBehavior_get_unknown3(
26655            self_: *mut whiteout_M3TurretBehavior,
26656        ) -> f32;
26657        pub fn whiteout_m3_M3TurretBehavior_set_unknown3(
26658            self_: *mut whiteout_M3TurretBehavior,
26659            value: f32,
26660        );
26661        pub fn whiteout_m3_M3TurretBehavior_get_unknown4(
26662            self_: *mut whiteout_M3TurretBehavior,
26663        ) -> f32;
26664        pub fn whiteout_m3_M3TurretBehavior_set_unknown4(
26665            self_: *mut whiteout_M3TurretBehavior,
26666            value: f32,
26667        );
26668        pub fn whiteout_m3_M3TurretBehavior_get_mainBoneOffset(
26669            self_: *mut whiteout_M3TurretBehavior,
26670        ) -> *mut core::ffi::c_void;
26671        pub fn whiteout_m3_M3TurretBehavior_set_mainBoneOffset(
26672            self_: *mut whiteout_M3TurretBehavior,
26673            value: *const core::ffi::c_void,
26674        );
26675        // BillboardBehavior
26676        pub fn whiteout_m3_M3BillboardBehavior_new() -> *mut whiteout_M3BillboardBehavior;
26677        pub fn whiteout_m3_M3BillboardBehavior_delete(self_: *mut whiteout_M3BillboardBehavior);
26678        pub fn whiteout_m3_M3BillboardBehavior_get_dependents_count(
26679            self_: *mut whiteout_M3BillboardBehavior,
26680        ) -> usize;
26681        pub fn whiteout_m3_M3BillboardBehavior_resize_dependents(
26682            self_: *mut whiteout_M3BillboardBehavior,
26683            count: usize,
26684        );
26685        pub fn whiteout_m3_M3BillboardBehavior_get_dependents_data(
26686            self_: *mut whiteout_M3BillboardBehavior,
26687        ) -> *const u16;
26688        pub fn whiteout_m3_M3BillboardBehavior_assign_dependents(
26689            self_: *mut whiteout_M3BillboardBehavior,
26690            data: *const u16,
26691            count: usize,
26692        );
26693        pub fn whiteout_m3_M3BillboardBehavior_get_boneIndex(
26694            self_: *mut whiteout_M3BillboardBehavior,
26695        ) -> u16;
26696        pub fn whiteout_m3_M3BillboardBehavior_set_boneIndex(
26697            self_: *mut whiteout_M3BillboardBehavior,
26698            value: u16,
26699        );
26700        pub fn whiteout_m3_M3BillboardBehavior_get_billboardType(
26701            self_: *mut whiteout_M3BillboardBehavior,
26702        ) -> u8;
26703        pub fn whiteout_m3_M3BillboardBehavior_set_billboardType(
26704            self_: *mut whiteout_M3BillboardBehavior,
26705            value: u8,
26706        );
26707        pub fn whiteout_m3_M3BillboardBehavior_get_cameraLookAt(
26708            self_: *mut whiteout_M3BillboardBehavior,
26709        ) -> u8;
26710        pub fn whiteout_m3_M3BillboardBehavior_set_cameraLookAt(
26711            self_: *mut whiteout_M3BillboardBehavior,
26712            value: u8,
26713        );
26714        pub fn whiteout_m3_M3BillboardBehavior_get_up(
26715            self_: *mut whiteout_M3BillboardBehavior,
26716        ) -> *mut core::ffi::c_void;
26717        pub fn whiteout_m3_M3BillboardBehavior_set_up(
26718            self_: *mut whiteout_M3BillboardBehavior,
26719            value: *const core::ffi::c_void,
26720        );
26721        pub fn whiteout_m3_M3BillboardBehavior_get_forward(
26722            self_: *mut whiteout_M3BillboardBehavior,
26723        ) -> *mut core::ffi::c_void;
26724        pub fn whiteout_m3_M3BillboardBehavior_set_forward(
26725            self_: *mut whiteout_M3BillboardBehavior,
26726            value: *const core::ffi::c_void,
26727        );
26728        // IKJoint
26729        pub fn whiteout_m3_M3IKJoint_new() -> *mut whiteout_M3IKJoint;
26730        pub fn whiteout_m3_M3IKJoint_delete(self_: *mut whiteout_M3IKJoint);
26731        pub fn whiteout_m3_M3IKJoint_get_dependents_count(self_: *mut whiteout_M3IKJoint) -> usize;
26732        pub fn whiteout_m3_M3IKJoint_resize_dependents(
26733            self_: *mut whiteout_M3IKJoint,
26734            count: usize,
26735        );
26736        pub fn whiteout_m3_M3IKJoint_get_dependents_data(
26737            self_: *mut whiteout_M3IKJoint,
26738        ) -> *const u16;
26739        pub fn whiteout_m3_M3IKJoint_assign_dependents(
26740            self_: *mut whiteout_M3IKJoint,
26741            data: *const u16,
26742            count: usize,
26743        );
26744        pub fn whiteout_m3_M3IKJoint_get_boneIndex1(self_: *mut whiteout_M3IKJoint) -> u16;
26745        pub fn whiteout_m3_M3IKJoint_set_boneIndex1(self_: *mut whiteout_M3IKJoint, value: u16);
26746        pub fn whiteout_m3_M3IKJoint_get_boneIndex2(self_: *mut whiteout_M3IKJoint) -> u16;
26747        pub fn whiteout_m3_M3IKJoint_set_boneIndex2(self_: *mut whiteout_M3IKJoint, value: u16);
26748        pub fn whiteout_m3_M3IKJoint_get_raycastUp(self_: *mut whiteout_M3IKJoint) -> f32;
26749        pub fn whiteout_m3_M3IKJoint_set_raycastUp(self_: *mut whiteout_M3IKJoint, value: f32);
26750        pub fn whiteout_m3_M3IKJoint_get_raycastDown(self_: *mut whiteout_M3IKJoint) -> f32;
26751        pub fn whiteout_m3_M3IKJoint_set_raycastDown(self_: *mut whiteout_M3IKJoint, value: f32);
26752        pub fn whiteout_m3_M3IKJoint_get_maxSpeed(self_: *mut whiteout_M3IKJoint) -> f32;
26753        pub fn whiteout_m3_M3IKJoint_set_maxSpeed(self_: *mut whiteout_M3IKJoint, value: f32);
26754        pub fn whiteout_m3_M3IKJoint_get_goalThreshold(self_: *mut whiteout_M3IKJoint) -> f32;
26755        pub fn whiteout_m3_M3IKJoint_set_goalThreshold(self_: *mut whiteout_M3IKJoint, value: f32);
26756        // IKTwoJoint
26757        pub fn whiteout_m3_M3IKTwoJoint_new() -> *mut whiteout_M3IKTwoJoint;
26758        pub fn whiteout_m3_M3IKTwoJoint_delete(self_: *mut whiteout_M3IKTwoJoint);
26759        pub fn whiteout_m3_M3IKTwoJoint_get_dependents_count(
26760            self_: *mut whiteout_M3IKTwoJoint,
26761        ) -> usize;
26762        pub fn whiteout_m3_M3IKTwoJoint_resize_dependents(
26763            self_: *mut whiteout_M3IKTwoJoint,
26764            count: usize,
26765        );
26766        pub fn whiteout_m3_M3IKTwoJoint_get_dependents_data(
26767            self_: *mut whiteout_M3IKTwoJoint,
26768        ) -> *const u16;
26769        pub fn whiteout_m3_M3IKTwoJoint_assign_dependents(
26770            self_: *mut whiteout_M3IKTwoJoint,
26771            data: *const u16,
26772            count: usize,
26773        );
26774        pub fn whiteout_m3_M3IKTwoJoint_get_boneBase(self_: *mut whiteout_M3IKTwoJoint) -> u16;
26775        pub fn whiteout_m3_M3IKTwoJoint_set_boneBase(self_: *mut whiteout_M3IKTwoJoint, value: u16);
26776        pub fn whiteout_m3_M3IKTwoJoint_get_boneTarget(self_: *mut whiteout_M3IKTwoJoint) -> u16;
26777        pub fn whiteout_m3_M3IKTwoJoint_set_boneTarget(
26778            self_: *mut whiteout_M3IKTwoJoint,
26779            value: u16,
26780        );
26781        pub fn whiteout_m3_M3IKTwoJoint_get_boneEnd(self_: *mut whiteout_M3IKTwoJoint) -> u16;
26782        pub fn whiteout_m3_M3IKTwoJoint_set_boneEnd(self_: *mut whiteout_M3IKTwoJoint, value: u16);
26783        pub fn whiteout_m3_M3IKTwoJoint_get_padding(self_: *mut whiteout_M3IKTwoJoint) -> u16;
26784        pub fn whiteout_m3_M3IKTwoJoint_set_padding(self_: *mut whiteout_M3IKTwoJoint, value: u16);
26785        pub fn whiteout_m3_M3IKTwoJoint_get_hingeAxis(
26786            self_: *mut whiteout_M3IKTwoJoint,
26787        ) -> *mut core::ffi::c_void;
26788        pub fn whiteout_m3_M3IKTwoJoint_set_hingeAxis(
26789            self_: *mut whiteout_M3IKTwoJoint,
26790            value: *const core::ffi::c_void,
26791        );
26792        pub fn whiteout_m3_M3IKTwoJoint_get_maxAngleInner(self_: *mut whiteout_M3IKTwoJoint)
26793            -> f32;
26794        pub fn whiteout_m3_M3IKTwoJoint_set_maxAngleInner(
26795            self_: *mut whiteout_M3IKTwoJoint,
26796            value: f32,
26797        );
26798        pub fn whiteout_m3_M3IKTwoJoint_get_maxAngleOuter(self_: *mut whiteout_M3IKTwoJoint)
26799            -> f32;
26800        pub fn whiteout_m3_M3IKTwoJoint_set_maxAngleOuter(
26801            self_: *mut whiteout_M3IKTwoJoint,
26802            value: f32,
26803        );
26804        pub fn whiteout_m3_M3IKTwoJoint_get_searchUp(self_: *mut whiteout_M3IKTwoJoint) -> f32;
26805        pub fn whiteout_m3_M3IKTwoJoint_set_searchUp(self_: *mut whiteout_M3IKTwoJoint, value: f32);
26806        pub fn whiteout_m3_M3IKTwoJoint_get_searchDown(self_: *mut whiteout_M3IKTwoJoint) -> f32;
26807        pub fn whiteout_m3_M3IKTwoJoint_set_searchDown(
26808            self_: *mut whiteout_M3IKTwoJoint,
26809            value: f32,
26810        );
26811        // IKCCD
26812        pub fn whiteout_m3_M3IKCCD_new() -> *mut whiteout_M3IKCCD;
26813        pub fn whiteout_m3_M3IKCCD_delete(self_: *mut whiteout_M3IKCCD);
26814        pub fn whiteout_m3_M3IKCCD_get_dependents_count(self_: *mut whiteout_M3IKCCD) -> usize;
26815        pub fn whiteout_m3_M3IKCCD_resize_dependents(self_: *mut whiteout_M3IKCCD, count: usize);
26816        pub fn whiteout_m3_M3IKCCD_get_dependents_data(self_: *mut whiteout_M3IKCCD) -> *const u16;
26817        pub fn whiteout_m3_M3IKCCD_assign_dependents(
26818            self_: *mut whiteout_M3IKCCD,
26819            data: *const u16,
26820            count: usize,
26821        );
26822        pub fn whiteout_m3_M3IKCCD_get_boneBase(self_: *mut whiteout_M3IKCCD) -> u16;
26823        pub fn whiteout_m3_M3IKCCD_set_boneBase(self_: *mut whiteout_M3IKCCD, value: u16);
26824        pub fn whiteout_m3_M3IKCCD_get_boneTarget(self_: *mut whiteout_M3IKCCD) -> u16;
26825        pub fn whiteout_m3_M3IKCCD_set_boneTarget(self_: *mut whiteout_M3IKCCD, value: u16);
26826        pub fn whiteout_m3_M3IKCCD_get_searchUp(self_: *mut whiteout_M3IKCCD) -> f32;
26827        pub fn whiteout_m3_M3IKCCD_set_searchUp(self_: *mut whiteout_M3IKCCD, value: f32);
26828        pub fn whiteout_m3_M3IKCCD_get_searchDown(self_: *mut whiteout_M3IKCCD) -> f32;
26829        pub fn whiteout_m3_M3IKCCD_set_searchDown(self_: *mut whiteout_M3IKCCD, value: f32);
26830        // OneBoneSolver
26831        pub fn whiteout_m3_M3OneBoneSolver_new() -> *mut whiteout_M3OneBoneSolver;
26832        pub fn whiteout_m3_M3OneBoneSolver_delete(self_: *mut whiteout_M3OneBoneSolver);
26833        pub fn whiteout_m3_M3OneBoneSolver_get_dependents_count(
26834            self_: *mut whiteout_M3OneBoneSolver,
26835        ) -> usize;
26836        pub fn whiteout_m3_M3OneBoneSolver_resize_dependents(
26837            self_: *mut whiteout_M3OneBoneSolver,
26838            count: usize,
26839        );
26840        pub fn whiteout_m3_M3OneBoneSolver_get_dependents_data(
26841            self_: *mut whiteout_M3OneBoneSolver,
26842        ) -> *const u16;
26843        pub fn whiteout_m3_M3OneBoneSolver_assign_dependents(
26844            self_: *mut whiteout_M3OneBoneSolver,
26845            data: *const u16,
26846            count: usize,
26847        );
26848        pub fn whiteout_m3_M3OneBoneSolver_get_bone(self_: *mut whiteout_M3OneBoneSolver) -> u16;
26849        pub fn whiteout_m3_M3OneBoneSolver_set_bone(
26850            self_: *mut whiteout_M3OneBoneSolver,
26851            value: u16,
26852        );
26853        pub fn whiteout_m3_M3OneBoneSolver_get_boneFallback(
26854            self_: *mut whiteout_M3OneBoneSolver,
26855        ) -> u16;
26856        pub fn whiteout_m3_M3OneBoneSolver_set_boneFallback(
26857            self_: *mut whiteout_M3OneBoneSolver,
26858            value: u16,
26859        );
26860        pub fn whiteout_m3_M3OneBoneSolver_get_maxAngle(
26861            self_: *mut whiteout_M3OneBoneSolver,
26862        ) -> f32;
26863        pub fn whiteout_m3_M3OneBoneSolver_set_maxAngle(
26864            self_: *mut whiteout_M3OneBoneSolver,
26865            value: f32,
26866        );
26867        // ShadowBox
26868        pub fn whiteout_m3_M3ShadowBox_new() -> *mut whiteout_M3ShadowBox;
26869        pub fn whiteout_m3_M3ShadowBox_delete(self_: *mut whiteout_M3ShadowBox);
26870        // ViewVolume
26871        pub fn whiteout_m3_M3ViewVolume_new() -> *mut whiteout_M3ViewVolume;
26872        pub fn whiteout_m3_M3ViewVolume_delete(self_: *mut whiteout_M3ViewVolume);
26873        pub fn whiteout_m3_M3ViewVolume_get_nodeIndex(self_: *mut whiteout_M3ViewVolume) -> u32;
26874        pub fn whiteout_m3_M3ViewVolume_set_nodeIndex(
26875            self_: *mut whiteout_M3ViewVolume,
26876            value: u32,
26877        );
26878        pub fn whiteout_m3_M3ViewVolume_get_size(
26879            self_: *mut whiteout_M3ViewVolume,
26880        ) -> *mut whiteout_M3AnimRefVector3f;
26881        pub fn whiteout_m3_M3ViewVolume_set_size(
26882            self_: *mut whiteout_M3ViewVolume,
26883            value: *const whiteout_M3AnimRefVector3f,
26884        );
26885        // TrailingModel
26886        pub fn whiteout_m3_M3TrailingModel_new() -> *mut whiteout_M3TrailingModel;
26887        pub fn whiteout_m3_M3TrailingModel_delete(self_: *mut whiteout_M3TrailingModel);
26888        pub fn whiteout_m3_M3TrailingModel_get_vectors_count(
26889            self_: *mut whiteout_M3TrailingModel,
26890        ) -> usize;
26891        pub fn whiteout_m3_M3TrailingModel_resize_vectors(
26892            self_: *mut whiteout_M3TrailingModel,
26893            count: usize,
26894        );
26895        pub fn whiteout_m3_M3TrailingModel_get_vectors_data(
26896            self_: *mut whiteout_M3TrailingModel,
26897        ) -> *const f32;
26898        pub fn whiteout_m3_M3TrailingModel_assign_vectors(
26899            self_: *mut whiteout_M3TrailingModel,
26900            data: *const f32,
26901            count: usize,
26902        );
26903        pub fn whiteout_m3_M3TrailingModel_get_param0(self_: *mut whiteout_M3TrailingModel) -> f32;
26904        pub fn whiteout_m3_M3TrailingModel_set_param0(
26905            self_: *mut whiteout_M3TrailingModel,
26906            value: f32,
26907        );
26908        pub fn whiteout_m3_M3TrailingModel_get_param1(self_: *mut whiteout_M3TrailingModel) -> f32;
26909        pub fn whiteout_m3_M3TrailingModel_set_param1(
26910            self_: *mut whiteout_M3TrailingModel,
26911            value: f32,
26912        );
26913        pub fn whiteout_m3_M3TrailingModel_get_animFloat0(
26914            self_: *mut whiteout_M3TrailingModel,
26915        ) -> *mut whiteout_M3AnimRefF32;
26916        pub fn whiteout_m3_M3TrailingModel_set_animFloat0(
26917            self_: *mut whiteout_M3TrailingModel,
26918            value: *const whiteout_M3AnimRefF32,
26919        );
26920        pub fn whiteout_m3_M3TrailingModel_get_animFloat1(
26921            self_: *mut whiteout_M3TrailingModel,
26922        ) -> *mut whiteout_M3AnimRefF32;
26923        pub fn whiteout_m3_M3TrailingModel_set_animFloat1(
26924            self_: *mut whiteout_M3TrailingModel,
26925            value: *const whiteout_M3AnimRefF32,
26926        );
26927        pub fn whiteout_m3_M3TrailingModel_get_flag(self_: *mut whiteout_M3TrailingModel) -> u32;
26928        pub fn whiteout_m3_M3TrailingModel_set_flag(
26929            self_: *mut whiteout_M3TrailingModel,
26930            value: u32,
26931        );
26932        pub fn whiteout_m3_M3TrailingModel_get_reserved0(
26933            self_: *mut whiteout_M3TrailingModel,
26934        ) -> u32;
26935        pub fn whiteout_m3_M3TrailingModel_set_reserved0(
26936            self_: *mut whiteout_M3TrailingModel,
26937            value: u32,
26938        );
26939        pub fn whiteout_m3_M3TrailingModel_get_reserved1(
26940            self_: *mut whiteout_M3TrailingModel,
26941        ) -> u32;
26942        pub fn whiteout_m3_M3TrailingModel_set_reserved1(
26943            self_: *mut whiteout_M3TrailingModel,
26944            value: u32,
26945        );
26946        // Force
26947        pub fn whiteout_m3_M3Force_new() -> *mut whiteout_M3Force;
26948        pub fn whiteout_m3_M3Force_delete(self_: *mut whiteout_M3Force);
26949        pub fn whiteout_m3_M3Force_get_forceType(self_: *mut whiteout_M3Force) -> i32;
26950        pub fn whiteout_m3_M3Force_set_forceType(self_: *mut whiteout_M3Force, value: i32);
26951        pub fn whiteout_m3_M3Force_get_forceShape(self_: *mut whiteout_M3Force) -> i32;
26952        pub fn whiteout_m3_M3Force_set_forceShape(self_: *mut whiteout_M3Force, value: i32);
26953        pub fn whiteout_m3_M3Force_get_unknown(self_: *mut whiteout_M3Force) -> u32;
26954        pub fn whiteout_m3_M3Force_set_unknown(self_: *mut whiteout_M3Force, value: u32);
26955        pub fn whiteout_m3_M3Force_get_boneIndex(self_: *mut whiteout_M3Force) -> u32;
26956        pub fn whiteout_m3_M3Force_set_boneIndex(self_: *mut whiteout_M3Force, value: u32);
26957        pub fn whiteout_m3_M3Force_get_flags(self_: *mut whiteout_M3Force) -> i32;
26958        pub fn whiteout_m3_M3Force_set_flags(self_: *mut whiteout_M3Force, value: i32);
26959        pub fn whiteout_m3_M3Force_get_localChannels(self_: *mut whiteout_M3Force) -> u32;
26960        pub fn whiteout_m3_M3Force_set_localChannels(self_: *mut whiteout_M3Force, value: u32);
26961        pub fn whiteout_m3_M3Force_get_strength(
26962            self_: *mut whiteout_M3Force,
26963        ) -> *mut whiteout_M3AnimRefF32;
26964        pub fn whiteout_m3_M3Force_set_strength(
26965            self_: *mut whiteout_M3Force,
26966            value: *const whiteout_M3AnimRefF32,
26967        );
26968        pub fn whiteout_m3_M3Force_get_width(
26969            self_: *mut whiteout_M3Force,
26970        ) -> *mut whiteout_M3AnimRefF32;
26971        pub fn whiteout_m3_M3Force_set_width(
26972            self_: *mut whiteout_M3Force,
26973            value: *const whiteout_M3AnimRefF32,
26974        );
26975        pub fn whiteout_m3_M3Force_get_height(
26976            self_: *mut whiteout_M3Force,
26977        ) -> *mut whiteout_M3AnimRefF32;
26978        pub fn whiteout_m3_M3Force_set_height(
26979            self_: *mut whiteout_M3Force,
26980            value: *const whiteout_M3AnimRefF32,
26981        );
26982        pub fn whiteout_m3_M3Force_get_length(
26983            self_: *mut whiteout_M3Force,
26984        ) -> *mut whiteout_M3AnimRefF32;
26985        pub fn whiteout_m3_M3Force_set_length(
26986            self_: *mut whiteout_M3Force,
26987            value: *const whiteout_M3AnimRefF32,
26988        );
26989        // Warp
26990        pub fn whiteout_m3_M3Warp_new() -> *mut whiteout_M3Warp;
26991        pub fn whiteout_m3_M3Warp_delete(self_: *mut whiteout_M3Warp);
26992        pub fn whiteout_m3_M3Warp_get_warpType(self_: *mut whiteout_M3Warp) -> u32;
26993        pub fn whiteout_m3_M3Warp_set_warpType(self_: *mut whiteout_M3Warp, value: u32);
26994        pub fn whiteout_m3_M3Warp_get_boneIndex(self_: *mut whiteout_M3Warp) -> u32;
26995        pub fn whiteout_m3_M3Warp_set_boneIndex(self_: *mut whiteout_M3Warp, value: u32);
26996        pub fn whiteout_m3_M3Warp_get_unknown(self_: *mut whiteout_M3Warp) -> u32;
26997        pub fn whiteout_m3_M3Warp_set_unknown(self_: *mut whiteout_M3Warp, value: u32);
26998        pub fn whiteout_m3_M3Warp_get_radius(
26999            self_: *mut whiteout_M3Warp,
27000        ) -> *mut whiteout_M3AnimRefF32;
27001        pub fn whiteout_m3_M3Warp_set_radius(
27002            self_: *mut whiteout_M3Warp,
27003            value: *const whiteout_M3AnimRefF32,
27004        );
27005        pub fn whiteout_m3_M3Warp_get_height(
27006            self_: *mut whiteout_M3Warp,
27007        ) -> *mut whiteout_M3AnimRefF32;
27008        pub fn whiteout_m3_M3Warp_set_height(
27009            self_: *mut whiteout_M3Warp,
27010            value: *const whiteout_M3AnimRefF32,
27011        );
27012        pub fn whiteout_m3_M3Warp_get_strength(
27013            self_: *mut whiteout_M3Warp,
27014        ) -> *mut whiteout_M3AnimRefF32;
27015        pub fn whiteout_m3_M3Warp_set_strength(
27016            self_: *mut whiteout_M3Warp,
27017            value: *const whiteout_M3AnimRefF32,
27018        );
27019        pub fn whiteout_m3_M3Warp_get_angular(
27020            self_: *mut whiteout_M3Warp,
27021        ) -> *mut whiteout_M3AnimRefF32;
27022        pub fn whiteout_m3_M3Warp_set_angular(
27023            self_: *mut whiteout_M3Warp,
27024            value: *const whiteout_M3AnimRefF32,
27025        );
27026        pub fn whiteout_m3_M3Warp_get_axial(
27027            self_: *mut whiteout_M3Warp,
27028        ) -> *mut whiteout_M3AnimRefF32;
27029        pub fn whiteout_m3_M3Warp_set_axial(
27030            self_: *mut whiteout_M3Warp,
27031            value: *const whiteout_M3AnimRefF32,
27032        );
27033        pub fn whiteout_m3_M3Warp_get_radial(
27034            self_: *mut whiteout_M3Warp,
27035        ) -> *mut whiteout_M3AnimRefF32;
27036        pub fn whiteout_m3_M3Warp_set_radial(
27037            self_: *mut whiteout_M3Warp,
27038            value: *const whiteout_M3AnimRefF32,
27039        );
27040        // ConvexHullHalfEdge
27041        pub fn whiteout_m3_M3ConvexHullHalfEdge_new() -> *mut whiteout_M3ConvexHullHalfEdge;
27042        pub fn whiteout_m3_M3ConvexHullHalfEdge_delete(self_: *mut whiteout_M3ConvexHullHalfEdge);
27043        pub fn whiteout_m3_M3ConvexHullHalfEdge_get_type(
27044            self_: *mut whiteout_M3ConvexHullHalfEdge,
27045        ) -> u8;
27046        pub fn whiteout_m3_M3ConvexHullHalfEdge_set_type(
27047            self_: *mut whiteout_M3ConvexHullHalfEdge,
27048            value: u8,
27049        );
27050        pub fn whiteout_m3_M3ConvexHullHalfEdge_get_faceIndex(
27051            self_: *mut whiteout_M3ConvexHullHalfEdge,
27052        ) -> u8;
27053        pub fn whiteout_m3_M3ConvexHullHalfEdge_set_faceIndex(
27054            self_: *mut whiteout_M3ConvexHullHalfEdge,
27055            value: u8,
27056        );
27057        pub fn whiteout_m3_M3ConvexHullHalfEdge_get_vertexIndex(
27058            self_: *mut whiteout_M3ConvexHullHalfEdge,
27059        ) -> u8;
27060        pub fn whiteout_m3_M3ConvexHullHalfEdge_set_vertexIndex(
27061            self_: *mut whiteout_M3ConvexHullHalfEdge,
27062            value: u8,
27063        );
27064        pub fn whiteout_m3_M3ConvexHullHalfEdge_get_nextAroundVertex(
27065            self_: *mut whiteout_M3ConvexHullHalfEdge,
27066        ) -> u8;
27067        pub fn whiteout_m3_M3ConvexHullHalfEdge_set_nextAroundVertex(
27068            self_: *mut whiteout_M3ConvexHullHalfEdge,
27069            value: u8,
27070        );
27071        // PhysicsMeshBvhNode
27072        pub fn whiteout_m3_M3PhysicsMeshBvhNode_new() -> *mut whiteout_M3PhysicsMeshBvhNode;
27073        pub fn whiteout_m3_M3PhysicsMeshBvhNode_delete(self_: *mut whiteout_M3PhysicsMeshBvhNode);
27074        // PhysicsMeshTriangle
27075        pub fn whiteout_m3_M3PhysicsMeshTriangle_new() -> *mut whiteout_M3PhysicsMeshTriangle;
27076        pub fn whiteout_m3_M3PhysicsMeshTriangle_delete(self_: *mut whiteout_M3PhysicsMeshTriangle);
27077        pub fn whiteout_m3_M3PhysicsMeshTriangle_get_vertexIndex0(
27078            self_: *mut whiteout_M3PhysicsMeshTriangle,
27079        ) -> u32;
27080        pub fn whiteout_m3_M3PhysicsMeshTriangle_set_vertexIndex0(
27081            self_: *mut whiteout_M3PhysicsMeshTriangle,
27082            value: u32,
27083        );
27084        pub fn whiteout_m3_M3PhysicsMeshTriangle_get_vertexIndex1(
27085            self_: *mut whiteout_M3PhysicsMeshTriangle,
27086        ) -> u32;
27087        pub fn whiteout_m3_M3PhysicsMeshTriangle_set_vertexIndex1(
27088            self_: *mut whiteout_M3PhysicsMeshTriangle,
27089            value: u32,
27090        );
27091        pub fn whiteout_m3_M3PhysicsMeshTriangle_get_vertexIndex2(
27092            self_: *mut whiteout_M3PhysicsMeshTriangle,
27093        ) -> u32;
27094        pub fn whiteout_m3_M3PhysicsMeshTriangle_set_vertexIndex2(
27095            self_: *mut whiteout_M3PhysicsMeshTriangle,
27096            value: u32,
27097        );
27098        pub fn whiteout_m3_M3PhysicsMeshTriangle_get_edgeIndex0(
27099            self_: *mut whiteout_M3PhysicsMeshTriangle,
27100        ) -> u32;
27101        pub fn whiteout_m3_M3PhysicsMeshTriangle_set_edgeIndex0(
27102            self_: *mut whiteout_M3PhysicsMeshTriangle,
27103            value: u32,
27104        );
27105        pub fn whiteout_m3_M3PhysicsMeshTriangle_get_edgeIndex1(
27106            self_: *mut whiteout_M3PhysicsMeshTriangle,
27107        ) -> u32;
27108        pub fn whiteout_m3_M3PhysicsMeshTriangle_set_edgeIndex1(
27109            self_: *mut whiteout_M3PhysicsMeshTriangle,
27110            value: u32,
27111        );
27112        pub fn whiteout_m3_M3PhysicsMeshTriangle_get_edgeIndex2(
27113            self_: *mut whiteout_M3PhysicsMeshTriangle,
27114        ) -> u32;
27115        pub fn whiteout_m3_M3PhysicsMeshTriangle_set_edgeIndex2(
27116            self_: *mut whiteout_M3PhysicsMeshTriangle,
27117            value: u32,
27118        );
27119        pub fn whiteout_m3_M3PhysicsMeshTriangle_get_reserved(
27120            self_: *mut whiteout_M3PhysicsMeshTriangle,
27121        ) -> u16;
27122        pub fn whiteout_m3_M3PhysicsMeshTriangle_set_reserved(
27123            self_: *mut whiteout_M3PhysicsMeshTriangle,
27124            value: u16,
27125        );
27126        pub fn whiteout_m3_M3PhysicsMeshTriangle_get_flags(
27127            self_: *mut whiteout_M3PhysicsMeshTriangle,
27128        ) -> u16;
27129        pub fn whiteout_m3_M3PhysicsMeshTriangle_set_flags(
27130            self_: *mut whiteout_M3PhysicsMeshTriangle,
27131            value: u16,
27132        );
27133        // PhysicsMeshEdge
27134        pub fn whiteout_m3_M3PhysicsMeshEdge_new() -> *mut whiteout_M3PhysicsMeshEdge;
27135        pub fn whiteout_m3_M3PhysicsMeshEdge_delete(self_: *mut whiteout_M3PhysicsMeshEdge);
27136        pub fn whiteout_m3_M3PhysicsMeshEdge_get_edgeType(
27137            self_: *mut whiteout_M3PhysicsMeshEdge,
27138        ) -> u32;
27139        pub fn whiteout_m3_M3PhysicsMeshEdge_set_edgeType(
27140            self_: *mut whiteout_M3PhysicsMeshEdge,
27141            value: u32,
27142        );
27143        pub fn whiteout_m3_M3PhysicsMeshEdge_get_vertexA(
27144            self_: *mut whiteout_M3PhysicsMeshEdge,
27145        ) -> u32;
27146        pub fn whiteout_m3_M3PhysicsMeshEdge_set_vertexA(
27147            self_: *mut whiteout_M3PhysicsMeshEdge,
27148            value: u32,
27149        );
27150        pub fn whiteout_m3_M3PhysicsMeshEdge_get_vertexB(
27151            self_: *mut whiteout_M3PhysicsMeshEdge,
27152        ) -> u32;
27153        pub fn whiteout_m3_M3PhysicsMeshEdge_set_vertexB(
27154            self_: *mut whiteout_M3PhysicsMeshEdge,
27155            value: u32,
27156        );
27157        pub fn whiteout_m3_M3PhysicsMeshEdge_get_faceA(
27158            self_: *mut whiteout_M3PhysicsMeshEdge,
27159        ) -> u32;
27160        pub fn whiteout_m3_M3PhysicsMeshEdge_set_faceA(
27161            self_: *mut whiteout_M3PhysicsMeshEdge,
27162            value: u32,
27163        );
27164        pub fn whiteout_m3_M3PhysicsMeshEdge_get_faceB(
27165            self_: *mut whiteout_M3PhysicsMeshEdge,
27166        ) -> u32;
27167        pub fn whiteout_m3_M3PhysicsMeshEdge_set_faceB(
27168            self_: *mut whiteout_M3PhysicsMeshEdge,
27169            value: u32,
27170        );
27171        // PhysicsShape
27172        pub fn whiteout_m3_M3PhysicsShape_new() -> *mut whiteout_M3PhysicsShape;
27173        pub fn whiteout_m3_M3PhysicsShape_delete(self_: *mut whiteout_M3PhysicsShape);
27174        pub fn whiteout_m3_M3PhysicsShape_get_collisionMargin(
27175            self_: *mut whiteout_M3PhysicsShape,
27176        ) -> f32;
27177        pub fn whiteout_m3_M3PhysicsShape_set_collisionMargin(
27178            self_: *mut whiteout_M3PhysicsShape,
27179            value: f32,
27180        );
27181        pub fn whiteout_m3_M3PhysicsShape_get_shapeType(self_: *mut whiteout_M3PhysicsShape)
27182            -> i32;
27183        pub fn whiteout_m3_M3PhysicsShape_set_shapeType(
27184            self_: *mut whiteout_M3PhysicsShape,
27185            value: i32,
27186        );
27187        pub fn whiteout_m3_M3PhysicsShape_get_oldSizes(
27188            self_: *mut whiteout_M3PhysicsShape,
27189        ) -> *mut core::ffi::c_void;
27190        pub fn whiteout_m3_M3PhysicsShape_set_oldSizes(
27191            self_: *mut whiteout_M3PhysicsShape,
27192            value: *const core::ffi::c_void,
27193        );
27194        pub fn whiteout_m3_M3PhysicsShape_get_shapeDimensions(
27195            self_: *mut whiteout_M3PhysicsShape,
27196        ) -> *mut core::ffi::c_void;
27197        pub fn whiteout_m3_M3PhysicsShape_set_shapeDimensions(
27198            self_: *mut whiteout_M3PhysicsShape,
27199            value: *const core::ffi::c_void,
27200        );
27201        pub fn whiteout_m3_M3PhysicsShape_get_hullFaceNormals_count(
27202            self_: *mut whiteout_M3PhysicsShape,
27203        ) -> usize;
27204        pub fn whiteout_m3_M3PhysicsShape_resize_hullFaceNormals(
27205            self_: *mut whiteout_M3PhysicsShape,
27206            count: usize,
27207        );
27208        pub fn whiteout_m3_M3PhysicsShape_get_hullFaceNormals_data(
27209            self_: *mut whiteout_M3PhysicsShape,
27210        ) -> *const f32;
27211        pub fn whiteout_m3_M3PhysicsShape_assign_hullFaceNormals(
27212            self_: *mut whiteout_M3PhysicsShape,
27213            data: *const f32,
27214            count: usize,
27215        );
27216        pub fn whiteout_m3_M3PhysicsShape_get_hullVertexPositions_count(
27217            self_: *mut whiteout_M3PhysicsShape,
27218        ) -> usize;
27219        pub fn whiteout_m3_M3PhysicsShape_resize_hullVertexPositions(
27220            self_: *mut whiteout_M3PhysicsShape,
27221            count: usize,
27222        );
27223        pub fn whiteout_m3_M3PhysicsShape_get_hullVertexPositions_data(
27224            self_: *mut whiteout_M3PhysicsShape,
27225        ) -> *const f32;
27226        pub fn whiteout_m3_M3PhysicsShape_assign_hullVertexPositions(
27227            self_: *mut whiteout_M3PhysicsShape,
27228            data: *const f32,
27229            count: usize,
27230        );
27231        pub fn whiteout_m3_M3PhysicsShape_get_hullHalfEdges_count(
27232            self_: *mut whiteout_M3PhysicsShape,
27233        ) -> usize;
27234        pub fn whiteout_m3_M3PhysicsShape_resize_hullHalfEdges(
27235            self_: *mut whiteout_M3PhysicsShape,
27236            count: usize,
27237        );
27238        pub fn whiteout_m3_M3PhysicsShape_get_hullHalfEdges_at(
27239            self_: *mut whiteout_M3PhysicsShape,
27240            index: usize,
27241        ) -> *mut whiteout_M3ConvexHullHalfEdge;
27242        pub fn whiteout_m3_M3PhysicsShape_get_hullVertexFaceIndices_count(
27243            self_: *mut whiteout_M3PhysicsShape,
27244        ) -> usize;
27245        pub fn whiteout_m3_M3PhysicsShape_resize_hullVertexFaceIndices(
27246            self_: *mut whiteout_M3PhysicsShape,
27247            count: usize,
27248        );
27249        pub fn whiteout_m3_M3PhysicsShape_get_hullVertexFaceIndices_data(
27250            self_: *mut whiteout_M3PhysicsShape,
27251        ) -> *const u8;
27252        pub fn whiteout_m3_M3PhysicsShape_assign_hullVertexFaceIndices(
27253            self_: *mut whiteout_M3PhysicsShape,
27254            data: *const u8,
27255            count: usize,
27256        );
27257        pub fn whiteout_m3_M3PhysicsShape_get_hullCenter(
27258            self_: *mut whiteout_M3PhysicsShape,
27259        ) -> *mut core::ffi::c_void;
27260        pub fn whiteout_m3_M3PhysicsShape_set_hullCenter(
27261            self_: *mut whiteout_M3PhysicsShape,
27262            value: *const core::ffi::c_void,
27263        );
27264        pub fn whiteout_m3_M3PhysicsShape_get_hullFaceNormalCount(
27265            self_: *mut whiteout_M3PhysicsShape,
27266        ) -> u32;
27267        pub fn whiteout_m3_M3PhysicsShape_set_hullFaceNormalCount(
27268            self_: *mut whiteout_M3PhysicsShape,
27269            value: u32,
27270        );
27271        pub fn whiteout_m3_M3PhysicsShape_get_hullVertexCount(
27272            self_: *mut whiteout_M3PhysicsShape,
27273        ) -> u32;
27274        pub fn whiteout_m3_M3PhysicsShape_set_hullVertexCount(
27275            self_: *mut whiteout_M3PhysicsShape,
27276            value: u32,
27277        );
27278        pub fn whiteout_m3_M3PhysicsShape_get_hullHalfEdgeCount(
27279            self_: *mut whiteout_M3PhysicsShape,
27280        ) -> u32;
27281        pub fn whiteout_m3_M3PhysicsShape_set_hullHalfEdgeCount(
27282            self_: *mut whiteout_M3PhysicsShape,
27283            value: u32,
27284        );
27285        pub fn whiteout_m3_M3PhysicsShape_get_hullUnknown0(
27286            self_: *mut whiteout_M3PhysicsShape,
27287        ) -> f32;
27288        pub fn whiteout_m3_M3PhysicsShape_set_hullUnknown0(
27289            self_: *mut whiteout_M3PhysicsShape,
27290            value: f32,
27291        );
27292        pub fn whiteout_m3_M3PhysicsShape_get_hullUnknown1(
27293            self_: *mut whiteout_M3PhysicsShape,
27294        ) -> f32;
27295        pub fn whiteout_m3_M3PhysicsShape_set_hullUnknown1(
27296            self_: *mut whiteout_M3PhysicsShape,
27297            value: f32,
27298        );
27299        pub fn whiteout_m3_M3PhysicsShape_get_meshBvhNodes_count(
27300            self_: *mut whiteout_M3PhysicsShape,
27301        ) -> usize;
27302        pub fn whiteout_m3_M3PhysicsShape_resize_meshBvhNodes(
27303            self_: *mut whiteout_M3PhysicsShape,
27304            count: usize,
27305        );
27306        pub fn whiteout_m3_M3PhysicsShape_get_meshBvhNodes_at(
27307            self_: *mut whiteout_M3PhysicsShape,
27308            index: usize,
27309        ) -> *mut whiteout_M3PhysicsMeshBvhNode;
27310        pub fn whiteout_m3_M3PhysicsShape_get_meshVertexPositions_count(
27311            self_: *mut whiteout_M3PhysicsShape,
27312        ) -> usize;
27313        pub fn whiteout_m3_M3PhysicsShape_resize_meshVertexPositions(
27314            self_: *mut whiteout_M3PhysicsShape,
27315            count: usize,
27316        );
27317        pub fn whiteout_m3_M3PhysicsShape_get_meshVertexPositions_data(
27318            self_: *mut whiteout_M3PhysicsShape,
27319        ) -> *const f32;
27320        pub fn whiteout_m3_M3PhysicsShape_assign_meshVertexPositions(
27321            self_: *mut whiteout_M3PhysicsShape,
27322            data: *const f32,
27323            count: usize,
27324        );
27325        pub fn whiteout_m3_M3PhysicsShape_get_meshBoundsCenter(
27326            self_: *mut whiteout_M3PhysicsShape,
27327        ) -> *mut core::ffi::c_void;
27328        pub fn whiteout_m3_M3PhysicsShape_set_meshBoundsCenter(
27329            self_: *mut whiteout_M3PhysicsShape,
27330            value: *const core::ffi::c_void,
27331        );
27332        pub fn whiteout_m3_M3PhysicsShape_get_meshBoundsExtent(
27333            self_: *mut whiteout_M3PhysicsShape,
27334        ) -> *mut core::ffi::c_void;
27335        pub fn whiteout_m3_M3PhysicsShape_set_meshBoundsExtent(
27336            self_: *mut whiteout_M3PhysicsShape,
27337            value: *const core::ffi::c_void,
27338        );
27339        pub fn whiteout_m3_M3PhysicsShape_get_meshTolerance(
27340            self_: *mut whiteout_M3PhysicsShape,
27341        ) -> *mut core::ffi::c_void;
27342        pub fn whiteout_m3_M3PhysicsShape_set_meshTolerance(
27343            self_: *mut whiteout_M3PhysicsShape,
27344            value: *const core::ffi::c_void,
27345        );
27346        pub fn whiteout_m3_M3PhysicsShape_get_meshNormalCount(
27347            self_: *mut whiteout_M3PhysicsShape,
27348        ) -> u32;
27349        pub fn whiteout_m3_M3PhysicsShape_set_meshNormalCount(
27350            self_: *mut whiteout_M3PhysicsShape,
27351            value: u32,
27352        );
27353        pub fn whiteout_m3_M3PhysicsShape_get_meshVertexCount(
27354            self_: *mut whiteout_M3PhysicsShape,
27355        ) -> u32;
27356        pub fn whiteout_m3_M3PhysicsShape_set_meshVertexCount(
27357            self_: *mut whiteout_M3PhysicsShape,
27358            value: u32,
27359        );
27360        pub fn whiteout_m3_M3PhysicsShape_get_meshFaceIndex16Count(
27361            self_: *mut whiteout_M3PhysicsShape,
27362        ) -> u32;
27363        pub fn whiteout_m3_M3PhysicsShape_set_meshFaceIndex16Count(
27364            self_: *mut whiteout_M3PhysicsShape,
27365            value: u32,
27366        );
27367        pub fn whiteout_m3_M3PhysicsShape_get_meshFaceIndex32Count(
27368            self_: *mut whiteout_M3PhysicsShape,
27369        ) -> u32;
27370        pub fn whiteout_m3_M3PhysicsShape_set_meshFaceIndex32Count(
27371            self_: *mut whiteout_M3PhysicsShape,
27372            value: u32,
27373        );
27374        pub fn whiteout_m3_M3PhysicsShape_get_meshUnknown1(
27375            self_: *mut whiteout_M3PhysicsShape,
27376        ) -> u32;
27377        pub fn whiteout_m3_M3PhysicsShape_set_meshUnknown1(
27378            self_: *mut whiteout_M3PhysicsShape,
27379            value: u32,
27380        );
27381        pub fn whiteout_m3_M3PhysicsShape_get_meshReserved(
27382            self_: *mut whiteout_M3PhysicsShape,
27383        ) -> u32;
27384        pub fn whiteout_m3_M3PhysicsShape_set_meshReserved(
27385            self_: *mut whiteout_M3PhysicsShape,
27386            value: u32,
27387        );
27388        pub fn whiteout_m3_M3PhysicsShape_get_meshTreeDepth(
27389            self_: *mut whiteout_M3PhysicsShape,
27390        ) -> u32;
27391        pub fn whiteout_m3_M3PhysicsShape_set_meshTreeDepth(
27392            self_: *mut whiteout_M3PhysicsShape,
27393            value: u32,
27394        );
27395        pub fn whiteout_m3_M3PhysicsShape_get_meshCollisionMargin(
27396            self_: *mut whiteout_M3PhysicsShape,
27397        ) -> f32;
27398        pub fn whiteout_m3_M3PhysicsShape_set_meshCollisionMargin(
27399            self_: *mut whiteout_M3PhysicsShape,
27400            value: f32,
27401        );
27402        // RigidBody
27403        pub fn whiteout_m3_M3RigidBody_new() -> *mut whiteout_M3RigidBody;
27404        pub fn whiteout_m3_M3RigidBody_delete(self_: *mut whiteout_M3RigidBody);
27405        pub fn whiteout_m3_M3RigidBody_get_simulationType(self_: *mut whiteout_M3RigidBody) -> u16;
27406        pub fn whiteout_m3_M3RigidBody_set_simulationType(
27407            self_: *mut whiteout_M3RigidBody,
27408            value: u16,
27409        );
27410        pub fn whiteout_m3_M3RigidBody_get_parentBoneIndex(self_: *mut whiteout_M3RigidBody)
27411            -> u16;
27412        pub fn whiteout_m3_M3RigidBody_set_parentBoneIndex(
27413            self_: *mut whiteout_M3RigidBody,
27414            value: u16,
27415        );
27416        pub fn whiteout_m3_M3RigidBody_get_physicsType(self_: *mut whiteout_M3RigidBody) -> u32;
27417        pub fn whiteout_m3_M3RigidBody_set_physicsType(
27418            self_: *mut whiteout_M3RigidBody,
27419            value: u32,
27420        );
27421        pub fn whiteout_m3_M3RigidBody_get_density(self_: *mut whiteout_M3RigidBody) -> f32;
27422        pub fn whiteout_m3_M3RigidBody_set_density(self_: *mut whiteout_M3RigidBody, value: f32);
27423        pub fn whiteout_m3_M3RigidBody_get_friction(self_: *mut whiteout_M3RigidBody) -> f32;
27424        pub fn whiteout_m3_M3RigidBody_set_friction(self_: *mut whiteout_M3RigidBody, value: f32);
27425        pub fn whiteout_m3_M3RigidBody_get_restitution(self_: *mut whiteout_M3RigidBody) -> f32;
27426        pub fn whiteout_m3_M3RigidBody_set_restitution(
27427            self_: *mut whiteout_M3RigidBody,
27428            value: f32,
27429        );
27430        pub fn whiteout_m3_M3RigidBody_get_linearDamping(self_: *mut whiteout_M3RigidBody) -> f32;
27431        pub fn whiteout_m3_M3RigidBody_set_linearDamping(
27432            self_: *mut whiteout_M3RigidBody,
27433            value: f32,
27434        );
27435        pub fn whiteout_m3_M3RigidBody_get_angularDamping(self_: *mut whiteout_M3RigidBody) -> f32;
27436        pub fn whiteout_m3_M3RigidBody_set_angularDamping(
27437            self_: *mut whiteout_M3RigidBody,
27438            value: f32,
27439        );
27440        pub fn whiteout_m3_M3RigidBody_get_gravityScale(self_: *mut whiteout_M3RigidBody) -> f32;
27441        pub fn whiteout_m3_M3RigidBody_set_gravityScale(
27442            self_: *mut whiteout_M3RigidBody,
27443            value: f32,
27444        );
27445        pub fn whiteout_m3_M3RigidBody_get_dynamicState(
27446            self_: *mut whiteout_M3RigidBody,
27447        ) -> *mut whiteout_M3AnimRefU32;
27448        pub fn whiteout_m3_M3RigidBody_set_dynamicState(
27449            self_: *mut whiteout_M3RigidBody,
27450            value: *const whiteout_M3AnimRefU32,
27451        );
27452        pub fn whiteout_m3_M3RigidBody_get_dynamicBlendOut(self_: *mut whiteout_M3RigidBody)
27453            -> f32;
27454        pub fn whiteout_m3_M3RigidBody_set_dynamicBlendOut(
27455            self_: *mut whiteout_M3RigidBody,
27456            value: f32,
27457        );
27458        pub fn whiteout_m3_M3RigidBody_get_rigidBodyShape_count(
27459            self_: *mut whiteout_M3RigidBody,
27460        ) -> usize;
27461        pub fn whiteout_m3_M3RigidBody_resize_rigidBodyShape(
27462            self_: *mut whiteout_M3RigidBody,
27463            count: usize,
27464        );
27465        pub fn whiteout_m3_M3RigidBody_get_rigidBodyShape_at(
27466            self_: *mut whiteout_M3RigidBody,
27467            index: usize,
27468        ) -> *mut whiteout_M3PhysicsShape;
27469        pub fn whiteout_m3_M3RigidBody_get_flags(self_: *mut whiteout_M3RigidBody) -> i32;
27470        pub fn whiteout_m3_M3RigidBody_set_flags(self_: *mut whiteout_M3RigidBody, value: i32);
27471        pub fn whiteout_m3_M3RigidBody_get_localForces(self_: *mut whiteout_M3RigidBody) -> u16;
27472        pub fn whiteout_m3_M3RigidBody_set_localForces(
27473            self_: *mut whiteout_M3RigidBody,
27474            value: u16,
27475        );
27476        pub fn whiteout_m3_M3RigidBody_get_worldForces(self_: *mut whiteout_M3RigidBody) -> u16;
27477        pub fn whiteout_m3_M3RigidBody_set_worldForces(
27478            self_: *mut whiteout_M3RigidBody,
27479            value: u16,
27480        );
27481        pub fn whiteout_m3_M3RigidBody_get_priority(self_: *mut whiteout_M3RigidBody) -> u32;
27482        pub fn whiteout_m3_M3RigidBody_set_priority(self_: *mut whiteout_M3RigidBody, value: u32);
27483        // PhysicsJoint
27484        pub fn whiteout_m3_M3PhysicsJoint_new() -> *mut whiteout_M3PhysicsJoint;
27485        pub fn whiteout_m3_M3PhysicsJoint_delete(self_: *mut whiteout_M3PhysicsJoint);
27486        pub fn whiteout_m3_M3PhysicsJoint_get_jointType(self_: *mut whiteout_M3PhysicsJoint)
27487            -> u32;
27488        pub fn whiteout_m3_M3PhysicsJoint_set_jointType(
27489            self_: *mut whiteout_M3PhysicsJoint,
27490            value: u32,
27491        );
27492        pub fn whiteout_m3_M3PhysicsJoint_get_boneIndex1(
27493            self_: *mut whiteout_M3PhysicsJoint,
27494        ) -> u32;
27495        pub fn whiteout_m3_M3PhysicsJoint_set_boneIndex1(
27496            self_: *mut whiteout_M3PhysicsJoint,
27497            value: u32,
27498        );
27499        pub fn whiteout_m3_M3PhysicsJoint_get_boneIndex2(
27500            self_: *mut whiteout_M3PhysicsJoint,
27501        ) -> u32;
27502        pub fn whiteout_m3_M3PhysicsJoint_set_boneIndex2(
27503            self_: *mut whiteout_M3PhysicsJoint,
27504            value: u32,
27505        );
27506        pub fn whiteout_m3_M3PhysicsJoint_get_enableLimits(
27507            self_: *mut whiteout_M3PhysicsJoint,
27508        ) -> u32;
27509        pub fn whiteout_m3_M3PhysicsJoint_set_enableLimits(
27510            self_: *mut whiteout_M3PhysicsJoint,
27511            value: u32,
27512        );
27513        pub fn whiteout_m3_M3PhysicsJoint_get_limitMin(self_: *mut whiteout_M3PhysicsJoint) -> f32;
27514        pub fn whiteout_m3_M3PhysicsJoint_set_limitMin(
27515            self_: *mut whiteout_M3PhysicsJoint,
27516            value: f32,
27517        );
27518        pub fn whiteout_m3_M3PhysicsJoint_get_limitMax(self_: *mut whiteout_M3PhysicsJoint) -> f32;
27519        pub fn whiteout_m3_M3PhysicsJoint_set_limitMax(
27520            self_: *mut whiteout_M3PhysicsJoint,
27521            value: f32,
27522        );
27523        pub fn whiteout_m3_M3PhysicsJoint_get_coneAngle(self_: *mut whiteout_M3PhysicsJoint)
27524            -> f32;
27525        pub fn whiteout_m3_M3PhysicsJoint_set_coneAngle(
27526            self_: *mut whiteout_M3PhysicsJoint,
27527            value: f32,
27528        );
27529        pub fn whiteout_m3_M3PhysicsJoint_get_enableFriction(
27530            self_: *mut whiteout_M3PhysicsJoint,
27531        ) -> u32;
27532        pub fn whiteout_m3_M3PhysicsJoint_set_enableFriction(
27533            self_: *mut whiteout_M3PhysicsJoint,
27534            value: u32,
27535        );
27536        pub fn whiteout_m3_M3PhysicsJoint_get_friction(self_: *mut whiteout_M3PhysicsJoint) -> f32;
27537        pub fn whiteout_m3_M3PhysicsJoint_set_friction(
27538            self_: *mut whiteout_M3PhysicsJoint,
27539            value: f32,
27540        );
27541        pub fn whiteout_m3_M3PhysicsJoint_get_dampingRatio(
27542            self_: *mut whiteout_M3PhysicsJoint,
27543        ) -> f32;
27544        pub fn whiteout_m3_M3PhysicsJoint_set_dampingRatio(
27545            self_: *mut whiteout_M3PhysicsJoint,
27546            value: f32,
27547        );
27548        pub fn whiteout_m3_M3PhysicsJoint_get_angularFrequency(
27549            self_: *mut whiteout_M3PhysicsJoint,
27550        ) -> f32;
27551        pub fn whiteout_m3_M3PhysicsJoint_set_angularFrequency(
27552            self_: *mut whiteout_M3PhysicsJoint,
27553            value: f32,
27554        );
27555        pub fn whiteout_m3_M3PhysicsJoint_get_breakThreshold(
27556            self_: *mut whiteout_M3PhysicsJoint,
27557        ) -> f32;
27558        pub fn whiteout_m3_M3PhysicsJoint_set_breakThreshold(
27559            self_: *mut whiteout_M3PhysicsJoint,
27560            value: f32,
27561        );
27562        pub fn whiteout_m3_M3PhysicsJoint_get_enableShape(
27563            self_: *mut whiteout_M3PhysicsJoint,
27564        ) -> u8;
27565        pub fn whiteout_m3_M3PhysicsJoint_set_enableShape(
27566            self_: *mut whiteout_M3PhysicsJoint,
27567            value: u8,
27568        );
27569        // PhysicsConstraint
27570        pub fn whiteout_m3_M3PhysicsConstraint_new() -> *mut whiteout_M3PhysicsConstraint;
27571        pub fn whiteout_m3_M3PhysicsConstraint_delete(self_: *mut whiteout_M3PhysicsConstraint);
27572        pub fn whiteout_m3_M3PhysicsConstraint_get_dependents_count(
27573            self_: *mut whiteout_M3PhysicsConstraint,
27574        ) -> usize;
27575        pub fn whiteout_m3_M3PhysicsConstraint_resize_dependents(
27576            self_: *mut whiteout_M3PhysicsConstraint,
27577            count: usize,
27578        );
27579        pub fn whiteout_m3_M3PhysicsConstraint_get_dependents_data(
27580            self_: *mut whiteout_M3PhysicsConstraint,
27581        ) -> *const u16;
27582        pub fn whiteout_m3_M3PhysicsConstraint_assign_dependents(
27583            self_: *mut whiteout_M3PhysicsConstraint,
27584            data: *const u16,
27585            count: usize,
27586        );
27587        pub fn whiteout_m3_M3PhysicsConstraint_get_rigidBody1(
27588            self_: *mut whiteout_M3PhysicsConstraint,
27589        ) -> u16;
27590        pub fn whiteout_m3_M3PhysicsConstraint_set_rigidBody1(
27591            self_: *mut whiteout_M3PhysicsConstraint,
27592            value: u16,
27593        );
27594        pub fn whiteout_m3_M3PhysicsConstraint_get_rigidBody2(
27595            self_: *mut whiteout_M3PhysicsConstraint,
27596        ) -> u16;
27597        pub fn whiteout_m3_M3PhysicsConstraint_set_rigidBody2(
27598            self_: *mut whiteout_M3PhysicsConstraint,
27599            value: u16,
27600        );
27601        pub fn whiteout_m3_M3PhysicsConstraint_get_breakForce(
27602            self_: *mut whiteout_M3PhysicsConstraint,
27603        ) -> f32;
27604        pub fn whiteout_m3_M3PhysicsConstraint_set_breakForce(
27605            self_: *mut whiteout_M3PhysicsConstraint,
27606            value: f32,
27607        );
27608        // ClothCollider
27609        pub fn whiteout_m3_M3ClothCollider_new() -> *mut whiteout_M3ClothCollider;
27610        pub fn whiteout_m3_M3ClothCollider_delete(self_: *mut whiteout_M3ClothCollider);
27611        pub fn whiteout_m3_M3ClothCollider_get_radius(self_: *mut whiteout_M3ClothCollider) -> f32;
27612        pub fn whiteout_m3_M3ClothCollider_set_radius(
27613            self_: *mut whiteout_M3ClothCollider,
27614            value: f32,
27615        );
27616        pub fn whiteout_m3_M3ClothCollider_get_height(self_: *mut whiteout_M3ClothCollider) -> f32;
27617        pub fn whiteout_m3_M3ClothCollider_set_height(
27618            self_: *mut whiteout_M3ClothCollider,
27619            value: f32,
27620        );
27621        pub fn whiteout_m3_M3ClothCollider_get_padding(self_: *mut whiteout_M3ClothCollider)
27622            -> u32;
27623        pub fn whiteout_m3_M3ClothCollider_set_padding(
27624            self_: *mut whiteout_M3ClothCollider,
27625            value: u32,
27626        );
27627        // ClothProxy
27628        pub fn whiteout_m3_M3ClothProxy_new() -> *mut whiteout_M3ClothProxy;
27629        pub fn whiteout_m3_M3ClothProxy_delete(self_: *mut whiteout_M3ClothProxy);
27630        pub fn whiteout_m3_M3ClothProxy_get_proxyIndex(self_: *mut whiteout_M3ClothProxy) -> u32;
27631        pub fn whiteout_m3_M3ClothProxy_set_proxyIndex(
27632            self_: *mut whiteout_M3ClothProxy,
27633            value: u32,
27634        );
27635        pub fn whiteout_m3_M3ClothProxy_get_clothIndex(self_: *mut whiteout_M3ClothProxy) -> u32;
27636        pub fn whiteout_m3_M3ClothProxy_set_clothIndex(
27637            self_: *mut whiteout_M3ClothProxy,
27638            value: u32,
27639        );
27640        pub fn whiteout_m3_M3ClothProxy_get_proxyVertices_count(
27641            self_: *mut whiteout_M3ClothProxy,
27642        ) -> usize;
27643        pub fn whiteout_m3_M3ClothProxy_resize_proxyVertices(
27644            self_: *mut whiteout_M3ClothProxy,
27645            count: usize,
27646        );
27647        pub fn whiteout_m3_M3ClothProxy_get_proxyVertices_data(
27648            self_: *mut whiteout_M3ClothProxy,
27649        ) -> *const u64;
27650        pub fn whiteout_m3_M3ClothProxy_assign_proxyVertices(
27651            self_: *mut whiteout_M3ClothProxy,
27652            data: *const u64,
27653            count: usize,
27654        );
27655        pub fn whiteout_m3_M3ClothProxy_get_proxyWeights_count(
27656            self_: *mut whiteout_M3ClothProxy,
27657        ) -> usize;
27658        pub fn whiteout_m3_M3ClothProxy_resize_proxyWeights(
27659            self_: *mut whiteout_M3ClothProxy,
27660            count: usize,
27661        );
27662        pub fn whiteout_m3_M3ClothProxy_get_proxyWeights_data(
27663            self_: *mut whiteout_M3ClothProxy,
27664        ) -> *const u32;
27665        pub fn whiteout_m3_M3ClothProxy_assign_proxyWeights(
27666            self_: *mut whiteout_M3ClothProxy,
27667            data: *const u32,
27668            count: usize,
27669        );
27670        // ClothPhysics
27671        pub fn whiteout_m3_M3ClothPhysics_new() -> *mut whiteout_M3ClothPhysics;
27672        pub fn whiteout_m3_M3ClothPhysics_delete(self_: *mut whiteout_M3ClothPhysics);
27673        pub fn whiteout_m3_M3ClothPhysics_get_clothMeshCount(
27674            self_: *mut whiteout_M3ClothPhysics,
27675        ) -> u32;
27676        pub fn whiteout_m3_M3ClothPhysics_set_clothMeshCount(
27677            self_: *mut whiteout_M3ClothPhysics,
27678            value: u32,
27679        );
27680        pub fn whiteout_m3_M3ClothPhysics_get_skinBoneCount(
27681            self_: *mut whiteout_M3ClothPhysics,
27682        ) -> u32;
27683        pub fn whiteout_m3_M3ClothPhysics_set_skinBoneCount(
27684            self_: *mut whiteout_M3ClothPhysics,
27685            value: u32,
27686        );
27687        pub fn whiteout_m3_M3ClothPhysics_get_skinBones_count(
27688            self_: *mut whiteout_M3ClothPhysics,
27689        ) -> usize;
27690        pub fn whiteout_m3_M3ClothPhysics_resize_skinBones(
27691            self_: *mut whiteout_M3ClothPhysics,
27692            count: usize,
27693        );
27694        pub fn whiteout_m3_M3ClothPhysics_get_skinBones_data(
27695            self_: *mut whiteout_M3ClothPhysics,
27696        ) -> *const u16;
27697        pub fn whiteout_m3_M3ClothPhysics_assign_skinBones(
27698            self_: *mut whiteout_M3ClothPhysics,
27699            data: *const u16,
27700            count: usize,
27701        );
27702        pub fn whiteout_m3_M3ClothPhysics_get_simEnabled_count(
27703            self_: *mut whiteout_M3ClothPhysics,
27704        ) -> usize;
27705        pub fn whiteout_m3_M3ClothPhysics_resize_simEnabled(
27706            self_: *mut whiteout_M3ClothPhysics,
27707            count: usize,
27708        );
27709        pub fn whiteout_m3_M3ClothPhysics_get_simEnabled_data(
27710            self_: *mut whiteout_M3ClothPhysics,
27711        ) -> *const u8;
27712        pub fn whiteout_m3_M3ClothPhysics_assign_simEnabled(
27713            self_: *mut whiteout_M3ClothPhysics,
27714            data: *const u8,
27715            count: usize,
27716        );
27717        pub fn whiteout_m3_M3ClothPhysics_get_vertexBones_count(
27718            self_: *mut whiteout_M3ClothPhysics,
27719        ) -> usize;
27720        pub fn whiteout_m3_M3ClothPhysics_resize_vertexBones(
27721            self_: *mut whiteout_M3ClothPhysics,
27722            count: usize,
27723        );
27724        pub fn whiteout_m3_M3ClothPhysics_get_vertexBones_data(
27725            self_: *mut whiteout_M3ClothPhysics,
27726        ) -> *const u32;
27727        pub fn whiteout_m3_M3ClothPhysics_assign_vertexBones(
27728            self_: *mut whiteout_M3ClothPhysics,
27729            data: *const u32,
27730            count: usize,
27731        );
27732        pub fn whiteout_m3_M3ClothPhysics_get_vertexWeights_count(
27733            self_: *mut whiteout_M3ClothPhysics,
27734        ) -> usize;
27735        pub fn whiteout_m3_M3ClothPhysics_resize_vertexWeights(
27736            self_: *mut whiteout_M3ClothPhysics,
27737            count: usize,
27738        );
27739        pub fn whiteout_m3_M3ClothPhysics_get_vertexWeights_data(
27740            self_: *mut whiteout_M3ClothPhysics,
27741        ) -> *const u32;
27742        pub fn whiteout_m3_M3ClothPhysics_assign_vertexWeights(
27743            self_: *mut whiteout_M3ClothPhysics,
27744            data: *const u32,
27745            count: usize,
27746        );
27747        pub fn whiteout_m3_M3ClothPhysics_get_colliders_count(
27748            self_: *mut whiteout_M3ClothPhysics,
27749        ) -> usize;
27750        pub fn whiteout_m3_M3ClothPhysics_resize_colliders(
27751            self_: *mut whiteout_M3ClothPhysics,
27752            count: usize,
27753        );
27754        pub fn whiteout_m3_M3ClothPhysics_get_colliders_at(
27755            self_: *mut whiteout_M3ClothPhysics,
27756            index: usize,
27757        ) -> *mut whiteout_M3ClothCollider;
27758        pub fn whiteout_m3_M3ClothPhysics_get_proxies_count(
27759            self_: *mut whiteout_M3ClothPhysics,
27760        ) -> usize;
27761        pub fn whiteout_m3_M3ClothPhysics_resize_proxies(
27762            self_: *mut whiteout_M3ClothPhysics,
27763            count: usize,
27764        );
27765        pub fn whiteout_m3_M3ClothPhysics_get_proxies_at(
27766            self_: *mut whiteout_M3ClothPhysics,
27767            index: usize,
27768        ) -> *mut whiteout_M3ClothProxy;
27769        pub fn whiteout_m3_M3ClothPhysics_get_density(self_: *mut whiteout_M3ClothPhysics) -> f32;
27770        pub fn whiteout_m3_M3ClothPhysics_set_density(
27771            self_: *mut whiteout_M3ClothPhysics,
27772            value: f32,
27773        );
27774        pub fn whiteout_m3_M3ClothPhysics_get_tracking(self_: *mut whiteout_M3ClothPhysics) -> f32;
27775        pub fn whiteout_m3_M3ClothPhysics_set_tracking(
27776            self_: *mut whiteout_M3ClothPhysics,
27777            value: f32,
27778        );
27779        pub fn whiteout_m3_M3ClothPhysics_get_stretchStiffness(
27780            self_: *mut whiteout_M3ClothPhysics,
27781        ) -> f32;
27782        pub fn whiteout_m3_M3ClothPhysics_set_stretchStiffness(
27783            self_: *mut whiteout_M3ClothPhysics,
27784            value: f32,
27785        );
27786        pub fn whiteout_m3_M3ClothPhysics_get_horizontalStiffness(
27787            self_: *mut whiteout_M3ClothPhysics,
27788        ) -> f32;
27789        pub fn whiteout_m3_M3ClothPhysics_set_horizontalStiffness(
27790            self_: *mut whiteout_M3ClothPhysics,
27791            value: f32,
27792        );
27793        pub fn whiteout_m3_M3ClothPhysics_get_bendingStiffness(
27794            self_: *mut whiteout_M3ClothPhysics,
27795        ) -> f32;
27796        pub fn whiteout_m3_M3ClothPhysics_set_bendingStiffness(
27797            self_: *mut whiteout_M3ClothPhysics,
27798            value: f32,
27799        );
27800        pub fn whiteout_m3_M3ClothPhysics_get_damping(self_: *mut whiteout_M3ClothPhysics) -> f32;
27801        pub fn whiteout_m3_M3ClothPhysics_set_damping(
27802            self_: *mut whiteout_M3ClothPhysics,
27803            value: f32,
27804        );
27805        pub fn whiteout_m3_M3ClothPhysics_get_friction(self_: *mut whiteout_M3ClothPhysics) -> f32;
27806        pub fn whiteout_m3_M3ClothPhysics_set_friction(
27807            self_: *mut whiteout_M3ClothPhysics,
27808            value: f32,
27809        );
27810        pub fn whiteout_m3_M3ClothPhysics_get_gravity(self_: *mut whiteout_M3ClothPhysics) -> f32;
27811        pub fn whiteout_m3_M3ClothPhysics_set_gravity(
27812            self_: *mut whiteout_M3ClothPhysics,
27813            value: f32,
27814        );
27815        pub fn whiteout_m3_M3ClothPhysics_get_explosionScale(
27816            self_: *mut whiteout_M3ClothPhysics,
27817        ) -> f32;
27818        pub fn whiteout_m3_M3ClothPhysics_set_explosionScale(
27819            self_: *mut whiteout_M3ClothPhysics,
27820            value: f32,
27821        );
27822        pub fn whiteout_m3_M3ClothPhysics_get_windScale(self_: *mut whiteout_M3ClothPhysics)
27823            -> f32;
27824        pub fn whiteout_m3_M3ClothPhysics_set_windScale(
27825            self_: *mut whiteout_M3ClothPhysics,
27826            value: f32,
27827        );
27828        pub fn whiteout_m3_M3ClothPhysics_get_shearStiffness(
27829            self_: *mut whiteout_M3ClothPhysics,
27830        ) -> f32;
27831        pub fn whiteout_m3_M3ClothPhysics_set_shearStiffness(
27832            self_: *mut whiteout_M3ClothPhysics,
27833            value: f32,
27834        );
27835        pub fn whiteout_m3_M3ClothPhysics_get_dragFactor(
27836            self_: *mut whiteout_M3ClothPhysics,
27837        ) -> f32;
27838        pub fn whiteout_m3_M3ClothPhysics_set_dragFactor(
27839            self_: *mut whiteout_M3ClothPhysics,
27840            value: f32,
27841        );
27842        pub fn whiteout_m3_M3ClothPhysics_get_liftFactor(
27843            self_: *mut whiteout_M3ClothPhysics,
27844        ) -> f32;
27845        pub fn whiteout_m3_M3ClothPhysics_set_liftFactor(
27846            self_: *mut whiteout_M3ClothPhysics,
27847            value: f32,
27848        );
27849        pub fn whiteout_m3_M3ClothPhysics_get_sphereStiffness(
27850            self_: *mut whiteout_M3ClothPhysics,
27851        ) -> f32;
27852        pub fn whiteout_m3_M3ClothPhysics_set_sphereStiffness(
27853            self_: *mut whiteout_M3ClothPhysics,
27854            value: f32,
27855        );
27856        pub fn whiteout_m3_M3ClothPhysics_get_flatten(self_: *mut whiteout_M3ClothPhysics) -> u32;
27857        pub fn whiteout_m3_M3ClothPhysics_set_flatten(
27858            self_: *mut whiteout_M3ClothPhysics,
27859            value: u32,
27860        );
27861        pub fn whiteout_m3_M3ClothPhysics_get_active(
27862            self_: *mut whiteout_M3ClothPhysics,
27863        ) -> *mut whiteout_M3AnimRefU32;
27864        pub fn whiteout_m3_M3ClothPhysics_set_active(
27865            self_: *mut whiteout_M3ClothPhysics,
27866            value: *const whiteout_M3AnimRefU32,
27867        );
27868        pub fn whiteout_m3_M3ClothPhysics_get_useSkinCollision(
27869            self_: *mut whiteout_M3ClothPhysics,
27870        ) -> u32;
27871        pub fn whiteout_m3_M3ClothPhysics_set_useSkinCollision(
27872            self_: *mut whiteout_M3ClothPhysics,
27873            value: u32,
27874        );
27875        pub fn whiteout_m3_M3ClothPhysics_get_skinOffset(
27876            self_: *mut whiteout_M3ClothPhysics,
27877        ) -> f32;
27878        pub fn whiteout_m3_M3ClothPhysics_set_skinOffset(
27879            self_: *mut whiteout_M3ClothPhysics,
27880            value: f32,
27881        );
27882        pub fn whiteout_m3_M3ClothPhysics_get_skinExponent(
27883            self_: *mut whiteout_M3ClothPhysics,
27884        ) -> f32;
27885        pub fn whiteout_m3_M3ClothPhysics_set_skinExponent(
27886            self_: *mut whiteout_M3ClothPhysics,
27887            value: f32,
27888        );
27889        pub fn whiteout_m3_M3ClothPhysics_get_skinStiffness(
27890            self_: *mut whiteout_M3ClothPhysics,
27891        ) -> f32;
27892        pub fn whiteout_m3_M3ClothPhysics_set_skinStiffness(
27893            self_: *mut whiteout_M3ClothPhysics,
27894            value: f32,
27895        );
27896        pub fn whiteout_m3_M3ClothPhysics_get_localChannels(
27897            self_: *mut whiteout_M3ClothPhysics,
27898        ) -> u32;
27899        pub fn whiteout_m3_M3ClothPhysics_set_localChannels(
27900            self_: *mut whiteout_M3ClothPhysics,
27901            value: u32,
27902        );
27903        pub fn whiteout_m3_M3ClothPhysics_get_localWind(
27904            self_: *mut whiteout_M3ClothPhysics,
27905        ) -> *mut core::ffi::c_void;
27906        pub fn whiteout_m3_M3ClothPhysics_set_localWind(
27907            self_: *mut whiteout_M3ClothPhysics,
27908            value: *const core::ffi::c_void,
27909        );
27910        // Light
27911        pub fn whiteout_m3_M3Light_new() -> *mut whiteout_M3Light;
27912        pub fn whiteout_m3_M3Light_delete(self_: *mut whiteout_M3Light);
27913        pub fn whiteout_m3_M3Light_get_lightType(self_: *mut whiteout_M3Light) -> i32;
27914        pub fn whiteout_m3_M3Light_set_lightType(self_: *mut whiteout_M3Light, value: i32);
27915        pub fn whiteout_m3_M3Light_get_boneIndex(self_: *mut whiteout_M3Light) -> u16;
27916        pub fn whiteout_m3_M3Light_set_boneIndex(self_: *mut whiteout_M3Light, value: u16);
27917        pub fn whiteout_m3_M3Light_get_flags(self_: *mut whiteout_M3Light) -> i32;
27918        pub fn whiteout_m3_M3Light_set_flags(self_: *mut whiteout_M3Light, value: i32);
27919        pub fn whiteout_m3_M3Light_get_lodCut(self_: *mut whiteout_M3Light) -> u32;
27920        pub fn whiteout_m3_M3Light_set_lodCut(self_: *mut whiteout_M3Light, value: u32);
27921        pub fn whiteout_m3_M3Light_get_shadowLodCut(self_: *mut whiteout_M3Light) -> u32;
27922        pub fn whiteout_m3_M3Light_set_shadowLodCut(self_: *mut whiteout_M3Light, value: u32);
27923        pub fn whiteout_m3_M3Light_get_diffuseColor(
27924            self_: *mut whiteout_M3Light,
27925        ) -> *mut whiteout_M3AnimRefVector3f;
27926        pub fn whiteout_m3_M3Light_set_diffuseColor(
27927            self_: *mut whiteout_M3Light,
27928            value: *const whiteout_M3AnimRefVector3f,
27929        );
27930        pub fn whiteout_m3_M3Light_get_intensityMultiplier(
27931            self_: *mut whiteout_M3Light,
27932        ) -> *mut whiteout_M3AnimRefF32;
27933        pub fn whiteout_m3_M3Light_set_intensityMultiplier(
27934            self_: *mut whiteout_M3Light,
27935            value: *const whiteout_M3AnimRefF32,
27936        );
27937        pub fn whiteout_m3_M3Light_get_specularColor(
27938            self_: *mut whiteout_M3Light,
27939        ) -> *mut whiteout_M3AnimRefVector3f;
27940        pub fn whiteout_m3_M3Light_set_specularColor(
27941            self_: *mut whiteout_M3Light,
27942            value: *const whiteout_M3AnimRefVector3f,
27943        );
27944        pub fn whiteout_m3_M3Light_get_specularMultiplier(
27945            self_: *mut whiteout_M3Light,
27946        ) -> *mut whiteout_M3AnimRefF32;
27947        pub fn whiteout_m3_M3Light_set_specularMultiplier(
27948            self_: *mut whiteout_M3Light,
27949            value: *const whiteout_M3AnimRefF32,
27950        );
27951        pub fn whiteout_m3_M3Light_get_decay(
27952            self_: *mut whiteout_M3Light,
27953        ) -> *mut whiteout_M3AnimRefF32;
27954        pub fn whiteout_m3_M3Light_set_decay(
27955            self_: *mut whiteout_M3Light,
27956            value: *const whiteout_M3AnimRefF32,
27957        );
27958        pub fn whiteout_m3_M3Light_get_attenuationEnd(self_: *mut whiteout_M3Light) -> f32;
27959        pub fn whiteout_m3_M3Light_set_attenuationEnd(self_: *mut whiteout_M3Light, value: f32);
27960        pub fn whiteout_m3_M3Light_get_attenuationStart(
27961            self_: *mut whiteout_M3Light,
27962        ) -> *mut whiteout_M3AnimRefF32;
27963        pub fn whiteout_m3_M3Light_set_attenuationStart(
27964            self_: *mut whiteout_M3Light,
27965            value: *const whiteout_M3AnimRefF32,
27966        );
27967        pub fn whiteout_m3_M3Light_get_hotSpot(
27968            self_: *mut whiteout_M3Light,
27969        ) -> *mut whiteout_M3AnimRefF32;
27970        pub fn whiteout_m3_M3Light_set_hotSpot(
27971            self_: *mut whiteout_M3Light,
27972            value: *const whiteout_M3AnimRefF32,
27973        );
27974        pub fn whiteout_m3_M3Light_get_falloff(
27975            self_: *mut whiteout_M3Light,
27976        ) -> *mut whiteout_M3AnimRefF32;
27977        pub fn whiteout_m3_M3Light_set_falloff(
27978            self_: *mut whiteout_M3Light,
27979            value: *const whiteout_M3AnimRefF32,
27980        );
27981        // Camera
27982        pub fn whiteout_m3_M3Camera_new() -> *mut whiteout_M3Camera;
27983        pub fn whiteout_m3_M3Camera_delete(self_: *mut whiteout_M3Camera);
27984        pub fn whiteout_m3_M3Camera_get_boneIndex(self_: *mut whiteout_M3Camera) -> u32;
27985        pub fn whiteout_m3_M3Camera_set_boneIndex(self_: *mut whiteout_M3Camera, value: u32);
27986        pub fn whiteout_m3_M3Camera_get_name(self_: *mut whiteout_M3Camera) -> RawCString;
27987        pub fn whiteout_m3_M3Camera_set_name(
27988            self_: *mut whiteout_M3Camera,
27989            value: *const core::ffi::c_char,
27990        );
27991        pub fn whiteout_m3_M3Camera_get_fieldOfView(
27992            self_: *mut whiteout_M3Camera,
27993        ) -> *mut whiteout_M3AnimRefF32;
27994        pub fn whiteout_m3_M3Camera_set_fieldOfView(
27995            self_: *mut whiteout_M3Camera,
27996            value: *const whiteout_M3AnimRefF32,
27997        );
27998        pub fn whiteout_m3_M3Camera_get_useVerticalFOV(self_: *mut whiteout_M3Camera) -> u32;
27999        pub fn whiteout_m3_M3Camera_set_useVerticalFOV(self_: *mut whiteout_M3Camera, value: u32);
28000        pub fn whiteout_m3_M3Camera_get_dofType(self_: *mut whiteout_M3Camera) -> u32;
28001        pub fn whiteout_m3_M3Camera_set_dofType(self_: *mut whiteout_M3Camera, value: u32);
28002        pub fn whiteout_m3_M3Camera_get_farClip(
28003            self_: *mut whiteout_M3Camera,
28004        ) -> *mut whiteout_M3AnimRefF32;
28005        pub fn whiteout_m3_M3Camera_set_farClip(
28006            self_: *mut whiteout_M3Camera,
28007            value: *const whiteout_M3AnimRefF32,
28008        );
28009        pub fn whiteout_m3_M3Camera_get_nearClip(
28010            self_: *mut whiteout_M3Camera,
28011        ) -> *mut whiteout_M3AnimRefF32;
28012        pub fn whiteout_m3_M3Camera_set_nearClip(
28013            self_: *mut whiteout_M3Camera,
28014            value: *const whiteout_M3AnimRefF32,
28015        );
28016        pub fn whiteout_m3_M3Camera_get_shadowClipDistance(
28017            self_: *mut whiteout_M3Camera,
28018        ) -> *mut whiteout_M3AnimRefF32;
28019        pub fn whiteout_m3_M3Camera_set_shadowClipDistance(
28020            self_: *mut whiteout_M3Camera,
28021            value: *const whiteout_M3AnimRefF32,
28022        );
28023        pub fn whiteout_m3_M3Camera_get_focusDistance(
28024            self_: *mut whiteout_M3Camera,
28025        ) -> *mut whiteout_M3AnimRefF32;
28026        pub fn whiteout_m3_M3Camera_set_focusDistance(
28027            self_: *mut whiteout_M3Camera,
28028            value: *const whiteout_M3AnimRefF32,
28029        );
28030        pub fn whiteout_m3_M3Camera_get_farFocusRange(
28031            self_: *mut whiteout_M3Camera,
28032        ) -> *mut whiteout_M3AnimRefF32;
28033        pub fn whiteout_m3_M3Camera_set_farFocusRange(
28034            self_: *mut whiteout_M3Camera,
28035            value: *const whiteout_M3AnimRefF32,
28036        );
28037        pub fn whiteout_m3_M3Camera_get_nearFocusRange(
28038            self_: *mut whiteout_M3Camera,
28039        ) -> *mut whiteout_M3AnimRefF32;
28040        pub fn whiteout_m3_M3Camera_set_nearFocusRange(
28041            self_: *mut whiteout_M3Camera,
28042            value: *const whiteout_M3AnimRefF32,
28043        );
28044        pub fn whiteout_m3_M3Camera_get_nearFalloffStart(
28045            self_: *mut whiteout_M3Camera,
28046        ) -> *mut whiteout_M3AnimRefF32;
28047        pub fn whiteout_m3_M3Camera_set_nearFalloffStart(
28048            self_: *mut whiteout_M3Camera,
28049            value: *const whiteout_M3AnimRefF32,
28050        );
28051        pub fn whiteout_m3_M3Camera_get_nearFalloffEnd(
28052            self_: *mut whiteout_M3Camera,
28053        ) -> *mut whiteout_M3AnimRefF32;
28054        pub fn whiteout_m3_M3Camera_set_nearFalloffEnd(
28055            self_: *mut whiteout_M3Camera,
28056            value: *const whiteout_M3AnimRefF32,
28057        );
28058        pub fn whiteout_m3_M3Camera_get_dofAmount(
28059            self_: *mut whiteout_M3Camera,
28060        ) -> *mut whiteout_M3AnimRefF32;
28061        pub fn whiteout_m3_M3Camera_set_dofAmount(
28062            self_: *mut whiteout_M3Camera,
28063            value: *const whiteout_M3AnimRefF32,
28064        );
28065        pub fn whiteout_m3_M3Camera_get_bokehFStop(
28066            self_: *mut whiteout_M3Camera,
28067        ) -> *mut whiteout_M3AnimRefF32;
28068        pub fn whiteout_m3_M3Camera_set_bokehFStop(
28069            self_: *mut whiteout_M3Camera,
28070            value: *const whiteout_M3AnimRefF32,
28071        );
28072        pub fn whiteout_m3_M3Camera_get_bokehMaxCoCDiameter(
28073            self_: *mut whiteout_M3Camera,
28074        ) -> *mut whiteout_M3AnimRefF32;
28075        pub fn whiteout_m3_M3Camera_set_bokehMaxCoCDiameter(
28076            self_: *mut whiteout_M3Camera,
28077            value: *const whiteout_M3AnimRefF32,
28078        );
28079        // Model
28080        pub fn whiteout_m3_M3Model_new() -> *mut whiteout_M3Model;
28081        pub fn whiteout_m3_M3Model_delete(self_: *mut whiteout_M3Model);
28082        pub fn whiteout_m3_M3Model_get_name(self_: *mut whiteout_M3Model) -> RawCString;
28083        pub fn whiteout_m3_M3Model_set_name(
28084            self_: *mut whiteout_M3Model,
28085            value: *const core::ffi::c_char,
28086        );
28087        pub fn whiteout_m3_M3Model_get_flags(self_: *mut whiteout_M3Model) -> i32;
28088        pub fn whiteout_m3_M3Model_set_flags(self_: *mut whiteout_M3Model, value: i32);
28089        pub fn whiteout_m3_M3Model_get_sequences_count(self_: *mut whiteout_M3Model) -> usize;
28090        pub fn whiteout_m3_M3Model_resize_sequences(self_: *mut whiteout_M3Model, count: usize);
28091        pub fn whiteout_m3_M3Model_get_sequences_at(
28092            self_: *mut whiteout_M3Model,
28093            index: usize,
28094        ) -> *mut whiteout_M3Sequence;
28095        pub fn whiteout_m3_M3Model_get_subTrackCollections_count(
28096            self_: *mut whiteout_M3Model,
28097        ) -> usize;
28098        pub fn whiteout_m3_M3Model_resize_subTrackCollections(
28099            self_: *mut whiteout_M3Model,
28100            count: usize,
28101        );
28102        pub fn whiteout_m3_M3Model_get_subTrackCollections_at(
28103            self_: *mut whiteout_M3Model,
28104            index: usize,
28105        ) -> *mut whiteout_M3SubTrackContainer;
28106        pub fn whiteout_m3_M3Model_get_animationGroups_count(self_: *mut whiteout_M3Model)
28107            -> usize;
28108        pub fn whiteout_m3_M3Model_resize_animationGroups(
28109            self_: *mut whiteout_M3Model,
28110            count: usize,
28111        );
28112        pub fn whiteout_m3_M3Model_get_animationGroups_at(
28113            self_: *mut whiteout_M3Model,
28114            index: usize,
28115        ) -> *mut whiteout_M3AnimationGroup;
28116        pub fn whiteout_m3_M3Model_get_boneAnimationSets_count(
28117            self_: *mut whiteout_M3Model,
28118        ) -> usize;
28119        pub fn whiteout_m3_M3Model_resize_boneAnimationSets(
28120            self_: *mut whiteout_M3Model,
28121            count: usize,
28122        );
28123        pub fn whiteout_m3_M3Model_get_boneAnimationSets_at(
28124            self_: *mut whiteout_M3Model,
28125            index: usize,
28126        ) -> *mut whiteout_M3BoneAnimationSet;
28127        pub fn whiteout_m3_M3Model_get_animationSplitCount(self_: *mut whiteout_M3Model) -> u32;
28128        pub fn whiteout_m3_M3Model_set_animationSplitCount(
28129            self_: *mut whiteout_M3Model,
28130            value: u32,
28131        );
28132        pub fn whiteout_m3_M3Model_get_animationStates_count(self_: *mut whiteout_M3Model)
28133            -> usize;
28134        pub fn whiteout_m3_M3Model_resize_animationStates(
28135            self_: *mut whiteout_M3Model,
28136            count: usize,
28137        );
28138        pub fn whiteout_m3_M3Model_get_animationStates_at(
28139            self_: *mut whiteout_M3Model,
28140            index: usize,
28141        ) -> *mut whiteout_M3AnimationState;
28142        pub fn whiteout_m3_M3Model_get_bones_count(self_: *mut whiteout_M3Model) -> usize;
28143        pub fn whiteout_m3_M3Model_resize_bones(self_: *mut whiteout_M3Model, count: usize);
28144        pub fn whiteout_m3_M3Model_get_bones_at(
28145            self_: *mut whiteout_M3Model,
28146            index: usize,
28147        ) -> *mut whiteout_M3Bone;
28148        pub fn whiteout_m3_M3Model_get_skinBoneCount(self_: *mut whiteout_M3Model) -> u32;
28149        pub fn whiteout_m3_M3Model_set_skinBoneCount(self_: *mut whiteout_M3Model, value: u32);
28150        pub fn whiteout_m3_M3Model_get_divisions_count(self_: *mut whiteout_M3Model) -> usize;
28151        pub fn whiteout_m3_M3Model_resize_divisions(self_: *mut whiteout_M3Model, count: usize);
28152        pub fn whiteout_m3_M3Model_get_divisions_at(
28153            self_: *mut whiteout_M3Model,
28154            index: usize,
28155        ) -> *mut whiteout_M3MeshDivision;
28156        pub fn whiteout_m3_M3Model_get_boneLookup_count(self_: *mut whiteout_M3Model) -> usize;
28157        pub fn whiteout_m3_M3Model_resize_boneLookup(self_: *mut whiteout_M3Model, count: usize);
28158        pub fn whiteout_m3_M3Model_get_boneLookup_data(self_: *mut whiteout_M3Model) -> *const u16;
28159        pub fn whiteout_m3_M3Model_assign_boneLookup(
28160            self_: *mut whiteout_M3Model,
28161            data: *const u16,
28162            count: usize,
28163        );
28164        pub fn whiteout_m3_M3Model_get_bounds(
28165            self_: *mut whiteout_M3Model,
28166        ) -> *mut whiteout_M3Extent;
28167        pub fn whiteout_m3_M3Model_set_bounds(
28168            self_: *mut whiteout_M3Model,
28169            value: *const whiteout_M3Extent,
28170        );
28171        pub fn whiteout_m3_M3Model_get_collisionBounds(
28172            self_: *mut whiteout_M3Model,
28173        ) -> *mut whiteout_M3Extent;
28174        pub fn whiteout_m3_M3Model_set_collisionBounds(
28175            self_: *mut whiteout_M3Model,
28176            value: *const whiteout_M3Extent,
28177        );
28178        pub fn whiteout_m3_M3Model_get_collisionFaces_count(self_: *mut whiteout_M3Model) -> usize;
28179        pub fn whiteout_m3_M3Model_resize_collisionFaces(
28180            self_: *mut whiteout_M3Model,
28181            count: usize,
28182        );
28183        pub fn whiteout_m3_M3Model_get_collisionFaces_data(
28184            self_: *mut whiteout_M3Model,
28185        ) -> *const u16;
28186        pub fn whiteout_m3_M3Model_assign_collisionFaces(
28187            self_: *mut whiteout_M3Model,
28188            data: *const u16,
28189            count: usize,
28190        );
28191        pub fn whiteout_m3_M3Model_get_collisionVerts_count(self_: *mut whiteout_M3Model) -> usize;
28192        pub fn whiteout_m3_M3Model_resize_collisionVerts(
28193            self_: *mut whiteout_M3Model,
28194            count: usize,
28195        );
28196        pub fn whiteout_m3_M3Model_get_collisionVerts_data(
28197            self_: *mut whiteout_M3Model,
28198        ) -> *const f32;
28199        pub fn whiteout_m3_M3Model_assign_collisionVerts(
28200            self_: *mut whiteout_M3Model,
28201            data: *const f32,
28202            count: usize,
28203        );
28204        pub fn whiteout_m3_M3Model_get_collisionNormals_count(
28205            self_: *mut whiteout_M3Model,
28206        ) -> usize;
28207        pub fn whiteout_m3_M3Model_resize_collisionNormals(
28208            self_: *mut whiteout_M3Model,
28209            count: usize,
28210        );
28211        pub fn whiteout_m3_M3Model_get_collisionNormals_data(
28212            self_: *mut whiteout_M3Model,
28213        ) -> *const f32;
28214        pub fn whiteout_m3_M3Model_assign_collisionNormals(
28215            self_: *mut whiteout_M3Model,
28216            data: *const f32,
28217            count: usize,
28218        );
28219        pub fn whiteout_m3_M3Model_get_attachmentPoints_count(
28220            self_: *mut whiteout_M3Model,
28221        ) -> usize;
28222        pub fn whiteout_m3_M3Model_resize_attachmentPoints(
28223            self_: *mut whiteout_M3Model,
28224            count: usize,
28225        );
28226        pub fn whiteout_m3_M3Model_get_attachmentPoints_at(
28227            self_: *mut whiteout_M3Model,
28228            index: usize,
28229        ) -> *mut whiteout_M3AttachmentPoint;
28230        pub fn whiteout_m3_M3Model_get_attachmentPointAddons_count(
28231            self_: *mut whiteout_M3Model,
28232        ) -> usize;
28233        pub fn whiteout_m3_M3Model_resize_attachmentPointAddons(
28234            self_: *mut whiteout_M3Model,
28235            count: usize,
28236        );
28237        pub fn whiteout_m3_M3Model_get_attachmentPointAddons_data(
28238            self_: *mut whiteout_M3Model,
28239        ) -> *const u16;
28240        pub fn whiteout_m3_M3Model_assign_attachmentPointAddons(
28241            self_: *mut whiteout_M3Model,
28242            data: *const u16,
28243            count: usize,
28244        );
28245        pub fn whiteout_m3_M3Model_get_lights_count(self_: *mut whiteout_M3Model) -> usize;
28246        pub fn whiteout_m3_M3Model_resize_lights(self_: *mut whiteout_M3Model, count: usize);
28247        pub fn whiteout_m3_M3Model_get_lights_at(
28248            self_: *mut whiteout_M3Model,
28249            index: usize,
28250        ) -> *mut whiteout_M3Light;
28251        pub fn whiteout_m3_M3Model_get_shadowBoxes_count(self_: *mut whiteout_M3Model) -> usize;
28252        pub fn whiteout_m3_M3Model_resize_shadowBoxes(self_: *mut whiteout_M3Model, count: usize);
28253        pub fn whiteout_m3_M3Model_get_shadowBoxes_at(
28254            self_: *mut whiteout_M3Model,
28255            index: usize,
28256        ) -> *mut whiteout_M3ShadowBox;
28257        pub fn whiteout_m3_M3Model_get_cameras_count(self_: *mut whiteout_M3Model) -> usize;
28258        pub fn whiteout_m3_M3Model_resize_cameras(self_: *mut whiteout_M3Model, count: usize);
28259        pub fn whiteout_m3_M3Model_get_cameras_at(
28260            self_: *mut whiteout_M3Model,
28261            index: usize,
28262        ) -> *mut whiteout_M3Camera;
28263        pub fn whiteout_m3_M3Model_get_camerasAddons_count(self_: *mut whiteout_M3Model) -> usize;
28264        pub fn whiteout_m3_M3Model_resize_camerasAddons(self_: *mut whiteout_M3Model, count: usize);
28265        pub fn whiteout_m3_M3Model_get_camerasAddons_data(
28266            self_: *mut whiteout_M3Model,
28267        ) -> *const u16;
28268        pub fn whiteout_m3_M3Model_assign_camerasAddons(
28269            self_: *mut whiteout_M3Model,
28270            data: *const u16,
28271            count: usize,
28272        );
28273        pub fn whiteout_m3_M3Model_get_materialMaps_count(self_: *mut whiteout_M3Model) -> usize;
28274        pub fn whiteout_m3_M3Model_resize_materialMaps(self_: *mut whiteout_M3Model, count: usize);
28275        pub fn whiteout_m3_M3Model_get_materialMaps_at(
28276            self_: *mut whiteout_M3Model,
28277            index: usize,
28278        ) -> *mut whiteout_M3MaterialMap;
28279        pub fn whiteout_m3_M3Model_get_standardMaterials_count(
28280            self_: *mut whiteout_M3Model,
28281        ) -> usize;
28282        pub fn whiteout_m3_M3Model_resize_standardMaterials(
28283            self_: *mut whiteout_M3Model,
28284            count: usize,
28285        );
28286        pub fn whiteout_m3_M3Model_get_standardMaterials_at(
28287            self_: *mut whiteout_M3Model,
28288            index: usize,
28289        ) -> *mut whiteout_M3StandardMaterial;
28290        pub fn whiteout_m3_M3Model_get_displacementMaterials_count(
28291            self_: *mut whiteout_M3Model,
28292        ) -> usize;
28293        pub fn whiteout_m3_M3Model_resize_displacementMaterials(
28294            self_: *mut whiteout_M3Model,
28295            count: usize,
28296        );
28297        pub fn whiteout_m3_M3Model_get_displacementMaterials_at(
28298            self_: *mut whiteout_M3Model,
28299            index: usize,
28300        ) -> *mut whiteout_M3DisplacementMaterial;
28301        pub fn whiteout_m3_M3Model_get_compositeMaterials_count(
28302            self_: *mut whiteout_M3Model,
28303        ) -> usize;
28304        pub fn whiteout_m3_M3Model_resize_compositeMaterials(
28305            self_: *mut whiteout_M3Model,
28306            count: usize,
28307        );
28308        pub fn whiteout_m3_M3Model_get_compositeMaterials_at(
28309            self_: *mut whiteout_M3Model,
28310            index: usize,
28311        ) -> *mut whiteout_M3CompositeMaterial;
28312        pub fn whiteout_m3_M3Model_get_terrainMaterials_count(
28313            self_: *mut whiteout_M3Model,
28314        ) -> usize;
28315        pub fn whiteout_m3_M3Model_resize_terrainMaterials(
28316            self_: *mut whiteout_M3Model,
28317            count: usize,
28318        );
28319        pub fn whiteout_m3_M3Model_get_terrainMaterials_at(
28320            self_: *mut whiteout_M3Model,
28321            index: usize,
28322        ) -> *mut whiteout_M3TerrainMaterial;
28323        pub fn whiteout_m3_M3Model_get_volumeMaterials_count(self_: *mut whiteout_M3Model)
28324            -> usize;
28325        pub fn whiteout_m3_M3Model_resize_volumeMaterials(
28326            self_: *mut whiteout_M3Model,
28327            count: usize,
28328        );
28329        pub fn whiteout_m3_M3Model_get_volumeMaterials_at(
28330            self_: *mut whiteout_M3Model,
28331            index: usize,
28332        ) -> *mut whiteout_M3VolumeMaterial;
28333        pub fn whiteout_m3_M3Model_get_hairMaterials_count(self_: *mut whiteout_M3Model) -> usize;
28334        pub fn whiteout_m3_M3Model_resize_hairMaterials(self_: *mut whiteout_M3Model, count: usize);
28335        pub fn whiteout_m3_M3Model_get_hairMaterials_at(
28336            self_: *mut whiteout_M3Model,
28337            index: usize,
28338        ) -> *mut whiteout_M3HairMaterial;
28339        pub fn whiteout_m3_M3Model_get_creepMaterials_count(self_: *mut whiteout_M3Model) -> usize;
28340        pub fn whiteout_m3_M3Model_resize_creepMaterials(
28341            self_: *mut whiteout_M3Model,
28342            count: usize,
28343        );
28344        pub fn whiteout_m3_M3Model_get_creepMaterials_at(
28345            self_: *mut whiteout_M3Model,
28346            index: usize,
28347        ) -> *mut whiteout_M3CreepMaterial;
28348        pub fn whiteout_m3_M3Model_get_volumeNoiseMaterials_count(
28349            self_: *mut whiteout_M3Model,
28350        ) -> usize;
28351        pub fn whiteout_m3_M3Model_resize_volumeNoiseMaterials(
28352            self_: *mut whiteout_M3Model,
28353            count: usize,
28354        );
28355        pub fn whiteout_m3_M3Model_get_volumeNoiseMaterials_at(
28356            self_: *mut whiteout_M3Model,
28357            index: usize,
28358        ) -> *mut whiteout_M3VolumeNoiseMaterial;
28359        pub fn whiteout_m3_M3Model_get_stbMaterials_count(self_: *mut whiteout_M3Model) -> usize;
28360        pub fn whiteout_m3_M3Model_resize_stbMaterials(self_: *mut whiteout_M3Model, count: usize);
28361        pub fn whiteout_m3_M3Model_get_stbMaterials_at(
28362            self_: *mut whiteout_M3Model,
28363            index: usize,
28364        ) -> *mut whiteout_M3STBMaterial;
28365        pub fn whiteout_m3_M3Model_get_reflectionMaterials_count(
28366            self_: *mut whiteout_M3Model,
28367        ) -> usize;
28368        pub fn whiteout_m3_M3Model_resize_reflectionMaterials(
28369            self_: *mut whiteout_M3Model,
28370            count: usize,
28371        );
28372        pub fn whiteout_m3_M3Model_get_reflectionMaterials_at(
28373            self_: *mut whiteout_M3Model,
28374            index: usize,
28375        ) -> *mut whiteout_M3ReflectionMaterial;
28376        pub fn whiteout_m3_M3Model_get_lensFlareMaterials_count(
28377            self_: *mut whiteout_M3Model,
28378        ) -> usize;
28379        pub fn whiteout_m3_M3Model_resize_lensFlareMaterials(
28380            self_: *mut whiteout_M3Model,
28381            count: usize,
28382        );
28383        pub fn whiteout_m3_M3Model_get_lensFlareMaterials_at(
28384            self_: *mut whiteout_M3Model,
28385            index: usize,
28386        ) -> *mut whiteout_M3LensFlare;
28387        pub fn whiteout_m3_M3Model_get_materialAddData_count(self_: *mut whiteout_M3Model)
28388            -> usize;
28389        pub fn whiteout_m3_M3Model_resize_materialAddData(
28390            self_: *mut whiteout_M3Model,
28391            count: usize,
28392        );
28393        pub fn whiteout_m3_M3Model_get_materialAddData_at(
28394            self_: *mut whiteout_M3Model,
28395            index: usize,
28396        ) -> *mut whiteout_M3MaterialAddData;
28397        pub fn whiteout_m3_M3Model_get_particleEmitters_count(
28398            self_: *mut whiteout_M3Model,
28399        ) -> usize;
28400        pub fn whiteout_m3_M3Model_resize_particleEmitters(
28401            self_: *mut whiteout_M3Model,
28402            count: usize,
28403        );
28404        pub fn whiteout_m3_M3Model_get_particleEmitters_at(
28405            self_: *mut whiteout_M3Model,
28406            index: usize,
28407        ) -> *mut whiteout_M3ParticleEmitter;
28408        pub fn whiteout_m3_M3Model_get_particleEmitterCopies_count(
28409            self_: *mut whiteout_M3Model,
28410        ) -> usize;
28411        pub fn whiteout_m3_M3Model_resize_particleEmitterCopies(
28412            self_: *mut whiteout_M3Model,
28413            count: usize,
28414        );
28415        pub fn whiteout_m3_M3Model_get_particleEmitterCopies_at(
28416            self_: *mut whiteout_M3Model,
28417            index: usize,
28418        ) -> *mut whiteout_M3ParticleEmitterCopy;
28419        pub fn whiteout_m3_M3Model_get_ribbonEmitters_count(self_: *mut whiteout_M3Model) -> usize;
28420        pub fn whiteout_m3_M3Model_resize_ribbonEmitters(
28421            self_: *mut whiteout_M3Model,
28422            count: usize,
28423        );
28424        pub fn whiteout_m3_M3Model_get_ribbonEmitters_at(
28425            self_: *mut whiteout_M3Model,
28426            index: usize,
28427        ) -> *mut whiteout_M3RibbonEmitter;
28428        pub fn whiteout_m3_M3Model_get_projections_count(self_: *mut whiteout_M3Model) -> usize;
28429        pub fn whiteout_m3_M3Model_resize_projections(self_: *mut whiteout_M3Model, count: usize);
28430        pub fn whiteout_m3_M3Model_get_projections_at(
28431            self_: *mut whiteout_M3Model,
28432            index: usize,
28433        ) -> *mut whiteout_M3Projector;
28434        pub fn whiteout_m3_M3Model_get_forces_count(self_: *mut whiteout_M3Model) -> usize;
28435        pub fn whiteout_m3_M3Model_resize_forces(self_: *mut whiteout_M3Model, count: usize);
28436        pub fn whiteout_m3_M3Model_get_forces_at(
28437            self_: *mut whiteout_M3Model,
28438            index: usize,
28439        ) -> *mut whiteout_M3Force;
28440        pub fn whiteout_m3_M3Model_get_warps_count(self_: *mut whiteout_M3Model) -> usize;
28441        pub fn whiteout_m3_M3Model_resize_warps(self_: *mut whiteout_M3Model, count: usize);
28442        pub fn whiteout_m3_M3Model_get_warps_at(
28443            self_: *mut whiteout_M3Model,
28444            index: usize,
28445        ) -> *mut whiteout_M3Warp;
28446        pub fn whiteout_m3_M3Model_get_viewVolumes_count(self_: *mut whiteout_M3Model) -> usize;
28447        pub fn whiteout_m3_M3Model_resize_viewVolumes(self_: *mut whiteout_M3Model, count: usize);
28448        pub fn whiteout_m3_M3Model_get_viewVolumes_at(
28449            self_: *mut whiteout_M3Model,
28450            index: usize,
28451        ) -> *mut whiteout_M3ViewVolume;
28452        pub fn whiteout_m3_M3Model_get_rigidBodies_count(self_: *mut whiteout_M3Model) -> usize;
28453        pub fn whiteout_m3_M3Model_resize_rigidBodies(self_: *mut whiteout_M3Model, count: usize);
28454        pub fn whiteout_m3_M3Model_get_rigidBodies_at(
28455            self_: *mut whiteout_M3Model,
28456            index: usize,
28457        ) -> *mut whiteout_M3RigidBody;
28458        pub fn whiteout_m3_M3Model_get_physicsConstraints_count(
28459            self_: *mut whiteout_M3Model,
28460        ) -> usize;
28461        pub fn whiteout_m3_M3Model_resize_physicsConstraints(
28462            self_: *mut whiteout_M3Model,
28463            count: usize,
28464        );
28465        pub fn whiteout_m3_M3Model_get_physicsConstraints_at(
28466            self_: *mut whiteout_M3Model,
28467            index: usize,
28468        ) -> *mut whiteout_M3PhysicsConstraint;
28469        pub fn whiteout_m3_M3Model_get_physicsJoints_count(self_: *mut whiteout_M3Model) -> usize;
28470        pub fn whiteout_m3_M3Model_resize_physicsJoints(self_: *mut whiteout_M3Model, count: usize);
28471        pub fn whiteout_m3_M3Model_get_physicsJoints_at(
28472            self_: *mut whiteout_M3Model,
28473            index: usize,
28474        ) -> *mut whiteout_M3PhysicsJoint;
28475        pub fn whiteout_m3_M3Model_get_clothPhysics_count(self_: *mut whiteout_M3Model) -> usize;
28476        pub fn whiteout_m3_M3Model_resize_clothPhysics(self_: *mut whiteout_M3Model, count: usize);
28477        pub fn whiteout_m3_M3Model_get_clothPhysics_at(
28478            self_: *mut whiteout_M3Model,
28479            index: usize,
28480        ) -> *mut whiteout_M3ClothPhysics;
28481        pub fn whiteout_m3_M3Model_get_ikTwoJoints_count(self_: *mut whiteout_M3Model) -> usize;
28482        pub fn whiteout_m3_M3Model_resize_ikTwoJoints(self_: *mut whiteout_M3Model, count: usize);
28483        pub fn whiteout_m3_M3Model_get_ikTwoJoints_at(
28484            self_: *mut whiteout_M3Model,
28485            index: usize,
28486        ) -> *mut whiteout_M3IKTwoJoint;
28487        pub fn whiteout_m3_M3Model_get_ikCCD_count(self_: *mut whiteout_M3Model) -> usize;
28488        pub fn whiteout_m3_M3Model_resize_ikCCD(self_: *mut whiteout_M3Model, count: usize);
28489        pub fn whiteout_m3_M3Model_get_ikCCD_at(
28490            self_: *mut whiteout_M3Model,
28491            index: usize,
28492        ) -> *mut whiteout_M3IKCCD;
28493        pub fn whiteout_m3_M3Model_get_ikJoints_count(self_: *mut whiteout_M3Model) -> usize;
28494        pub fn whiteout_m3_M3Model_resize_ikJoints(self_: *mut whiteout_M3Model, count: usize);
28495        pub fn whiteout_m3_M3Model_get_ikJoints_at(
28496            self_: *mut whiteout_M3Model,
28497            index: usize,
28498        ) -> *mut whiteout_M3IKJoint;
28499        pub fn whiteout_m3_M3Model_get_oneBoneSolvers_count(self_: *mut whiteout_M3Model) -> usize;
28500        pub fn whiteout_m3_M3Model_resize_oneBoneSolvers(
28501            self_: *mut whiteout_M3Model,
28502            count: usize,
28503        );
28504        pub fn whiteout_m3_M3Model_get_oneBoneSolvers_at(
28505            self_: *mut whiteout_M3Model,
28506            index: usize,
28507        ) -> *mut whiteout_M3OneBoneSolver;
28508        pub fn whiteout_m3_M3Model_get_turretBehaviors_count(self_: *mut whiteout_M3Model)
28509            -> usize;
28510        pub fn whiteout_m3_M3Model_resize_turretBehaviors(
28511            self_: *mut whiteout_M3Model,
28512            count: usize,
28513        );
28514        pub fn whiteout_m3_M3Model_get_turretBehaviors_at(
28515            self_: *mut whiteout_M3Model,
28516            index: usize,
28517        ) -> *mut whiteout_M3TurretBehavior;
28518        pub fn whiteout_m3_M3Model_get_triggerData_count(self_: *mut whiteout_M3Model) -> usize;
28519        pub fn whiteout_m3_M3Model_resize_triggerData(self_: *mut whiteout_M3Model, count: usize);
28520        pub fn whiteout_m3_M3Model_get_triggerData_at(
28521            self_: *mut whiteout_M3Model,
28522            index: usize,
28523        ) -> *mut whiteout_M3TriggerData;
28524        pub fn whiteout_m3_M3Model_get_initialReference_count(
28525            self_: *mut whiteout_M3Model,
28526        ) -> usize;
28527        pub fn whiteout_m3_M3Model_resize_initialReference(
28528            self_: *mut whiteout_M3Model,
28529            count: usize,
28530        );
28531        pub fn whiteout_m3_M3Model_get_initialReference_at(
28532            self_: *mut whiteout_M3Model,
28533            index: usize,
28534        ) -> *mut whiteout_M3InitialReference;
28535        pub fn whiteout_m3_M3Model_get_tightHitTestObject(
28536            self_: *mut whiteout_M3Model,
28537        ) -> *mut whiteout_M3HitTestShape;
28538        pub fn whiteout_m3_M3Model_set_tightHitTestObject(
28539            self_: *mut whiteout_M3Model,
28540            value: *const whiteout_M3HitTestShape,
28541        );
28542        pub fn whiteout_m3_M3Model_get_fuzzyHitTestObjects_count(
28543            self_: *mut whiteout_M3Model,
28544        ) -> usize;
28545        pub fn whiteout_m3_M3Model_resize_fuzzyHitTestObjects(
28546            self_: *mut whiteout_M3Model,
28547            count: usize,
28548        );
28549        pub fn whiteout_m3_M3Model_get_fuzzyHitTestObjects_at(
28550            self_: *mut whiteout_M3Model,
28551            index: usize,
28552        ) -> *mut whiteout_M3HitTestShape;
28553        pub fn whiteout_m3_M3Model_get_attachmentVolumes_count(
28554            self_: *mut whiteout_M3Model,
28555        ) -> usize;
28556        pub fn whiteout_m3_M3Model_resize_attachmentVolumes(
28557            self_: *mut whiteout_M3Model,
28558            count: usize,
28559        );
28560        pub fn whiteout_m3_M3Model_get_attachmentVolumes_at(
28561            self_: *mut whiteout_M3Model,
28562            index: usize,
28563        ) -> *mut whiteout_M3AttachmentVolume;
28564        pub fn whiteout_m3_M3Model_get_attachmentVolumesAddon0_count(
28565            self_: *mut whiteout_M3Model,
28566        ) -> usize;
28567        pub fn whiteout_m3_M3Model_resize_attachmentVolumesAddon0(
28568            self_: *mut whiteout_M3Model,
28569            count: usize,
28570        );
28571        pub fn whiteout_m3_M3Model_get_attachmentVolumesAddon0_data(
28572            self_: *mut whiteout_M3Model,
28573        ) -> *const u16;
28574        pub fn whiteout_m3_M3Model_assign_attachmentVolumesAddon0(
28575            self_: *mut whiteout_M3Model,
28576            data: *const u16,
28577            count: usize,
28578        );
28579        pub fn whiteout_m3_M3Model_get_attachmentVolumesAddon1_count(
28580            self_: *mut whiteout_M3Model,
28581        ) -> usize;
28582        pub fn whiteout_m3_M3Model_resize_attachmentVolumesAddon1(
28583            self_: *mut whiteout_M3Model,
28584            count: usize,
28585        );
28586        pub fn whiteout_m3_M3Model_get_attachmentVolumesAddon1_data(
28587            self_: *mut whiteout_M3Model,
28588        ) -> *const u16;
28589        pub fn whiteout_m3_M3Model_assign_attachmentVolumesAddon1(
28590            self_: *mut whiteout_M3Model,
28591            data: *const u16,
28592            count: usize,
28593        );
28594        pub fn whiteout_m3_M3Model_get_billboardBehaviors_count(
28595            self_: *mut whiteout_M3Model,
28596        ) -> usize;
28597        pub fn whiteout_m3_M3Model_resize_billboardBehaviors(
28598            self_: *mut whiteout_M3Model,
28599            count: usize,
28600        );
28601        pub fn whiteout_m3_M3Model_get_billboardBehaviors_at(
28602            self_: *mut whiteout_M3Model,
28603            index: usize,
28604        ) -> *mut whiteout_M3BillboardBehavior;
28605        pub fn whiteout_m3_M3Model_get_trailingModels_count(self_: *mut whiteout_M3Model) -> usize;
28606        pub fn whiteout_m3_M3Model_resize_trailingModels(
28607            self_: *mut whiteout_M3Model,
28608            count: usize,
28609        );
28610        pub fn whiteout_m3_M3Model_get_trailingModels_at(
28611            self_: *mut whiteout_M3Model,
28612            index: usize,
28613        ) -> *mut whiteout_M3TrailingModel;
28614        pub fn whiteout_m3_M3Model_get_m3aAnimHash(self_: *mut whiteout_M3Model) -> u32;
28615        pub fn whiteout_m3_M3Model_set_m3aAnimHash(self_: *mut whiteout_M3Model, value: u32);
28616        pub fn whiteout_m3_M3Model_get_m3aAnimHashes_count(self_: *mut whiteout_M3Model) -> usize;
28617        pub fn whiteout_m3_M3Model_resize_m3aAnimHashes(self_: *mut whiteout_M3Model, count: usize);
28618        pub fn whiteout_m3_M3Model_get_m3aAnimHashes_data(
28619            self_: *mut whiteout_M3Model,
28620        ) -> *const u32;
28621        pub fn whiteout_m3_M3Model_assign_m3aAnimHashes(
28622            self_: *mut whiteout_M3Model,
28623            data: *const u32,
28624            count: usize,
28625        );
28626        // Parser
28627        pub fn whiteout_m3_M3Parser_new() -> *mut whiteout_M3Parser;
28628        pub fn whiteout_m3_M3Parser_delete(self_: *mut whiteout_M3Parser);
28629        pub fn whiteout_m3_M3Parser_parse(
28630            self_: *mut whiteout_M3Parser,
28631            file_path: *const core::ffi::c_char,
28632        ) -> *mut whiteout_M3Model;
28633        pub fn whiteout_m3_M3Parser_parse_buffer(
28634            self_: *mut whiteout_M3Parser,
28635            buffer: *const u8,
28636            buffer_size: usize,
28637        ) -> *mut whiteout_M3Model;
28638        pub fn whiteout_m3_M3Parser_hasIssues(self_: *mut whiteout_M3Parser) -> i32;
28639        pub fn whiteout_m3_M3Parser_getIssues_count(self_: *mut whiteout_M3Parser) -> usize;
28640        pub fn whiteout_m3_M3Parser_getIssues_at(
28641            self_: *mut whiteout_M3Parser,
28642            index: usize,
28643        ) -> RawCString;
28644        // Writer
28645        pub fn whiteout_m3_M3Writer_new() -> *mut whiteout_M3Writer;
28646        pub fn whiteout_m3_M3Writer_delete(self_: *mut whiteout_M3Writer);
28647        pub fn whiteout_m3_M3Writer_write(
28648            self_: *mut whiteout_M3Writer,
28649            file_path: *const core::ffi::c_char,
28650            model: *mut whiteout_M3Model,
28651        );
28652        pub fn whiteout_m3_M3Writer_write_model(
28653            self_: *mut whiteout_M3Writer,
28654            model: *mut whiteout_M3Model,
28655        ) -> RawBytes;
28656        // AnimRefF32
28657        pub fn whiteout_m3_M3AnimRefF32_new() -> *mut whiteout_M3AnimRefF32;
28658        pub fn whiteout_m3_M3AnimRefF32_delete(self_: *mut whiteout_M3AnimRefF32);
28659        pub fn whiteout_m3_M3AnimRefF32_get_interpType(self_: *mut whiteout_M3AnimRefF32) -> u16;
28660        pub fn whiteout_m3_M3AnimRefF32_set_interpType(
28661            self_: *mut whiteout_M3AnimRefF32,
28662            value: u16,
28663        );
28664        pub fn whiteout_m3_M3AnimRefF32_get_flags(self_: *mut whiteout_M3AnimRefF32) -> u16;
28665        pub fn whiteout_m3_M3AnimRefF32_set_flags(self_: *mut whiteout_M3AnimRefF32, value: u16);
28666        pub fn whiteout_m3_M3AnimRefF32_get_animId(self_: *mut whiteout_M3AnimRefF32) -> u32;
28667        pub fn whiteout_m3_M3AnimRefF32_set_animId(self_: *mut whiteout_M3AnimRefF32, value: u32);
28668        pub fn whiteout_m3_M3AnimRefF32_get_initValue(self_: *mut whiteout_M3AnimRefF32) -> f32;
28669        pub fn whiteout_m3_M3AnimRefF32_set_initValue(
28670            self_: *mut whiteout_M3AnimRefF32,
28671            value: f32,
28672        );
28673        pub fn whiteout_m3_M3AnimRefF32_get_nullValue(self_: *mut whiteout_M3AnimRefF32) -> f32;
28674        pub fn whiteout_m3_M3AnimRefF32_set_nullValue(
28675            self_: *mut whiteout_M3AnimRefF32,
28676            value: f32,
28677        );
28678        pub fn whiteout_m3_M3AnimRefF32_get_unused(self_: *mut whiteout_M3AnimRefF32) -> i32;
28679        pub fn whiteout_m3_M3AnimRefF32_set_unused(self_: *mut whiteout_M3AnimRefF32, value: i32);
28680        // AnimRefVector3f
28681        pub fn whiteout_m3_M3AnimRefVector3f_new() -> *mut whiteout_M3AnimRefVector3f;
28682        pub fn whiteout_m3_M3AnimRefVector3f_delete(self_: *mut whiteout_M3AnimRefVector3f);
28683        pub fn whiteout_m3_M3AnimRefVector3f_get_interpType(
28684            self_: *mut whiteout_M3AnimRefVector3f,
28685        ) -> u16;
28686        pub fn whiteout_m3_M3AnimRefVector3f_set_interpType(
28687            self_: *mut whiteout_M3AnimRefVector3f,
28688            value: u16,
28689        );
28690        pub fn whiteout_m3_M3AnimRefVector3f_get_flags(
28691            self_: *mut whiteout_M3AnimRefVector3f,
28692        ) -> u16;
28693        pub fn whiteout_m3_M3AnimRefVector3f_set_flags(
28694            self_: *mut whiteout_M3AnimRefVector3f,
28695            value: u16,
28696        );
28697        pub fn whiteout_m3_M3AnimRefVector3f_get_animId(
28698            self_: *mut whiteout_M3AnimRefVector3f,
28699        ) -> u32;
28700        pub fn whiteout_m3_M3AnimRefVector3f_set_animId(
28701            self_: *mut whiteout_M3AnimRefVector3f,
28702            value: u32,
28703        );
28704        pub fn whiteout_m3_M3AnimRefVector3f_get_initValue(
28705            self_: *mut whiteout_M3AnimRefVector3f,
28706        ) -> *mut core::ffi::c_void;
28707        pub fn whiteout_m3_M3AnimRefVector3f_set_initValue(
28708            self_: *mut whiteout_M3AnimRefVector3f,
28709            value: *const core::ffi::c_void,
28710        );
28711        pub fn whiteout_m3_M3AnimRefVector3f_get_nullValue(
28712            self_: *mut whiteout_M3AnimRefVector3f,
28713        ) -> *mut core::ffi::c_void;
28714        pub fn whiteout_m3_M3AnimRefVector3f_set_nullValue(
28715            self_: *mut whiteout_M3AnimRefVector3f,
28716            value: *const core::ffi::c_void,
28717        );
28718        pub fn whiteout_m3_M3AnimRefVector3f_get_unused(
28719            self_: *mut whiteout_M3AnimRefVector3f,
28720        ) -> i32;
28721        pub fn whiteout_m3_M3AnimRefVector3f_set_unused(
28722            self_: *mut whiteout_M3AnimRefVector3f,
28723            value: i32,
28724        );
28725        // AnimRefM3ColorBGRA
28726        pub fn whiteout_m3_M3AnimRefM3ColorBGRA_new() -> *mut whiteout_M3AnimRefM3ColorBGRA;
28727        pub fn whiteout_m3_M3AnimRefM3ColorBGRA_delete(self_: *mut whiteout_M3AnimRefM3ColorBGRA);
28728        pub fn whiteout_m3_M3AnimRefM3ColorBGRA_get_interpType(
28729            self_: *mut whiteout_M3AnimRefM3ColorBGRA,
28730        ) -> u16;
28731        pub fn whiteout_m3_M3AnimRefM3ColorBGRA_set_interpType(
28732            self_: *mut whiteout_M3AnimRefM3ColorBGRA,
28733            value: u16,
28734        );
28735        pub fn whiteout_m3_M3AnimRefM3ColorBGRA_get_flags(
28736            self_: *mut whiteout_M3AnimRefM3ColorBGRA,
28737        ) -> u16;
28738        pub fn whiteout_m3_M3AnimRefM3ColorBGRA_set_flags(
28739            self_: *mut whiteout_M3AnimRefM3ColorBGRA,
28740            value: u16,
28741        );
28742        pub fn whiteout_m3_M3AnimRefM3ColorBGRA_get_animId(
28743            self_: *mut whiteout_M3AnimRefM3ColorBGRA,
28744        ) -> u32;
28745        pub fn whiteout_m3_M3AnimRefM3ColorBGRA_set_animId(
28746            self_: *mut whiteout_M3AnimRefM3ColorBGRA,
28747            value: u32,
28748        );
28749        pub fn whiteout_m3_M3AnimRefM3ColorBGRA_get_initValue(
28750            self_: *mut whiteout_M3AnimRefM3ColorBGRA,
28751        ) -> *mut whiteout_M3ColorBGRA;
28752        pub fn whiteout_m3_M3AnimRefM3ColorBGRA_set_initValue(
28753            self_: *mut whiteout_M3AnimRefM3ColorBGRA,
28754            value: *const whiteout_M3ColorBGRA,
28755        );
28756        pub fn whiteout_m3_M3AnimRefM3ColorBGRA_get_nullValue(
28757            self_: *mut whiteout_M3AnimRefM3ColorBGRA,
28758        ) -> *mut whiteout_M3ColorBGRA;
28759        pub fn whiteout_m3_M3AnimRefM3ColorBGRA_set_nullValue(
28760            self_: *mut whiteout_M3AnimRefM3ColorBGRA,
28761            value: *const whiteout_M3ColorBGRA,
28762        );
28763        pub fn whiteout_m3_M3AnimRefM3ColorBGRA_get_unused(
28764            self_: *mut whiteout_M3AnimRefM3ColorBGRA,
28765        ) -> i32;
28766        pub fn whiteout_m3_M3AnimRefM3ColorBGRA_set_unused(
28767            self_: *mut whiteout_M3AnimRefM3ColorBGRA,
28768            value: i32,
28769        );
28770        // AnimRefU16
28771        pub fn whiteout_m3_M3AnimRefU16_new() -> *mut whiteout_M3AnimRefU16;
28772        pub fn whiteout_m3_M3AnimRefU16_delete(self_: *mut whiteout_M3AnimRefU16);
28773        pub fn whiteout_m3_M3AnimRefU16_get_interpType(self_: *mut whiteout_M3AnimRefU16) -> u16;
28774        pub fn whiteout_m3_M3AnimRefU16_set_interpType(
28775            self_: *mut whiteout_M3AnimRefU16,
28776            value: u16,
28777        );
28778        pub fn whiteout_m3_M3AnimRefU16_get_flags(self_: *mut whiteout_M3AnimRefU16) -> u16;
28779        pub fn whiteout_m3_M3AnimRefU16_set_flags(self_: *mut whiteout_M3AnimRefU16, value: u16);
28780        pub fn whiteout_m3_M3AnimRefU16_get_animId(self_: *mut whiteout_M3AnimRefU16) -> u32;
28781        pub fn whiteout_m3_M3AnimRefU16_set_animId(self_: *mut whiteout_M3AnimRefU16, value: u32);
28782        pub fn whiteout_m3_M3AnimRefU16_get_initValue(self_: *mut whiteout_M3AnimRefU16) -> u16;
28783        pub fn whiteout_m3_M3AnimRefU16_set_initValue(
28784            self_: *mut whiteout_M3AnimRefU16,
28785            value: u16,
28786        );
28787        pub fn whiteout_m3_M3AnimRefU16_get_nullValue(self_: *mut whiteout_M3AnimRefU16) -> u16;
28788        pub fn whiteout_m3_M3AnimRefU16_set_nullValue(
28789            self_: *mut whiteout_M3AnimRefU16,
28790            value: u16,
28791        );
28792        pub fn whiteout_m3_M3AnimRefU16_get_unused(self_: *mut whiteout_M3AnimRefU16) -> i32;
28793        pub fn whiteout_m3_M3AnimRefU16_set_unused(self_: *mut whiteout_M3AnimRefU16, value: i32);
28794        // AnimRefVector2f
28795        pub fn whiteout_m3_M3AnimRefVector2f_new() -> *mut whiteout_M3AnimRefVector2f;
28796        pub fn whiteout_m3_M3AnimRefVector2f_delete(self_: *mut whiteout_M3AnimRefVector2f);
28797        pub fn whiteout_m3_M3AnimRefVector2f_get_interpType(
28798            self_: *mut whiteout_M3AnimRefVector2f,
28799        ) -> u16;
28800        pub fn whiteout_m3_M3AnimRefVector2f_set_interpType(
28801            self_: *mut whiteout_M3AnimRefVector2f,
28802            value: u16,
28803        );
28804        pub fn whiteout_m3_M3AnimRefVector2f_get_flags(
28805            self_: *mut whiteout_M3AnimRefVector2f,
28806        ) -> u16;
28807        pub fn whiteout_m3_M3AnimRefVector2f_set_flags(
28808            self_: *mut whiteout_M3AnimRefVector2f,
28809            value: u16,
28810        );
28811        pub fn whiteout_m3_M3AnimRefVector2f_get_animId(
28812            self_: *mut whiteout_M3AnimRefVector2f,
28813        ) -> u32;
28814        pub fn whiteout_m3_M3AnimRefVector2f_set_animId(
28815            self_: *mut whiteout_M3AnimRefVector2f,
28816            value: u32,
28817        );
28818        pub fn whiteout_m3_M3AnimRefVector2f_get_initValue(
28819            self_: *mut whiteout_M3AnimRefVector2f,
28820        ) -> *mut core::ffi::c_void;
28821        pub fn whiteout_m3_M3AnimRefVector2f_set_initValue(
28822            self_: *mut whiteout_M3AnimRefVector2f,
28823            value: *const core::ffi::c_void,
28824        );
28825        pub fn whiteout_m3_M3AnimRefVector2f_get_nullValue(
28826            self_: *mut whiteout_M3AnimRefVector2f,
28827        ) -> *mut core::ffi::c_void;
28828        pub fn whiteout_m3_M3AnimRefVector2f_set_nullValue(
28829            self_: *mut whiteout_M3AnimRefVector2f,
28830            value: *const core::ffi::c_void,
28831        );
28832        pub fn whiteout_m3_M3AnimRefVector2f_get_unused(
28833            self_: *mut whiteout_M3AnimRefVector2f,
28834        ) -> i32;
28835        pub fn whiteout_m3_M3AnimRefVector2f_set_unused(
28836            self_: *mut whiteout_M3AnimRefVector2f,
28837            value: i32,
28838        );
28839        // AnimRefU32
28840        pub fn whiteout_m3_M3AnimRefU32_new() -> *mut whiteout_M3AnimRefU32;
28841        pub fn whiteout_m3_M3AnimRefU32_delete(self_: *mut whiteout_M3AnimRefU32);
28842        pub fn whiteout_m3_M3AnimRefU32_get_interpType(self_: *mut whiteout_M3AnimRefU32) -> u16;
28843        pub fn whiteout_m3_M3AnimRefU32_set_interpType(
28844            self_: *mut whiteout_M3AnimRefU32,
28845            value: u16,
28846        );
28847        pub fn whiteout_m3_M3AnimRefU32_get_flags(self_: *mut whiteout_M3AnimRefU32) -> u16;
28848        pub fn whiteout_m3_M3AnimRefU32_set_flags(self_: *mut whiteout_M3AnimRefU32, value: u16);
28849        pub fn whiteout_m3_M3AnimRefU32_get_animId(self_: *mut whiteout_M3AnimRefU32) -> u32;
28850        pub fn whiteout_m3_M3AnimRefU32_set_animId(self_: *mut whiteout_M3AnimRefU32, value: u32);
28851        pub fn whiteout_m3_M3AnimRefU32_get_initValue(self_: *mut whiteout_M3AnimRefU32) -> u32;
28852        pub fn whiteout_m3_M3AnimRefU32_set_initValue(
28853            self_: *mut whiteout_M3AnimRefU32,
28854            value: u32,
28855        );
28856        pub fn whiteout_m3_M3AnimRefU32_get_nullValue(self_: *mut whiteout_M3AnimRefU32) -> u32;
28857        pub fn whiteout_m3_M3AnimRefU32_set_nullValue(
28858            self_: *mut whiteout_M3AnimRefU32,
28859            value: u32,
28860        );
28861        pub fn whiteout_m3_M3AnimRefU32_get_unused(self_: *mut whiteout_M3AnimRefU32) -> i32;
28862        pub fn whiteout_m3_M3AnimRefU32_set_unused(self_: *mut whiteout_M3AnimRefU32, value: i32);
28863        // AnimRefQuaternion
28864        pub fn whiteout_m3_M3AnimRefQuaternion_new() -> *mut whiteout_M3AnimRefQuaternion;
28865        pub fn whiteout_m3_M3AnimRefQuaternion_delete(self_: *mut whiteout_M3AnimRefQuaternion);
28866        pub fn whiteout_m3_M3AnimRefQuaternion_get_interpType(
28867            self_: *mut whiteout_M3AnimRefQuaternion,
28868        ) -> u16;
28869        pub fn whiteout_m3_M3AnimRefQuaternion_set_interpType(
28870            self_: *mut whiteout_M3AnimRefQuaternion,
28871            value: u16,
28872        );
28873        pub fn whiteout_m3_M3AnimRefQuaternion_get_flags(
28874            self_: *mut whiteout_M3AnimRefQuaternion,
28875        ) -> u16;
28876        pub fn whiteout_m3_M3AnimRefQuaternion_set_flags(
28877            self_: *mut whiteout_M3AnimRefQuaternion,
28878            value: u16,
28879        );
28880        pub fn whiteout_m3_M3AnimRefQuaternion_get_animId(
28881            self_: *mut whiteout_M3AnimRefQuaternion,
28882        ) -> u32;
28883        pub fn whiteout_m3_M3AnimRefQuaternion_set_animId(
28884            self_: *mut whiteout_M3AnimRefQuaternion,
28885            value: u32,
28886        );
28887        pub fn whiteout_m3_M3AnimRefQuaternion_get_initValue(
28888            self_: *mut whiteout_M3AnimRefQuaternion,
28889        ) -> *mut core::ffi::c_void;
28890        pub fn whiteout_m3_M3AnimRefQuaternion_set_initValue(
28891            self_: *mut whiteout_M3AnimRefQuaternion,
28892            value: *const core::ffi::c_void,
28893        );
28894        pub fn whiteout_m3_M3AnimRefQuaternion_get_nullValue(
28895            self_: *mut whiteout_M3AnimRefQuaternion,
28896        ) -> *mut core::ffi::c_void;
28897        pub fn whiteout_m3_M3AnimRefQuaternion_set_nullValue(
28898            self_: *mut whiteout_M3AnimRefQuaternion,
28899            value: *const core::ffi::c_void,
28900        );
28901        pub fn whiteout_m3_M3AnimRefQuaternion_get_unused(
28902            self_: *mut whiteout_M3AnimRefQuaternion,
28903        ) -> i32;
28904        pub fn whiteout_m3_M3AnimRefQuaternion_set_unused(
28905            self_: *mut whiteout_M3AnimRefQuaternion,
28906            value: i32,
28907        );
28908        // AnimRefM3Extent
28909        pub fn whiteout_m3_M3AnimRefM3Extent_new() -> *mut whiteout_M3AnimRefM3Extent;
28910        pub fn whiteout_m3_M3AnimRefM3Extent_delete(self_: *mut whiteout_M3AnimRefM3Extent);
28911        pub fn whiteout_m3_M3AnimRefM3Extent_get_interpType(
28912            self_: *mut whiteout_M3AnimRefM3Extent,
28913        ) -> u16;
28914        pub fn whiteout_m3_M3AnimRefM3Extent_set_interpType(
28915            self_: *mut whiteout_M3AnimRefM3Extent,
28916            value: u16,
28917        );
28918        pub fn whiteout_m3_M3AnimRefM3Extent_get_flags(
28919            self_: *mut whiteout_M3AnimRefM3Extent,
28920        ) -> u16;
28921        pub fn whiteout_m3_M3AnimRefM3Extent_set_flags(
28922            self_: *mut whiteout_M3AnimRefM3Extent,
28923            value: u16,
28924        );
28925        pub fn whiteout_m3_M3AnimRefM3Extent_get_animId(
28926            self_: *mut whiteout_M3AnimRefM3Extent,
28927        ) -> u32;
28928        pub fn whiteout_m3_M3AnimRefM3Extent_set_animId(
28929            self_: *mut whiteout_M3AnimRefM3Extent,
28930            value: u32,
28931        );
28932        pub fn whiteout_m3_M3AnimRefM3Extent_get_initValue(
28933            self_: *mut whiteout_M3AnimRefM3Extent,
28934        ) -> *mut whiteout_M3Extent;
28935        pub fn whiteout_m3_M3AnimRefM3Extent_set_initValue(
28936            self_: *mut whiteout_M3AnimRefM3Extent,
28937            value: *const whiteout_M3Extent,
28938        );
28939        pub fn whiteout_m3_M3AnimRefM3Extent_get_nullValue(
28940            self_: *mut whiteout_M3AnimRefM3Extent,
28941        ) -> *mut whiteout_M3Extent;
28942        pub fn whiteout_m3_M3AnimRefM3Extent_set_nullValue(
28943            self_: *mut whiteout_M3AnimRefM3Extent,
28944            value: *const whiteout_M3Extent,
28945        );
28946        pub fn whiteout_m3_M3AnimRefM3Extent_get_unused(
28947            self_: *mut whiteout_M3AnimRefM3Extent,
28948        ) -> i32;
28949        pub fn whiteout_m3_M3AnimRefM3Extent_set_unused(
28950            self_: *mut whiteout_M3AnimRefM3Extent,
28951            value: i32,
28952        );
28953    }
28954}