Skip to main content

box3d_rust/human/
types.rs

1//! Ragdoll bone/human types from `shared/human.h`.
2//!
3//! SPDX-FileCopyrightText: 2026 Erin Catto
4//! SPDX-License-Identifier: MIT
5
6use crate::id::{BodyId, JointId, NULL_BODY_ID, NULL_JOINT_ID};
7use crate::joint::JointType;
8use crate::math_functions::{Transform, Vec2, TRANSFORM_IDENTITY, VEC2_ZERO};
9
10/// Bone indices in the ragdoll hierarchy. (BoneId)
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12#[repr(usize)]
13pub enum BoneId {
14    Pelvis = 0,
15    Spine01 = 1,
16    Spine02 = 2,
17    Spine03 = 3,
18    Neck = 4,
19    Head = 5,
20    ThighL = 6,
21    CalfL = 7,
22    ThighR = 8,
23    CalfR = 9,
24    UpperArmL = 10,
25    LowerArmL = 11,
26    UpperArmR = 12,
27    LowerArmR = 13,
28}
29
30/// Number of bones in a human ragdoll. (bone_count)
31pub const BONE_COUNT: usize = 14;
32
33/// Max filter joints that disable selected bone-bone collisions. (FILTER_JOINT_COUNT)
34pub const FILTER_JOINT_COUNT: usize = 8;
35
36/// Hex colors used when `colorize` is true. (b3HexColor / types.h)
37pub const COLOR_MEDIUM_TURQUOISE: u32 = 0x48D1CC;
38pub const COLOR_DODGER_BLUE: u32 = 0x1E90FF;
39pub const COLOR_NAVAJO_WHITE: u32 = 0xFFDEAD;
40pub const COLOR_LIGHT_YELLOW: u32 = 0xFFFFE0;
41pub const COLOR_PERU: u32 = 0xCD853F;
42pub const COLOR_TAN: u32 = 0xD2B48C;
43
44/// One bone of a human ragdoll. (Bone)
45#[derive(Debug, Clone, Copy)]
46pub struct Bone {
47    pub body_id: BodyId,
48    pub joint_id: JointId,
49    pub anchor_id: BodyId,
50    pub anchor_joint_id: JointId,
51    pub local_frame_a: Transform,
52    pub local_frame_b: Transform,
53    pub reference_frame: Transform,
54    pub joint_type: JointType,
55    pub swing_limit: f32,
56    pub twist_limit: Vec2,
57    pub joint_friction: f32,
58    pub parent_index: i32,
59}
60
61impl Default for Bone {
62    fn default() -> Self {
63        Bone {
64            body_id: NULL_BODY_ID,
65            joint_id: NULL_JOINT_ID,
66            anchor_id: NULL_BODY_ID,
67            anchor_joint_id: NULL_JOINT_ID,
68            local_frame_a: TRANSFORM_IDENTITY,
69            local_frame_b: TRANSFORM_IDENTITY,
70            reference_frame: TRANSFORM_IDENTITY,
71            joint_type: JointType::Parallel,
72            swing_limit: 0.0,
73            twist_limit: VEC2_ZERO,
74            joint_friction: 1.0,
75            parent_index: -1,
76        }
77    }
78}
79
80/// Zero-initialized human ragdoll. Must call [`super::create_human`] to spawn.
81/// (Human)
82#[derive(Debug, Clone)]
83pub struct Human {
84    pub bones: [Bone; BONE_COUNT],
85    pub filter_joints: [JointId; FILTER_JOINT_COUNT],
86    pub filter_joint_count: i32,
87    pub friction_torque: f32,
88    pub is_spawned: bool,
89}
90
91impl Default for Human {
92    fn default() -> Self {
93        Human {
94            bones: [Bone::default(); BONE_COUNT],
95            filter_joints: [NULL_JOINT_ID; FILTER_JOINT_COUNT],
96            filter_joint_count: 0,
97            friction_torque: 0.0,
98            is_spawned: false,
99        }
100    }
101}