1use super::types::{
7 BoneId, Human, BONE_COUNT, COLOR_DODGER_BLUE, COLOR_LIGHT_YELLOW, COLOR_MEDIUM_TURQUOISE,
8 COLOR_NAVAJO_WHITE, COLOR_PERU, COLOR_TAN, FILTER_JOINT_COUNT,
9};
10use crate::body::create_body;
11use crate::geometry::Capsule;
12use crate::id::{NULL_BODY_ID, NULL_JOINT_ID};
13use crate::joint::{create_filter_joint, create_revolute_joint, create_spherical_joint, JointType};
14use crate::math_functions::{
15 normalize_quat, offset_pos, Pos, Quat, Transform, Vec2, Vec3, DEG_TO_RAD,
16};
17use crate::shape::create_capsule_shape;
18use crate::types::{
19 default_body_def, default_filter_joint_def, default_revolute_joint_def, default_shape_def,
20 default_spherical_joint_def, BodyType,
21};
22use crate::world::World;
23
24#[inline]
26fn xf(px: f32, py: f32, pz: f32, qx: f32, qy: f32, qz: f32, qs: f32) -> Transform {
27 Transform {
28 p: Vec3 {
29 x: px,
30 y: py,
31 z: pz,
32 },
33 q: Quat {
34 v: Vec3 {
35 x: qx,
36 y: qy,
37 z: qz,
38 },
39 s: qs,
40 },
41 }
42}
43
44pub fn create_human(
47 human: &mut Human,
48 world: &mut World,
49 position: Pos,
50 friction_torque: f32,
51 hertz: f32,
52 damping_ratio: f32,
53 group_index: i32,
54 user_data: u64,
55 colorize: bool,
56) {
57 debug_assert!(!human.is_spawned);
58
59 for i in 0..BONE_COUNT {
60 human.bones[i].body_id = NULL_BODY_ID;
61 human.bones[i].anchor_id = NULL_BODY_ID;
62 human.bones[i].joint_id = NULL_JOINT_ID;
63 human.bones[i].joint_friction = 1.0;
64 human.bones[i].parent_index = -1;
65 }
66
67 for i in 0..FILTER_JOINT_COUNT {
68 human.filter_joints[i] = NULL_JOINT_ID;
69 }
70
71 human.friction_torque = friction_torque;
72
73 let mut body_def = default_body_def();
74 body_def.type_ = BodyType::Dynamic;
75 body_def.user_data = user_data;
76
77 let mut shape_def = default_shape_def();
78 shape_def.base_material.rolling_resistance = 0.2;
79
80 let shirt_color = COLOR_MEDIUM_TURQUOISE;
81 let pant_color = COLOR_DODGER_BLUE;
82 let skin_colors = [
83 COLOR_NAVAJO_WHITE,
84 COLOR_LIGHT_YELLOW,
85 COLOR_PERU,
86 COLOR_TAN,
87 ];
88 let skin_color = skin_colors[(group_index.rem_euclid(4)) as usize];
89
90 {
92 let bone = &mut human.bones[BoneId::Pelvis as usize];
93 bone.parent_index = -1;
94 body_def.name = "pelvis".to_string();
95 bone.reference_frame = xf(0.0, 0.932087, -0.051708, 0.739169, 0.0, 0.0, 0.673520);
96 body_def.rotation = bone.reference_frame.q;
97 body_def.position = offset_pos(position, bone.reference_frame.p);
98 bone.body_id = create_body(world, &body_def);
99
100 let capsule = Capsule {
101 center1: Vec3 {
102 x: 0.07,
103 y: 0.0,
104 z: -0.08,
105 },
106 center2: Vec3 {
107 x: -0.07,
108 y: 0.0,
109 z: -0.08,
110 },
111 radius: 0.13,
112 };
113 shape_def.filter.group_index = 0;
114 shape_def.base_material.custom_color = if colorize { pant_color } else { 0 };
115 create_capsule_shape(world, bone.body_id, &shape_def, &capsule);
116 }
117
118 {
120 let bone = &mut human.bones[BoneId::Spine01 as usize];
121 bone.parent_index = BoneId::Pelvis as i32;
122 body_def.name = "spine_01".to_string();
123 bone.reference_frame = xf(0.0, 1.113505, -0.03481, 0.739973, 0.0, 0.0, 0.672637);
124 body_def.rotation = bone.reference_frame.q;
125 body_def.position = offset_pos(position, bone.reference_frame.p);
126 bone.body_id = create_body(world, &body_def);
127 body_def.type_ = BodyType::Dynamic;
128
129 let capsule = Capsule {
130 center1: Vec3 {
131 x: 0.06,
132 y: -0.0,
133 z: -0.052264,
134 },
135 center2: Vec3 {
136 x: -0.06,
137 y: 0.0,
138 z: -0.052264,
139 },
140 radius: 0.12,
141 };
142 shape_def.filter.group_index = -group_index;
143 shape_def.base_material.custom_color = if colorize { shirt_color } else { 0 };
144 create_capsule_shape(world, bone.body_id, &shape_def, &capsule);
145
146 bone.joint_type = JointType::Spherical;
147 bone.local_frame_a = xf(0.0, 0.0, -0.182204, -0.999999, 0.0, -0.0, 0.001194);
148 bone.local_frame_b = xf(0.0, 0.0, -0.007736, -1.0, 0.0, -0.0, 0.0);
149 bone.swing_limit = 25.0 * DEG_TO_RAD;
150 bone.twist_limit = Vec2 {
151 x: -15.0 * DEG_TO_RAD,
152 y: 15.0 * DEG_TO_RAD,
153 };
154 }
155
156 {
158 let bone = &mut human.bones[BoneId::Spine02 as usize];
159 bone.parent_index = BoneId::Spine01 as i32;
160 bone.reference_frame = xf(0.0, 1.194336, -0.027087, 0.703611, 0.0, 0.0, 0.710586);
161 body_def.rotation = bone.reference_frame.q;
162 body_def.position = offset_pos(position, bone.reference_frame.p);
163 bone.body_id = create_body(world, &body_def);
164
165 let capsule = Capsule {
166 center1: Vec3 {
167 x: 0.08,
168 y: -0.015133,
169 z: -0.091801,
170 },
171 center2: Vec3 {
172 x: -0.08,
173 y: -0.015133,
174 z: -0.091801,
175 },
176 radius: 0.10,
177 };
178 shape_def.filter.group_index = 0;
179 shape_def.base_material.custom_color = if colorize { shirt_color } else { 0 };
180 create_capsule_shape(world, bone.body_id, &shape_def, &capsule);
181
182 bone.joint_type = JointType::Spherical;
183 bone.local_frame_a = xf(0.0, -0.0, -0.088935, -0.998619, -0.0, 0.0, -0.052540);
184 bone.local_frame_b = xf(-0.0, 0.0, -0.008199, -1.0, 0.0, -0.0, 0.0);
185 bone.swing_limit = 25.0 * DEG_TO_RAD;
186 bone.twist_limit = Vec2 {
187 x: -15.0 * DEG_TO_RAD,
188 y: 15.0 * DEG_TO_RAD,
189 };
190 }
191
192 {
194 let bone = &mut human.bones[BoneId::Spine03 as usize];
195 bone.parent_index = BoneId::Spine02 as i32;
196 body_def.name = "spine_03".to_string();
197 bone.reference_frame = xf(
198 -0.0, 1.31043, -0.028232, 0.669856, 0.000001, -0.000001, 0.742491,
199 );
200 body_def.rotation = bone.reference_frame.q;
201 body_def.position = offset_pos(position, bone.reference_frame.p);
202 bone.body_id = create_body(world, &body_def);
203
204 let capsule = Capsule {
205 center1: Vec3 {
206 x: 0.11,
207 y: -0.039753,
208 z: -0.13,
209 },
210 center2: Vec3 {
211 x: -0.11,
212 y: -0.039753,
213 z: -0.13,
214 },
215 radius: 0.145,
216 };
217 shape_def.filter.group_index = 0;
218 shape_def.base_material.custom_color = if colorize { shirt_color } else { 0 };
219 create_capsule_shape(world, bone.body_id, &shape_def, &capsule);
220
221 bone.joint_type = JointType::Spherical;
222 bone.local_frame_a = xf(
223 -0.0, 0.0, -0.124298, -0.998921, 0.000001, -0.000001, -0.046434,
224 );
225 bone.local_frame_b = xf(0.0, 0.0, 0.0, -1.0, 0.0, -0.000001, 0.0);
226 bone.swing_limit = 15.0 * DEG_TO_RAD;
227 bone.twist_limit = Vec2 {
228 x: -10.0 * DEG_TO_RAD,
229 y: 10.0 * DEG_TO_RAD,
230 };
231 }
232
233 {
235 let bone = &mut human.bones[BoneId::Neck as usize];
236 bone.parent_index = BoneId::Spine03 as i32;
237 body_def.name = "neck".to_string();
238 bone.reference_frame = xf(0.0, 1.575582, -0.055837, 0.879922, 0.0, 0.0, 0.475118);
239 body_def.rotation = bone.reference_frame.q;
240 body_def.position = offset_pos(position, bone.reference_frame.p);
241 bone.body_id = create_body(world, &body_def);
242
243 let capsule = Capsule {
244 center1: Vec3 {
245 x: -0.000001,
246 y: -0.0,
247 z: -0.02,
248 },
249 center2: Vec3 {
250 x: 0.0,
251 y: -0.005,
252 z: -0.08,
253 },
254 radius: 0.07,
255 };
256 shape_def.filter.group_index = 0;
257 shape_def.base_material.custom_color = if colorize { skin_color } else { 0 };
258 create_capsule_shape(world, bone.body_id, &shape_def, &capsule);
259
260 bone.joint_type = JointType::Spherical;
261 bone.local_frame_a = xf(
262 0.000001, -0.000259, -0.266585, -0.942192, -0.000001, 0.0, 0.335074,
263 );
264 bone.local_frame_b = xf(0.0, 0.0, 0.0, -1.0, 0.0, -0.000001, 0.0);
265 bone.swing_limit = 45.0 * DEG_TO_RAD;
266 bone.twist_limit = Vec2 {
267 x: -15.0 * DEG_TO_RAD,
268 y: 15.0 * DEG_TO_RAD,
269 };
270 bone.joint_friction = 0.8;
271 }
272
273 {
275 let bone = &mut human.bones[BoneId::Head as usize];
276 bone.parent_index = BoneId::Neck as i32;
277 body_def.name = "head".to_string();
278 bone.reference_frame = xf(0.0, 1.653348, -0.003241, 0.750288, 0.0, 0.0, 0.661111);
279 body_def.rotation = bone.reference_frame.q;
280 body_def.position = offset_pos(position, bone.reference_frame.p);
281 bone.body_id = create_body(world, &body_def);
282
283 let capsule = Capsule {
284 center1: Vec3 {
285 x: -0.000001,
286 y: 0.016892,
287 z: -0.05869,
288 },
289 center2: Vec3 {
290 x: 0.0,
291 y: -0.003629,
292 z: -0.115072,
293 },
294 radius: 0.0975,
295 };
296 shape_def.filter.group_index = 0;
297 shape_def.base_material.custom_color = if colorize { skin_color } else { 0 };
298 create_capsule_shape(world, bone.body_id, &shape_def, &capsule);
299
300 bone.joint_type = JointType::Spherical;
301 bone.local_frame_a = xf(0.0, 0.001321, -0.093873, -0.974301, -0.0, -0.0, -0.225251);
302 bone.local_frame_b = xf(0.0, 0.001268, -0.005104, -1.0, 0.0, -0.0, 0.0);
303 bone.swing_limit = 15.0 * DEG_TO_RAD;
304 bone.twist_limit = Vec2 {
305 x: -15.0 * DEG_TO_RAD,
306 y: 15.0 * DEG_TO_RAD,
307 };
308 bone.joint_friction = 0.4;
309 }
310
311 create_legs_and_arms(
312 human,
313 world,
314 &mut body_def,
315 &mut shape_def,
316 position,
317 group_index,
318 colorize,
319 pant_color,
320 shirt_color,
321 skin_color,
322 );
323 create_bone_joints(human, world, friction_torque, hertz, damping_ratio);
324
325 let mut filter_def = default_filter_joint_def();
326 filter_def.base.body_id_a = human.bones[BoneId::ThighL as usize].body_id;
327 filter_def.base.body_id_b = human.bones[BoneId::ThighR as usize].body_id;
328 human.filter_joints[0] = create_filter_joint(world, &filter_def);
329 human.filter_joint_count = 1;
330
331 human.is_spawned = true;
332}
333
334#[allow(clippy::too_many_arguments)]
335fn create_legs_and_arms(
336 human: &mut Human,
337 world: &mut World,
338 body_def: &mut crate::types::BodyDef,
339 shape_def: &mut crate::types::ShapeDef,
340 position: Pos,
341 group_index: i32,
342 colorize: bool,
343 pant_color: u32,
344 shirt_color: u32,
345 skin_color: u32,
346) {
347 {
349 let bone = &mut human.bones[BoneId::ThighL as usize];
350 bone.parent_index = BoneId::Pelvis as i32;
351 body_def.name = "thigh_l".to_string();
352 bone.reference_frame = xf(
353 0.090416, 0.986104, -0.035090, -0.703287, -0.070715, 0.053866, 0.705327,
354 );
355 body_def.rotation = bone.reference_frame.q;
356 body_def.position = offset_pos(position, bone.reference_frame.p);
357 bone.body_id = create_body(world, body_def);
358
359 let capsule = Capsule {
360 center1: Vec3 {
361 x: 0.023719,
362 y: 0.006008,
363 z: -0.039068,
364 },
365 center2: Vec3 {
366 x: -0.064492,
367 y: -0.004664,
368 z: -0.424718,
369 },
370 radius: 0.09,
371 };
372 shape_def.filter.group_index = -group_index;
373 shape_def.base_material.custom_color = if colorize { pant_color } else { 0 };
374 create_capsule_shape(world, bone.body_id, shape_def, &capsule);
375
376 bone.joint_type = JointType::Spherical;
377 bone.local_frame_a = xf(
378 0.05, 0.011537, -0.055325, -0.714896, -0.022305, -0.698361, -0.026790,
379 );
380 bone.local_frame_b = xf(0.0, 0.0, 0.0, -0.002064, 0.758987, 0.017046, 0.650880);
381 bone.swing_limit = 10.0 * DEG_TO_RAD;
382 bone.twist_limit = Vec2 {
383 x: -60.0 * DEG_TO_RAD,
384 y: 40.0 * DEG_TO_RAD,
385 };
386 }
387
388 {
390 let bone = &mut human.bones[BoneId::CalfL as usize];
391 bone.parent_index = BoneId::ThighL as i32;
392 body_def.name = "calf_l".to_string();
393 bone.reference_frame = xf(
394 0.101198, 0.527027, -0.037374, -0.653328, -0.066860, 0.058582, 0.751838,
395 );
396 body_def.rotation = bone.reference_frame.q;
397 body_def.position = offset_pos(position, bone.reference_frame.p);
398 bone.body_id = create_body(world, body_def);
399
400 let capsule = Capsule {
401 center1: Vec3 {
402 x: 0.001778,
403 y: 0.0,
404 z: 0.009841,
405 },
406 center2: Vec3 {
407 x: -0.078577,
408 y: 0.014707,
409 z: -0.41816,
410 },
411 radius: 0.075,
412 };
413 shape_def.filter.group_index = 0;
414 shape_def.base_material.custom_color = if colorize { pant_color } else { 0 };
415 create_capsule_shape(world, bone.body_id, shape_def, &capsule);
416
417 bone.joint_type = JointType::Revolute;
418 bone.local_frame_a = xf(
419 -0.069989, 0.000253, -0.453844, -0.000677, 0.760087, 0.105674, 0.641171,
420 );
421 bone.local_frame_b = xf(0.0, 0.0, 0.0, -0.044589, 0.765540, 0.053368, 0.639619);
422 bone.twist_limit = Vec2 {
423 x: -5.0 * DEG_TO_RAD,
424 y: 45.0 * DEG_TO_RAD,
425 };
426 }
427
428 {
430 let bone = &mut human.bones[BoneId::ThighR as usize];
431 bone.parent_index = BoneId::Pelvis as i32;
432 body_def.name = "thigh_r".to_string();
433 bone.reference_frame = xf(
434 -0.090416, 0.986104, -0.03509, -0.703287, 0.070715, -0.053865, 0.705326,
435 );
436 body_def.rotation = bone.reference_frame.q;
437 body_def.position = offset_pos(position, bone.reference_frame.p);
438 bone.body_id = create_body(world, body_def);
439
440 let capsule = Capsule {
441 center1: Vec3 {
442 x: -0.023719,
443 y: 0.006008,
444 z: -0.039068,
445 },
446 center2: Vec3 {
447 x: 0.064492,
448 y: -0.004664,
449 z: -0.424718,
450 },
451 radius: 0.09,
452 };
453 shape_def.filter.group_index = -group_index;
454 shape_def.base_material.custom_color = if colorize { pant_color } else { 0 };
455 create_capsule_shape(world, bone.body_id, shape_def, &capsule);
456
457 bone.joint_type = JointType::Spherical;
458 bone.local_frame_a = xf(
459 -0.05, 0.011537, -0.055326, -0.039089, -0.714094, 0.043177, 0.697623,
460 );
461 bone.local_frame_b = xf(0.0, 0.0, 0.0, 0.758805, -0.019886, -0.651012, -0.001759);
462 bone.swing_limit = 10.0 * DEG_TO_RAD;
463 bone.twist_limit = Vec2 {
464 x: -30.0 * DEG_TO_RAD,
465 y: 60.0 * DEG_TO_RAD,
466 };
467 }
468
469 {
471 let bone = &mut human.bones[BoneId::CalfR as usize];
472 bone.parent_index = BoneId::ThighR as i32;
473 body_def.name = "calf_r".to_string();
474 bone.reference_frame = xf(
475 -0.101198, 0.527027, -0.037373, -0.653327, 0.06686, -0.058582, 0.751839,
476 );
477 body_def.rotation = bone.reference_frame.q;
478 body_def.position = offset_pos(position, bone.reference_frame.p);
479 bone.body_id = create_body(world, body_def);
480
481 let capsule = Capsule {
482 center1: Vec3 {
483 x: -0.001820,
484 y: 0.0,
485 z: 0.010071,
486 },
487 center2: Vec3 {
488 x: 0.077883,
489 y: 0.014825,
490 z: -0.418047,
491 },
492 radius: 0.075,
493 };
494 shape_def.filter.group_index = 0;
495 shape_def.base_material.custom_color = if colorize { pant_color } else { 0 };
496 create_capsule_shape(world, bone.body_id, shape_def, &capsule);
497
498 bone.joint_type = JointType::Revolute;
499 bone.local_frame_a = xf(
500 0.069988, 0.000253, -0.453844, 0.760086, -0.000675, -0.641171, -0.105676,
501 );
502 bone.local_frame_b = xf(0.0, 0.0, 0.0, 0.765540, -0.044589, -0.639619, -0.053368);
503 bone.twist_limit = Vec2 {
504 x: -45.0 * DEG_TO_RAD,
505 y: 5.0 * DEG_TO_RAD,
506 };
507 }
508
509 {
511 let bone = &mut human.bones[BoneId::UpperArmL as usize];
512 bone.parent_index = BoneId::Spine03 as i32;
513 body_def.name = "upper_arm_l".to_string();
514 bone.reference_frame = xf(
515 0.20378, 1.484275, -0.115897, 0.143082, 0.695980, -0.690130, 0.13733,
516 );
517 body_def.rotation = bone.reference_frame.q;
518 body_def.position = offset_pos(position, bone.reference_frame.p);
519 bone.body_id = create_body(world, body_def);
520
521 let capsule = Capsule {
522 center1: Vec3 {
523 x: 0.0,
524 y: 0.0,
525 z: 0.0,
526 },
527 center2: Vec3 {
528 x: -0.091118,
529 y: 0.037775,
530 z: 0.229719,
531 },
532 radius: 0.075,
533 };
534 shape_def.filter.group_index = 0;
535 shape_def.base_material.custom_color = if colorize { shirt_color } else { 0 };
536 create_capsule_shape(world, bone.body_id, shape_def, &capsule);
537
538 bone.joint_type = JointType::Spherical;
539 bone.local_frame_a = xf(
540 0.203780, -0.069369, -0.181921, -0.278486, 0.445600, -0.097014, 0.845266,
541 );
542 bone.local_frame_b = xf(0.0, 0.0, 0.0, -0.201396, -0.001586, 0.901850, 0.382234);
543 bone.swing_limit = 60.0 * DEG_TO_RAD;
544 bone.twist_limit = Vec2 {
545 x: -5.0 * DEG_TO_RAD,
546 y: 5.0 * DEG_TO_RAD,
547 };
548 }
549
550 {
552 let bone = &mut human.bones[BoneId::LowerArmL as usize];
553 bone.parent_index = BoneId::UpperArmL as i32;
554 body_def.name = "lower_arm_l".to_string();
555 bone.reference_frame = xf(
556 0.305614, 1.242908, -0.117599, 0.165048, 0.563437, -0.802002, 0.109959,
557 );
558 body_def.rotation = bone.reference_frame.q;
559 body_def.position = offset_pos(position, bone.reference_frame.p);
560 bone.body_id = create_body(world, body_def);
561
562 let capsule = Capsule {
563 center1: Vec3 {
564 x: 0.0,
565 y: 0.0,
566 z: 0.0,
567 },
568 center2: Vec3 {
569 x: -0.142406,
570 y: 0.039392,
571 z: 0.261092,
572 },
573 radius: 0.05,
574 };
575 shape_def.filter.group_index = 0;
576 shape_def.base_material.custom_color = if colorize { skin_color } else { 0 };
577 create_capsule_shape(world, bone.body_id, shape_def, &capsule);
578
579 bone.joint_type = JointType::Revolute;
580 bone.local_frame_a = xf(
581 -0.095482, 0.039584, 0.240723, 0.512487, -0.180629, 0.839474, 0.003742,
582 );
583 bone.local_frame_b = xf(0.0, 0.0, 0.0, 0.503803, -0.029831, 0.858168, 0.094017);
584 bone.twist_limit = Vec2 {
585 x: -5.0 * DEG_TO_RAD,
586 y: 60.0 * DEG_TO_RAD,
587 };
588 }
589
590 {
592 let bone = &mut human.bones[BoneId::UpperArmR as usize];
593 bone.parent_index = BoneId::Spine03 as i32;
594 body_def.name = "upper_arm_r".to_string();
595 bone.reference_frame = xf(
596 -0.20378, 1.484276, -0.115899, 0.143083, -0.695978, 0.690132, 0.137329,
597 );
598 body_def.rotation = bone.reference_frame.q;
599 body_def.position = offset_pos(position, bone.reference_frame.p);
600 bone.body_id = create_body(world, body_def);
601
602 let capsule = Capsule {
603 center1: Vec3 {
604 x: 0.0,
605 y: 0.0,
606 z: 0.0,
607 },
608 center2: Vec3 {
609 x: 0.091118,
610 y: 0.037775,
611 z: 0.229718,
612 },
613 radius: 0.075,
614 };
615 shape_def.filter.group_index = 0;
616 shape_def.base_material.custom_color = if colorize { shirt_color } else { 0 };
617 create_capsule_shape(world, bone.body_id, shape_def, &capsule);
618
619 bone.joint_type = JointType::Spherical;
620 bone.local_frame_a = xf(
621 -0.203779, -0.069371, -0.181922, -0.253621, -0.414842, 0.106962, 0.867261,
622 );
623 bone.local_frame_b = xf(0.0, 0.0, 0.0, -0.201397, 0.001587, -0.901850, 0.382233);
624 bone.swing_limit = 60.0 * DEG_TO_RAD;
625 bone.twist_limit = Vec2 {
626 x: -5.0 * DEG_TO_RAD,
627 y: 5.0 * DEG_TO_RAD,
628 };
629 }
630
631 {
633 let bone = &mut human.bones[BoneId::LowerArmR as usize];
634 bone.parent_index = BoneId::UpperArmR as i32;
635 body_def.name = "lower_arm_r".to_string();
636 bone.reference_frame = xf(
637 -0.305614, 1.242907, -0.117599, 0.165048, -0.563437, 0.802002, 0.109959,
638 );
639 body_def.rotation = bone.reference_frame.q;
640 body_def.position = offset_pos(position, bone.reference_frame.p);
641 bone.body_id = create_body(world, body_def);
642
643 let capsule = Capsule {
644 center1: Vec3 {
645 x: 0.0,
646 y: 0.0,
647 z: 0.0,
648 },
649 center2: Vec3 {
650 x: 0.142406,
651 y: 0.039392,
652 z: 0.261092,
653 },
654 radius: 0.05,
655 };
656 shape_def.filter.group_index = 0;
657 shape_def.base_material.custom_color = if colorize { skin_color } else { 0 };
658 create_capsule_shape(world, bone.body_id, shape_def, &capsule);
659
660 bone.joint_type = JointType::Revolute;
661 bone.local_frame_a = xf(
662 0.095484, 0.039585, 0.240723, -0.180627, 0.512487, -0.003744, -0.839474,
663 );
664 bone.local_frame_b = xf(0.0, 0.0, 0.0, -0.029831, 0.503803, -0.094017, -0.858169);
665 bone.twist_limit = Vec2 {
666 x: -60.0 * DEG_TO_RAD,
667 y: 5.0 * DEG_TO_RAD,
668 };
669 }
670}
671
672fn create_bone_joints(
673 human: &mut Human,
674 world: &mut World,
675 friction_torque: f32,
676 hertz: f32,
677 damping_ratio: f32,
678) {
679 for i in 1..BONE_COUNT {
680 let parent_index = human.bones[i].parent_index as usize;
681 let body_id_a = human.bones[parent_index].body_id;
682 let body_id_b = human.bones[i].body_id;
683
684 human.bones[i].local_frame_a.q = normalize_quat(human.bones[i].local_frame_a.q);
685 human.bones[i].local_frame_b.q = normalize_quat(human.bones[i].local_frame_b.q);
686
687 let joint_type = human.bones[i].joint_type;
688 let local_frame_a = human.bones[i].local_frame_a;
689 let local_frame_b = human.bones[i].local_frame_b;
690 let twist_limit = human.bones[i].twist_limit;
691 let swing_limit = human.bones[i].swing_limit;
692 let joint_friction = human.bones[i].joint_friction;
693
694 if joint_type == JointType::Revolute {
695 let mut joint_def = default_revolute_joint_def();
696 joint_def.base.body_id_a = body_id_a;
697 joint_def.base.body_id_b = body_id_b;
698 joint_def.base.local_frame_a = local_frame_a;
699 joint_def.base.local_frame_b = local_frame_b;
700 joint_def.enable_limit = true;
701 joint_def.lower_angle = twist_limit.x;
702 joint_def.upper_angle = twist_limit.y;
703 joint_def.enable_spring = hertz > 0.0;
704 joint_def.hertz = hertz;
705 joint_def.damping_ratio = damping_ratio;
706 joint_def.enable_motor = true;
707 joint_def.max_motor_torque = joint_friction * friction_torque;
708 human.bones[i].joint_id = create_revolute_joint(world, &joint_def);
709 } else if joint_type == JointType::Spherical {
710 let mut joint_def = default_spherical_joint_def();
711 joint_def.base.body_id_a = body_id_a;
712 joint_def.base.body_id_b = body_id_b;
713 joint_def.base.local_frame_a = local_frame_a;
714 joint_def.base.local_frame_b = local_frame_b;
715 joint_def.enable_cone_limit = true;
716 joint_def.cone_angle = swing_limit;
717 joint_def.enable_twist_limit = true;
718 joint_def.lower_twist_angle = twist_limit.x;
719 joint_def.upper_twist_angle = twist_limit.y;
720 joint_def.enable_spring = hertz > 0.0;
721 joint_def.hertz = hertz;
722 joint_def.damping_ratio = damping_ratio;
723 joint_def.enable_motor = true;
724 joint_def.max_motor_torque = joint_friction * friction_torque;
725 human.bones[i].joint_id = create_spherical_joint(world, &joint_def);
726 }
727 }
728}