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}