box2d_rust/body/
access.rs1use super::get_body_full_id;
8use crate::core::NULL_INDEX;
9use crate::id::{BodyId, JointId, ShapeId};
10use crate::solver_set::{AWAKE_SET, DISABLED_SET, STATIC_SET};
11use crate::types::BodyType;
12use crate::world::World;
13
14pub fn body_get_shape_count(world: &World, body_id: BodyId) -> i32 {
16 let body_index = get_body_full_id(world, body_id);
17 world.bodies[body_index as usize].shape_count
18}
19
20pub fn body_get_shapes(world: &World, body_id: BodyId, capacity: usize) -> Vec<ShapeId> {
22 let body_index = get_body_full_id(world, body_id);
23 let mut out = Vec::new();
24 let mut shape_id = world.bodies[body_index as usize].head_shape_id;
25 while shape_id != NULL_INDEX && out.len() < capacity {
26 let shape = &world.shapes[shape_id as usize];
27 out.push(ShapeId {
28 index1: shape_id + 1,
29 world0: world.world_id,
30 generation: shape.generation,
31 });
32 shape_id = shape.next_shape_id;
33 }
34 out
35}
36
37pub fn body_get_joint_count(world: &World, body_id: BodyId) -> i32 {
39 let body_index = get_body_full_id(world, body_id);
40 world.bodies[body_index as usize].joint_count
41}
42
43pub fn body_get_joints(world: &World, body_id: BodyId, capacity: usize) -> Vec<JointId> {
45 let body_index = get_body_full_id(world, body_id);
46 let mut out = Vec::new();
47 let mut joint_key = world.bodies[body_index as usize].head_joint_key;
48 while joint_key != NULL_INDEX && out.len() < capacity {
49 let joint_id = joint_key >> 1;
50 let edge_index = joint_key & 1;
51
52 let joint = &world.joints[joint_id as usize];
53 out.push(JointId {
54 index1: joint_id + 1,
55 world0: world.world_id,
56 generation: joint.generation,
57 });
58
59 joint_key = joint.edges[edge_index as usize].next_key;
60 }
61 out
62}
63
64pub fn body_get_contact_capacity(world: &World, body_id: BodyId) -> i32 {
66 debug_assert!(!world.locked);
67 let body_index = get_body_full_id(world, body_id);
68 world.bodies[body_index as usize].contact_count
69}
70
71pub fn body_get_contact_data(
74 world: &World,
75 body_id: BodyId,
76 capacity: usize,
77) -> Vec<crate::events::ContactData> {
78 debug_assert!(!world.locked);
79 let body_index = get_body_full_id(world, body_id);
80
81 let mut out = Vec::new();
82 let mut contact_key = world.bodies[body_index as usize].head_contact_key;
83 while contact_key != NULL_INDEX && out.len() < capacity {
84 let contact_id = contact_key >> 1;
85 let edge_index = contact_key & 1;
86
87 let contact = &world.contacts[contact_id as usize];
88
89 if contact.flags & crate::contact::contact_flags::TOUCHING != 0 {
91 let shape_a = &world.shapes[contact.shape_id_a as usize];
92 let shape_b = &world.shapes[contact.shape_id_b as usize];
93
94 let contact_sim = if contact.set_index == AWAKE_SET && contact.color_index != NULL_INDEX
95 {
96 &world.constraint_graph.colors[contact.color_index as usize].contact_sims
97 [contact.local_index as usize]
98 } else {
99 &world.solver_sets[contact.set_index as usize].contact_sims
100 [contact.local_index as usize]
101 };
102
103 out.push(crate::events::ContactData {
104 contact_id: crate::id::ContactId {
105 index1: contact_id + 1,
106 world0: world.world_id,
107 padding: 0,
108 generation: contact.generation,
109 },
110 shape_id_a: ShapeId {
111 index1: shape_a.id + 1,
112 world0: world.world_id,
113 generation: shape_a.generation,
114 },
115 shape_id_b: ShapeId {
116 index1: shape_b.id + 1,
117 world0: world.world_id,
118 generation: shape_b.generation,
119 },
120 manifold: contact_sim.manifold,
121 });
122 }
123
124 contact_key = contact.edges[edge_index as usize].next_key;
125 }
126
127 out
128}
129
130impl World {
131 pub fn validate_connectivity(&self) {
134 if !cfg!(debug_assertions) {
135 return;
136 }
137
138 for body_index in 0..self.bodies.len() as i32 {
139 let body = &self.bodies[body_index as usize];
140 if body.id == NULL_INDEX {
141 self.body_id_pool.validate_free_id(body_index);
142 continue;
143 }
144
145 self.body_id_pool.validate_used_id(body_index);
146
147 debug_assert!(body_index == body.id);
148
149 let body_island_id = body.island_id;
150 let body_set_index = body.set_index;
151
152 let mut contact_key = body.head_contact_key;
153 while contact_key != NULL_INDEX {
154 let contact_id = contact_key >> 1;
155 let edge_index = contact_key & 1;
156
157 let contact = &self.contacts[contact_id as usize];
158
159 let touching = contact.flags & crate::contact::contact_flags::TOUCHING != 0;
160 if touching {
161 if body_set_index != STATIC_SET {
162 debug_assert!(contact.island_id == body_island_id);
163 }
164 } else {
165 debug_assert!(contact.island_id == NULL_INDEX);
166 }
167
168 contact_key = contact.edges[edge_index as usize].next_key;
169 }
170
171 let mut joint_key = body.head_joint_key;
172 while joint_key != NULL_INDEX {
173 let joint_id = joint_key >> 1;
174 let edge_index = joint_key & 1;
175
176 let joint = &self.joints[joint_id as usize];
177
178 let other_edge_index = edge_index ^ 1;
179 let other_body =
180 &self.bodies[joint.edges[other_edge_index as usize].body_id as usize];
181
182 if body_set_index == DISABLED_SET || other_body.set_index == DISABLED_SET {
183 debug_assert!(joint.island_id == NULL_INDEX);
184 } else if body_set_index == STATIC_SET {
185 if other_body.set_index == STATIC_SET {
187 debug_assert!(joint.island_id == NULL_INDEX);
188 }
189 } else if body.type_ != BodyType::Dynamic && other_body.type_ != BodyType::Dynamic {
190 debug_assert!(joint.island_id == NULL_INDEX);
191 } else {
192 debug_assert!(joint.island_id == body_island_id);
193 }
194
195 joint_key = joint.edges[edge_index as usize].next_key;
196 }
197 }
198 }
199}