1#![allow(dead_code)]
12
13mod create;
14pub use create::create_human;
15
16use box2d_rust::body::{body_get_local_point, destroy_body};
17use box2d_rust::id::{BodyId, JointId};
18use box2d_rust::joint::{create_revolute_joint, destroy_joint};
19use box2d_rust::math_functions::{Pos, Rot};
20use box2d_rust::types::default_revolute_joint_def;
21use box2d_rust::world::World;
22
23pub const BONE_HIP: usize = 0;
25pub const BONE_TORSO: usize = 1;
26pub const BONE_HEAD: usize = 2;
27pub const BONE_UPPER_LEFT_LEG: usize = 3;
28pub const BONE_LOWER_LEFT_LEG: usize = 4;
29pub const BONE_UPPER_RIGHT_LEG: usize = 5;
30pub const BONE_LOWER_RIGHT_LEG: usize = 6;
31pub const BONE_UPPER_LEFT_ARM: usize = 7;
32pub const BONE_LOWER_LEFT_ARM: usize = 8;
33pub const BONE_UPPER_RIGHT_ARM: usize = 9;
34pub const BONE_LOWER_RIGHT_ARM: usize = 10;
35pub const BONE_COUNT: usize = 11;
36
37#[derive(Clone, Copy)]
39pub struct Bone {
40 pub body_id: BodyId,
41 pub joint_id: JointId,
42 pub friction_scale: f32,
43 pub parent_index: i32,
44}
45
46impl Default for Bone {
47 fn default() -> Self {
48 Bone {
49 body_id: BodyId::default(),
50 joint_id: JointId::default(),
51 friction_scale: 1.0,
52 parent_index: -1,
53 }
54 }
55}
56
57#[derive(Clone)]
59pub struct Human {
60 pub bones: [Bone; BONE_COUNT],
61 pub friction_torque: f32,
62 pub original_scale: f32,
63 pub scale: f32,
64 pub is_spawned: bool,
65}
66
67impl Default for Human {
68 fn default() -> Self {
69 Human {
70 bones: [Bone::default(); BONE_COUNT],
71 friction_torque: 0.0,
72 original_scale: 0.0,
73 scale: 0.0,
74 is_spawned: false,
75 }
76 }
77}
78
79#[allow(clippy::too_many_arguments)]
83pub(crate) fn attach_revolute_joint(
84 world: &mut World,
85 parent_body: BodyId,
86 child_body: BodyId,
87 pivot: Pos,
88 lower_angle: f32,
89 upper_angle: f32,
90 enable_limit: bool,
91 enable_motor: bool,
92 max_motor_torque: f32,
93 enable_spring: bool,
94 hertz: f32,
95 damping_ratio: f32,
96 draw_scale: f32,
97 frame_a_rotation: Option<Rot>,
98) -> JointId {
99 let mut joint_def = default_revolute_joint_def();
100 joint_def.base.body_id_a = parent_body;
101 joint_def.base.body_id_b = child_body;
102 joint_def.base.local_frame_a.p = body_get_local_point(world, parent_body, pivot);
103 if let Some(q) = frame_a_rotation {
104 joint_def.base.local_frame_a.q = q;
105 }
106 joint_def.base.local_frame_b.p = body_get_local_point(world, child_body, pivot);
107 joint_def.enable_limit = enable_limit;
108 joint_def.lower_angle = lower_angle;
109 joint_def.upper_angle = upper_angle;
110 joint_def.enable_motor = enable_motor;
111 joint_def.max_motor_torque = max_motor_torque;
112 joint_def.enable_spring = enable_spring;
113 joint_def.hertz = hertz;
114 joint_def.damping_ratio = damping_ratio;
115 joint_def.base.draw_scale = draw_scale;
116 create_revolute_joint(world, &joint_def)
117}
118
119pub fn destroy_human(world: &mut World, human: &mut Human) {
121 debug_assert!(human.is_spawned);
122
123 for i in 0..BONE_COUNT {
124 if human.bones[i].joint_id.is_null() {
125 continue;
126 }
127
128 destroy_joint(world, human.bones[i].joint_id, false);
129 human.bones[i].joint_id = JointId::default();
130 }
131
132 for i in 0..BONE_COUNT {
133 if human.bones[i].body_id.is_null() {
134 continue;
135 }
136
137 destroy_body(world, human.bones[i].body_id);
138 human.bones[i].body_id = BodyId::default();
139 }
140
141 human.is_spawned = false;
142}