box3d_rust/recording/
writers.rs1use crate::constants::MAX_SHAPE_CAST_POINTS;
8use crate::distance::ShapeProxy;
9use crate::geometry::MassData;
10use crate::id::{BodyId, JointId, ShapeId, WorldId};
11use crate::math_functions::min_int;
12use crate::recording::buffer::{RecBuffer, SnapReader};
13use crate::types::{
14 default_body_def, default_distance_joint_def, default_explosion_def, default_filter_joint_def,
15 default_joint_def, default_motor_joint_def, default_parallel_joint_def,
16 default_prismatic_joint_def, default_query_filter, default_revolute_joint_def,
17 default_shape_def, default_spherical_joint_def, default_weld_joint_def,
18 default_wheel_joint_def, BodyDef, BodyType, DistanceJointDef, ExplosionDef, FilterJointDef,
19 JointDef, MotionLocks, MotorJointDef, ParallelJointDef, PrismaticJointDef, QueryFilter,
20 RevoluteJointDef, ShapeDef, SphericalJointDef, WeldJointDef, WheelJointDef,
21};
22
23impl RecBuffer {
24 pub fn append_str(&mut self, s: &str) {
26 let bytes = s.as_bytes();
27 let len = bytes.len().min(65534);
28 self.append_u16(len as u16);
29 if len > 0 {
30 self.append(&bytes[..len]);
31 }
32 }
33
34 pub fn append_str_null(&mut self) {
36 self.append_u16(0xFFFF);
37 }
38
39 pub fn append_world_id(&mut self, v: WorldId) {
40 self.append_u32(v.store());
41 }
42
43 pub fn append_body_id(&mut self, v: BodyId) {
44 self.append_u64(v.store());
45 }
46
47 pub fn append_shape_id(&mut self, v: ShapeId) {
48 self.append_u64(v.store());
49 }
50
51 pub fn append_joint_id(&mut self, v: JointId) {
52 self.append_u64(v.store());
53 }
54
55 pub fn append_mass_data(&mut self, v: MassData) {
56 self.append_f32(v.mass);
57 self.append_vec3(v.center);
58 self.append_matrix3(v.inertia);
59 }
60
61 pub fn append_locks(&mut self, v: MotionLocks) {
62 self.append_bool(v.linear_x);
63 self.append_bool(v.linear_y);
64 self.append_bool(v.linear_z);
65 self.append_bool(v.angular_x);
66 self.append_bool(v.angular_y);
67 self.append_bool(v.angular_z);
68 }
69
70 pub fn append_query_filter(&mut self, v: &QueryFilter) {
71 self.append_u64(v.category_bits);
72 self.append_u64(v.mask_bits);
73 }
74
75 pub fn append_shape_proxy(&mut self, v: &ShapeProxy) {
76 let mut count = v.count;
77 if count < 0 {
78 count = 0;
79 }
80 if count > MAX_SHAPE_CAST_POINTS as i32 {
81 count = MAX_SHAPE_CAST_POINTS as i32;
82 }
83 self.append_i32(count);
84 for i in 0..count {
85 self.append_vec3(v.points[i as usize]);
86 }
87 self.append_f32(v.radius);
88 }
89
90 pub fn append_explosion_def(&mut self, v: ExplosionDef) {
91 self.append_u64(v.mask_bits);
92 self.append_pos(v.position);
93 self.append_f32(v.radius);
94 self.append_f32(v.falloff);
95 self.append_f32(v.impulse_per_area);
96 }
97
98 pub fn append_body_def(&mut self, v: &BodyDef) {
100 self.append_i32(v.type_ as i32);
101 self.append_pos(v.position);
102 self.append_quat(v.rotation);
103 self.append_vec3(v.linear_velocity);
104 self.append_vec3(v.angular_velocity);
105 self.append_f32(v.linear_damping);
106 self.append_f32(v.angular_damping);
107 self.append_f32(v.gravity_scale);
108 self.append_f32(v.sleep_threshold);
109 self.append_str(&v.name);
110 self.append_u64(0); self.append_locks(v.motion_locks);
112 self.append_bool(v.enable_sleep);
113 self.append_bool(v.is_awake);
114 self.append_bool(v.is_bullet);
115 self.append_bool(v.is_enabled);
116 self.append_bool(v.allow_fast_rotation);
117 self.append_bool(v.enable_contact_recycling);
118 }
119
120 pub fn append_shape_def(&mut self, v: &ShapeDef) {
122 self.append_str(&v.name);
123 self.append_u64(0); let mat_count = v.materials.len() as i32;
125 self.append_i32(mat_count);
126 for m in &v.materials {
127 self.append_material(*m);
128 }
129 self.append_material(v.base_material);
130 self.append_f32(v.density);
131 self.append_f32(v.explosion_scale);
132 self.append_filter(v.filter);
133 self.append_bool(v.enable_custom_filtering);
134 self.append_bool(v.is_sensor);
135 self.append_bool(v.enable_sensor_events);
136 self.append_bool(v.enable_contact_events);
137 self.append_bool(v.enable_hit_events);
138 self.append_bool(v.enable_pre_solve_events);
139 self.append_bool(v.invoke_contact_creation);
140 self.append_bool(v.update_body_mass);
141 }
142
143 fn append_joint_base(&mut self, base: &JointDef) {
144 self.append_u64(0); self.append_body_id(base.body_id_a);
146 self.append_body_id(base.body_id_b);
147 self.append_transform(base.local_frame_a);
148 self.append_transform(base.local_frame_b);
149 self.append_f32(base.force_threshold);
150 self.append_f32(base.torque_threshold);
151 self.append_f32(base.constraint_hertz);
152 self.append_f32(base.constraint_damping_ratio);
153 self.append_f32(base.draw_scale);
154 self.append_bool(base.collide_connected);
155 }
156
157 pub fn append_parallel_joint_def(&mut self, v: &ParallelJointDef) {
158 self.append_joint_base(&v.base);
159 self.append_f32(v.hertz);
160 self.append_f32(v.damping_ratio);
161 self.append_f32(v.max_torque);
162 }
163
164 pub fn append_distance_joint_def(&mut self, v: &DistanceJointDef) {
165 self.append_joint_base(&v.base);
166 self.append_f32(v.length);
167 self.append_bool(v.enable_spring);
168 self.append_f32(v.lower_spring_force);
169 self.append_f32(v.upper_spring_force);
170 self.append_f32(v.hertz);
171 self.append_f32(v.damping_ratio);
172 self.append_bool(v.enable_limit);
173 self.append_f32(v.min_length);
174 self.append_f32(v.max_length);
175 self.append_bool(v.enable_motor);
176 self.append_f32(v.max_motor_force);
177 self.append_f32(v.motor_speed);
178 }
179
180 pub fn append_filter_joint_def(&mut self, v: &FilterJointDef) {
181 self.append_joint_base(&v.base);
182 }
183
184 pub fn append_motor_joint_def(&mut self, v: &MotorJointDef) {
185 self.append_joint_base(&v.base);
186 self.append_vec3(v.linear_velocity);
187 self.append_f32(v.max_velocity_force);
188 self.append_vec3(v.angular_velocity);
189 self.append_f32(v.max_velocity_torque);
190 self.append_f32(v.linear_hertz);
191 self.append_f32(v.linear_damping_ratio);
192 self.append_f32(v.max_spring_force);
193 self.append_f32(v.angular_hertz);
194 self.append_f32(v.angular_damping_ratio);
195 self.append_f32(v.max_spring_torque);
196 }
197
198 pub fn append_prismatic_joint_def(&mut self, v: &PrismaticJointDef) {
199 self.append_joint_base(&v.base);
200 self.append_bool(v.enable_spring);
201 self.append_f32(v.hertz);
202 self.append_f32(v.damping_ratio);
203 self.append_f32(v.target_translation);
204 self.append_bool(v.enable_limit);
205 self.append_f32(v.lower_translation);
206 self.append_f32(v.upper_translation);
207 self.append_bool(v.enable_motor);
208 self.append_f32(v.max_motor_force);
209 self.append_f32(v.motor_speed);
210 }
211
212 pub fn append_revolute_joint_def(&mut self, v: &RevoluteJointDef) {
213 self.append_joint_base(&v.base);
214 self.append_f32(v.target_angle);
215 self.append_bool(v.enable_spring);
216 self.append_f32(v.hertz);
217 self.append_f32(v.damping_ratio);
218 self.append_bool(v.enable_limit);
219 self.append_f32(v.lower_angle);
220 self.append_f32(v.upper_angle);
221 self.append_bool(v.enable_motor);
222 self.append_f32(v.max_motor_torque);
223 self.append_f32(v.motor_speed);
224 }
225
226 pub fn append_spherical_joint_def(&mut self, v: &SphericalJointDef) {
227 self.append_joint_base(&v.base);
228 self.append_bool(v.enable_spring);
229 self.append_f32(v.hertz);
230 self.append_f32(v.damping_ratio);
231 self.append_quat(v.target_rotation);
232 self.append_bool(v.enable_cone_limit);
233 self.append_f32(v.cone_angle);
234 self.append_bool(v.enable_twist_limit);
235 self.append_f32(v.lower_twist_angle);
236 self.append_f32(v.upper_twist_angle);
237 self.append_bool(v.enable_motor);
238 self.append_f32(v.max_motor_torque);
239 self.append_vec3(v.motor_velocity);
240 }
241
242 pub fn append_weld_joint_def(&mut self, v: &WeldJointDef) {
243 self.append_joint_base(&v.base);
244 self.append_f32(v.linear_hertz);
245 self.append_f32(v.angular_hertz);
246 self.append_f32(v.linear_damping_ratio);
247 self.append_f32(v.angular_damping_ratio);
248 }
249
250 pub fn append_wheel_joint_def(&mut self, v: &WheelJointDef) {
251 self.append_joint_base(&v.base);
252 self.append_bool(v.enable_suspension_spring);
253 self.append_f32(v.suspension_hertz);
254 self.append_f32(v.suspension_damping_ratio);
255 self.append_bool(v.enable_suspension_limit);
256 self.append_f32(v.lower_suspension_limit);
257 self.append_f32(v.upper_suspension_limit);
258 self.append_bool(v.enable_spin_motor);
259 self.append_f32(v.max_spin_torque);
260 self.append_f32(v.spin_speed);
261 self.append_bool(v.enable_steering);
262 self.append_f32(v.steering_hertz);
263 self.append_f32(v.steering_damping_ratio);
264 self.append_f32(v.target_steering_angle);
265 self.append_f32(v.max_steering_torque);
266 self.append_bool(v.enable_steering_limit);
267 self.append_f32(v.lower_steering_limit);
268 self.append_f32(v.upper_steering_limit);
269 }
270}
271
272impl<'a> SnapReader<'a> {
273 pub fn u24(&mut self) -> u32 {
274 let b0 = self.u8() as u32;
275 let b1 = self.u8() as u32;
276 let b2 = self.u8() as u32;
277 b0 | (b1 << 8) | (b2 << 16)
278 }
279
280 pub fn str_owned(&mut self) -> String {
282 let len = self.u16();
283 if len == 0xFFFF {
284 return String::new();
285 }
286 let n = len as usize;
287 if let Some(bytes) = self.bytes(n) {
288 String::from_utf8_lossy(bytes).into_owned()
289 } else {
290 String::new()
291 }
292 }
293
294 pub fn body_str(&mut self) -> String {
295 self.str_owned()
296 }
297
298 pub fn shape_str(&mut self) -> String {
299 self.str_owned()
300 }
301
302 pub fn world_id(&mut self) -> WorldId {
303 WorldId::load(self.u32())
304 }
305
306 pub fn body_id(&mut self) -> BodyId {
307 BodyId::load(self.u64())
308 }
309
310 pub fn shape_id(&mut self) -> ShapeId {
311 ShapeId::load(self.u64())
312 }
313
314 pub fn joint_id(&mut self) -> JointId {
315 JointId::load(self.u64())
316 }
317
318 pub fn mass_data(&mut self) -> MassData {
319 MassData {
320 mass: self.f32(),
321 center: self.vec3(),
322 inertia: self.matrix3(),
323 }
324 }
325
326 pub fn locks(&mut self) -> MotionLocks {
327 MotionLocks {
328 linear_x: self.bool(),
329 linear_y: self.bool(),
330 linear_z: self.bool(),
331 angular_x: self.bool(),
332 angular_y: self.bool(),
333 angular_z: self.bool(),
334 }
335 }
336
337 pub fn query_filter(&mut self) -> QueryFilter {
338 let mut f = default_query_filter();
339 f.category_bits = self.u64();
340 f.mask_bits = self.u64();
341 f
342 }
343
344 pub fn shape_proxy(&mut self) -> ShapeProxy {
345 let mut proxy = ShapeProxy::default();
346 let mut count = self.i32();
347 if count < 0 {
348 count = 0;
349 }
350 count = min_int(count, MAX_SHAPE_CAST_POINTS as i32);
351 proxy.count = count;
352 for i in 0..count {
353 proxy.points[i as usize] = self.vec3();
354 }
355 proxy.radius = self.f32();
356 proxy
357 }
358
359 pub fn explosion_def(&mut self) -> ExplosionDef {
360 let mut d = default_explosion_def();
361 d.mask_bits = self.u64();
362 d.position = self.pos();
363 d.radius = self.f32();
364 d.falloff = self.f32();
365 d.impulse_per_area = self.f32();
366 d
367 }
368
369 pub fn body_def(&mut self) -> BodyDef {
370 let mut d = default_body_def();
371 d.type_ = match self.i32() {
372 1 => BodyType::Kinematic,
373 2 => BodyType::Dynamic,
374 _ => BodyType::Static,
375 };
376 d.position = self.pos();
377 d.rotation = self.quat();
378 d.linear_velocity = self.vec3();
379 d.angular_velocity = self.vec3();
380 d.linear_damping = self.f32();
381 d.angular_damping = self.f32();
382 d.gravity_scale = self.f32();
383 d.sleep_threshold = self.f32();
384 d.name = self.str_owned();
385 let _user = self.u64();
386 d.motion_locks = self.locks();
387 d.enable_sleep = self.bool();
388 d.is_awake = self.bool();
389 d.is_bullet = self.bool();
390 d.is_enabled = self.bool();
391 d.allow_fast_rotation = self.bool();
392 d.enable_contact_recycling = self.bool();
393 d
394 }
395
396 pub fn shape_def(&mut self) -> ShapeDef {
397 let mut d = default_shape_def();
398 d.name = self.str_owned();
399 let _user = self.u64();
400 let mat_count = self.i32();
401 d.materials.clear();
402 if mat_count > 0 && self.ok {
403 d.materials.reserve(mat_count as usize);
404 for _ in 0..mat_count {
405 d.materials.push(self.material());
406 }
407 }
408 d.base_material = self.material();
409 d.density = self.f32();
410 d.explosion_scale = self.f32();
411 d.filter = self.filter();
412 d.enable_custom_filtering = self.bool();
413 d.is_sensor = self.bool();
414 d.enable_sensor_events = self.bool();
415 d.enable_contact_events = self.bool();
416 d.enable_hit_events = self.bool();
417 d.enable_pre_solve_events = self.bool();
418 d.invoke_contact_creation = self.bool();
419 d.update_body_mass = self.bool();
420 d
421 }
422
423 fn joint_base(&mut self) -> JointDef {
424 let mut base = default_joint_def();
425 let _user = self.u64();
426 base.body_id_a = self.body_id();
427 base.body_id_b = self.body_id();
428 base.local_frame_a = self.transform();
429 base.local_frame_b = self.transform();
430 base.force_threshold = self.f32();
431 base.torque_threshold = self.f32();
432 base.constraint_hertz = self.f32();
433 base.constraint_damping_ratio = self.f32();
434 base.draw_scale = self.f32();
435 base.collide_connected = self.bool();
436 base
437 }
438
439 pub fn parallel_joint_def(&mut self) -> ParallelJointDef {
440 let mut d = default_parallel_joint_def();
441 d.base = self.joint_base();
442 d.hertz = self.f32();
443 d.damping_ratio = self.f32();
444 d.max_torque = self.f32();
445 d
446 }
447
448 pub fn distance_joint_def(&mut self) -> DistanceJointDef {
449 let mut d = default_distance_joint_def();
450 d.base = self.joint_base();
451 d.length = self.f32();
452 d.enable_spring = self.bool();
453 d.lower_spring_force = self.f32();
454 d.upper_spring_force = self.f32();
455 d.hertz = self.f32();
456 d.damping_ratio = self.f32();
457 d.enable_limit = self.bool();
458 d.min_length = self.f32();
459 d.max_length = self.f32();
460 d.enable_motor = self.bool();
461 d.max_motor_force = self.f32();
462 d.motor_speed = self.f32();
463 d
464 }
465
466 pub fn filter_joint_def(&mut self) -> FilterJointDef {
467 let mut d = default_filter_joint_def();
468 d.base = self.joint_base();
469 d
470 }
471
472 pub fn motor_joint_def(&mut self) -> MotorJointDef {
473 let mut d = default_motor_joint_def();
474 d.base = self.joint_base();
475 d.linear_velocity = self.vec3();
476 d.max_velocity_force = self.f32();
477 d.angular_velocity = self.vec3();
478 d.max_velocity_torque = self.f32();
479 d.linear_hertz = self.f32();
480 d.linear_damping_ratio = self.f32();
481 d.max_spring_force = self.f32();
482 d.angular_hertz = self.f32();
483 d.angular_damping_ratio = self.f32();
484 d.max_spring_torque = self.f32();
485 d
486 }
487
488 pub fn prismatic_joint_def(&mut self) -> PrismaticJointDef {
489 let mut d = default_prismatic_joint_def();
490 d.base = self.joint_base();
491 d.enable_spring = self.bool();
492 d.hertz = self.f32();
493 d.damping_ratio = self.f32();
494 d.target_translation = self.f32();
495 d.enable_limit = self.bool();
496 d.lower_translation = self.f32();
497 d.upper_translation = self.f32();
498 d.enable_motor = self.bool();
499 d.max_motor_force = self.f32();
500 d.motor_speed = self.f32();
501 d
502 }
503
504 pub fn revolute_joint_def(&mut self) -> RevoluteJointDef {
505 let mut d = default_revolute_joint_def();
506 d.base = self.joint_base();
507 d.target_angle = self.f32();
508 d.enable_spring = self.bool();
509 d.hertz = self.f32();
510 d.damping_ratio = self.f32();
511 d.enable_limit = self.bool();
512 d.lower_angle = self.f32();
513 d.upper_angle = self.f32();
514 d.enable_motor = self.bool();
515 d.max_motor_torque = self.f32();
516 d.motor_speed = self.f32();
517 d
518 }
519
520 pub fn spherical_joint_def(&mut self) -> SphericalJointDef {
521 let mut d = default_spherical_joint_def();
522 d.base = self.joint_base();
523 d.enable_spring = self.bool();
524 d.hertz = self.f32();
525 d.damping_ratio = self.f32();
526 d.target_rotation = self.quat();
527 d.enable_cone_limit = self.bool();
528 d.cone_angle = self.f32();
529 d.enable_twist_limit = self.bool();
530 d.lower_twist_angle = self.f32();
531 d.upper_twist_angle = self.f32();
532 d.enable_motor = self.bool();
533 d.max_motor_torque = self.f32();
534 d.motor_velocity = self.vec3();
535 d
536 }
537
538 pub fn weld_joint_def(&mut self) -> WeldJointDef {
539 let mut d = default_weld_joint_def();
540 d.base = self.joint_base();
541 d.linear_hertz = self.f32();
542 d.angular_hertz = self.f32();
543 d.linear_damping_ratio = self.f32();
544 d.angular_damping_ratio = self.f32();
545 d
546 }
547
548 pub fn wheel_joint_def(&mut self) -> WheelJointDef {
549 let mut d = default_wheel_joint_def();
550 d.base = self.joint_base();
551 d.enable_suspension_spring = self.bool();
552 d.suspension_hertz = self.f32();
553 d.suspension_damping_ratio = self.f32();
554 d.enable_suspension_limit = self.bool();
555 d.lower_suspension_limit = self.f32();
556 d.upper_suspension_limit = self.f32();
557 d.enable_spin_motor = self.bool();
558 d.max_spin_torque = self.f32();
559 d.spin_speed = self.f32();
560 d.enable_steering = self.bool();
561 d.steering_hertz = self.f32();
562 d.steering_damping_ratio = self.f32();
563 d.target_steering_angle = self.f32();
564 d.max_steering_torque = self.f32();
565 d.enable_steering_limit = self.bool();
566 d.lower_steering_limit = self.f32();
567 d.upper_steering_limit = self.f32();
568 d
569 }
570}