Skip to main content

dynamis_abi/
body.rs

1use crate::constant::{
2    BODY_CCD, BODY_KINEMATIC, EDIT_ANGULAR_IMPULSE, EDIT_FORCE, EDIT_FORCE_AT_POINT, EDIT_IMPULSE,
3    EDIT_IMPULSE_AT_POINT, EDIT_PATCH, EDIT_SLEEP, EDIT_TORQUE, EDIT_WAKE, OVERRIDE_SLEEP_ANGULAR,
4    OVERRIDE_SLEEP_LINEAR,
5};
6use crate::{BodyDescriptorRecord, BodyEditRecord, BodyEditRunRecord, BodyStateRecord};
7use bytemuck::Zeroable;
8use dynamis_model::{BodyDesc, MassProperties, PhysicsConfig};
9
10impl BodyStateRecord {
11    pub fn initial(desc: &BodyDesc, body_id: u32, generation: u32) -> Self {
12        Self {
13            position: desc.position,
14            _pad0: 0.0,
15            prev_position: desc.position,
16            _pad1: 0.0,
17            orientation: desc.orientation,
18            velocity: desc.velocity,
19            _pad2: 0.0,
20            angular_velocity: desc.angular_velocity,
21            _pad3: 0.0,
22            force: [0.0; 3],
23            _pad4: 0.0,
24            torque: [0.0; 3],
25            _pad5: 0.0,
26            body_id,
27            generation,
28            sleep_timer: 0.0,
29            sleeping: 0,
30        }
31    }
32}
33
34impl BodyDescriptorRecord {
35    pub fn build(desc: &BodyDesc, mass: MassProperties, config: &PhysicsConfig) -> Self {
36        let mut flags = 0;
37        if desc.kinematic {
38            flags |= BODY_KINEMATIC;
39        }
40        if desc.ccd {
41            flags |= BODY_CCD;
42        }
43        if desc.sleep_velocity.is_some() {
44            flags |= OVERRIDE_SLEEP_LINEAR;
45        }
46        if desc.sleep_angular_velocity.is_some() {
47            flags |= OVERRIDE_SLEEP_ANGULAR;
48        }
49        Self {
50            inverse_mass: if desc.kinematic || desc.mass <= 0.0 {
51                0.0
52            } else {
53                1.0 / desc.mass
54            },
55            linear_damping: desc.linear_damping.unwrap_or(config.damping),
56            angular_damping: desc.angular_damping.unwrap_or(config.angular_damping),
57            gravity_scale: desc.gravity_scale,
58            sleep_velocity: desc.sleep_velocity.unwrap_or(0.0),
59            sleep_angular_velocity: desc.sleep_angular_velocity.unwrap_or(0.0),
60            flags,
61            _pad0: 0,
62            collision_group: desc.collision_group,
63            collision_mask: desc.collision_mask,
64            _pad1: 0,
65            _pad4: 0,
66            com: mass.com,
67            _pad2: 0.0,
68            inertia: mass.inertia,
69            inverse_inertia: mass.inverse_inertia,
70            _pad3: [0.0; 4],
71        }
72    }
73}
74
75impl BodyEditRunRecord {
76    pub fn new(row: usize, first: usize, len: usize) -> Self {
77        Self {
78            row: row as u32,
79            first: first as u32,
80            len: len as u32,
81            _pad: 0,
82        }
83    }
84}
85
86impl BodyEditRecord {
87    fn edit(kind: u32, mask: u32, state: BodyStateRecord) -> Self {
88        Self {
89            kind,
90            mask,
91            _pad0: 0,
92            _pad1: 0,
93            state,
94        }
95    }
96
97    pub fn patch(mask: u32, state: BodyStateRecord) -> Self {
98        Self::edit(EDIT_PATCH, mask, state)
99    }
100
101    pub fn force(force: [f32; 3]) -> Self {
102        let mut state = BodyStateRecord::zeroed();
103        state.force = force;
104        Self::edit(EDIT_FORCE, 0, state)
105    }
106
107    pub fn force_at_point(force: [f32; 3], point: [f32; 3]) -> Self {
108        let mut state = BodyStateRecord::zeroed();
109        state.force = force;
110        state.position = point;
111        Self::edit(EDIT_FORCE_AT_POINT, 0, state)
112    }
113
114    pub fn torque(torque: [f32; 3]) -> Self {
115        let mut state = BodyStateRecord::zeroed();
116        state.torque = torque;
117        Self::edit(EDIT_TORQUE, 0, state)
118    }
119
120    pub fn impulse(impulse: [f32; 3]) -> Self {
121        let mut state = BodyStateRecord::zeroed();
122        state.velocity = impulse;
123        Self::edit(EDIT_IMPULSE, 0, state)
124    }
125
126    pub fn impulse_at_point(impulse: [f32; 3], point: [f32; 3]) -> Self {
127        let mut state = BodyStateRecord::zeroed();
128        state.velocity = impulse;
129        state.position = point;
130        Self::edit(EDIT_IMPULSE_AT_POINT, 0, state)
131    }
132
133    pub fn angular_impulse(impulse: [f32; 3]) -> Self {
134        let mut state = BodyStateRecord::zeroed();
135        state.angular_velocity = impulse;
136        Self::edit(EDIT_ANGULAR_IMPULSE, 0, state)
137    }
138
139    pub fn sleep() -> Self {
140        Self::edit(EDIT_SLEEP, 0, BodyStateRecord::zeroed())
141    }
142
143    pub fn wake() -> Self {
144        Self::edit(EDIT_WAKE, 0, BodyStateRecord::zeroed())
145    }
146}