pub fn default_shape_def() -> ShapeDefExpand description
Initialize a shape definition with the default values. (b2DefaultShapeDef)
Examples found in repository?
examples/demo_scenes.rs (line 14)
10fn add_static_box(world: &mut World, x: f32, y: f32, hx: f32, hy: f32) -> i32 {
11 let mut body_def = default_body_def();
12 body_def.position = m::to_pos(m::Vec2 { x, y });
13 let id = create_body(world, &body_def);
14 let def = default_shape_def();
15 let poly = make_box(hx, hy);
16 create_polygon_shape(world, id, &def, &poly);
17 get_body_full_id(world, id)
18}
19
20fn add_box(world: &mut World, x: f32, y: f32, hx: f32, hy: f32) -> i32 {
21 let mut body_def = default_body_def();
22 body_def.type_ = BodyType::Dynamic;
23 body_def.position = m::to_pos(m::Vec2 { x, y });
24 let id = create_body(world, &body_def);
25 let mut def = default_shape_def();
26 def.density = 1.0;
27 def.material.friction = 0.3;
28 let poly = make_box(hx, hy);
29 create_polygon_shape(world, id, &def, &poly);
30 get_body_full_id(world, id)
31}
32
33fn add_circle(world: &mut World, x: f32, y: f32, r: f32, density: f32) -> i32 {
34 let mut body_def = default_body_def();
35 body_def.type_ = BodyType::Dynamic;
36 body_def.position = m::to_pos(m::Vec2 { x, y });
37 let id = create_body(world, &body_def);
38 let mut def = default_shape_def();
39 def.density = density;
40 def.material.friction = 0.3;
41 def.material.restitution = 0.2;
42 let circle = box2d_rust::collision::Circle {
43 center: m::VEC2_ZERO,
44 radius: r,
45 };
46 create_circle_shape(world, id, &def, &circle);
47 get_body_full_id(world, id)
48}More examples
examples/benchmark/scenes/rain.rs (line 76)
61pub fn create_rain(world: &mut World) {
62 RAIN_DATA.with(|rd| rd.borrow_mut().reset());
63
64 let grid_size = 0.5;
65 let grid_count = if BENCHMARK_DEBUG { 200 } else { 500 };
66 RAIN_DATA.with(|rd| {
67 let mut rd = rd.borrow_mut();
68 rd.grid_size = grid_size;
69 rd.grid_count = grid_count;
70 });
71
72 {
73 let body_def = default_body_def();
74 let ground_id = create_body(world, &body_def);
75
76 let shape_def = default_shape_def();
77 let mut y = 0.0;
78 let width = grid_size;
79 let height = grid_size;
80
81 for _ in 0..RAIN_ROW_COUNT {
82 let mut x = -0.5 * grid_count as f32 * grid_size;
83 for _ in 0..=grid_count {
84 let box_shape =
85 make_offset_box(0.5 * width, 0.5 * height, Vec2 { x, y }, ROT_IDENTITY);
86 create_polygon_shape(world, ground_id, &shape_def, &box_shape);
87
88 x += grid_size;
89 }
90
91 y += 45.0;
92 }
93 }
94
95 RAIN_DATA.with(|rd| {
96 let mut rd = rd.borrow_mut();
97 rd.column_count = 0;
98 rd.column_index = 0;
99 });
100}examples/benchmark/scenes/pyramids.rs (line 27)
20pub fn create_joint_grid(world: &mut World) {
21 world_enable_sleeping(world, false);
22
23 let n: i32 = if BENCHMARK_DEBUG { 20 } else { 100 };
24
25 let mut bodies: Vec<BodyId> = Vec::with_capacity((n * n) as usize);
26
27 let mut shape_def = default_shape_def();
28 shape_def.density = 1.0;
29 shape_def.filter.category_bits = 2;
30 shape_def.filter.mask_bits = (!2u32) as u64;
31
32 let circle = Circle {
33 center: Vec2 { x: 0.0, y: 0.0 },
34 radius: 0.4,
35 };
36
37 let mut joint_def = default_revolute_joint_def();
38 joint_def.base.draw_scale = 0.4;
39
40 let mut body_def = default_body_def();
41
42 for k in 0..n {
43 for i in 0..n {
44 let fk = k as f32;
45 let fi = i as f32;
46
47 if k >= n / 2 - 3 && k <= n / 2 + 3 && i == 0 {
48 body_def.type_ = BodyType::Static;
49 } else {
50 body_def.type_ = BodyType::Dynamic;
51 }
52
53 body_def.position = to_pos(Vec2 { x: fk, y: -fi });
54
55 let body = create_body(world, &body_def);
56 create_circle_shape(world, body, &shape_def, &circle);
57
58 let index = bodies.len();
59
60 if i > 0 {
61 joint_def.base.body_id_a = bodies[index - 1];
62 joint_def.base.body_id_b = body;
63 joint_def.base.local_frame_a.p = Vec2 { x: 0.0, y: -0.5 };
64 joint_def.base.local_frame_b.p = Vec2 { x: 0.0, y: 0.5 };
65 create_revolute_joint(world, &joint_def);
66 }
67
68 if k > 0 {
69 joint_def.base.body_id_a = bodies[index - n as usize];
70 joint_def.base.body_id_b = body;
71 joint_def.base.local_frame_a.p = Vec2 { x: 0.5, y: 0.0 };
72 joint_def.base.local_frame_b.p = Vec2 { x: -0.5, y: 0.0 };
73 create_revolute_joint(world, &joint_def);
74 }
75
76 bodies.push(body);
77 }
78 }
79}
80
81// (CreateLargePyramid)
82pub fn create_large_pyramid(world: &mut World) {
83 world_enable_sleeping(world, false);
84
85 let base_count: i32 = if BENCHMARK_DEBUG { 20 } else { 100 };
86
87 {
88 let mut body_def = default_body_def();
89 body_def.position = to_pos(Vec2 { x: 0.0, y: -1.0 });
90 let ground_id = create_body(world, &body_def);
91
92 let box_shape = make_box(100.0, 1.0);
93 let shape_def = default_shape_def();
94 create_polygon_shape(world, ground_id, &shape_def, &box_shape);
95 }
96
97 let mut body_def = default_body_def();
98 body_def.type_ = BodyType::Dynamic;
99
100 let mut shape_def = default_shape_def();
101 shape_def.density = 1.0;
102
103 let a = 0.5;
104 let box_shape = make_square(a);
105
106 let shift = 1.0 * a;
107
108 for i in 0..base_count {
109 let y = (2.0 * i as f32 + 1.0) * shift;
110
111 for j in i..base_count {
112 let x = (i as f32 + 1.0) * shift + 2.0 * (j - i) as f32 * shift - a * base_count as f32;
113
114 body_def.position = to_pos(Vec2 { x, y });
115
116 let body_id = create_body(world, &body_def);
117 create_polygon_shape(world, body_id, &shape_def, &box_shape);
118 }
119 }
120}
121
122// (static CreateSmallPyramid)
123fn create_small_pyramid(
124 world: &mut World,
125 base_count: i32,
126 extent: f32,
127 center_x: f32,
128 base_y: f32,
129) {
130 let mut body_def = default_body_def();
131 body_def.type_ = BodyType::Dynamic;
132
133 let shape_def = default_shape_def();
134
135 let box_shape = make_square(extent);
136
137 for i in 0..base_count {
138 let y = (2.0 * i as f32 + 1.0) * extent + base_y;
139
140 for j in i..base_count {
141 let x = (i as f32 + 1.0) * extent + 2.0 * (j - i) as f32 * extent + center_x - 0.5;
142 body_def.position = to_pos(Vec2 { x, y });
143
144 let body_id = create_body(world, &body_def);
145 create_polygon_shape(world, body_id, &shape_def, &box_shape);
146 }
147 }
148}
149
150// (CreateManyPyramids)
151pub fn create_many_pyramids(world: &mut World) {
152 world_enable_sleeping(world, false);
153
154 let base_count = 10;
155 let extent = 0.5;
156 let row_count: i32 = if BENCHMARK_DEBUG { 5 } else { 20 };
157 let column_count: i32 = if BENCHMARK_DEBUG { 5 } else { 20 };
158
159 let body_def = default_body_def();
160 let ground_id = create_body(world, &body_def);
161
162 let ground_delta_y = 2.0 * extent * (base_count as f32 + 1.0);
163 let ground_width = 2.0 * extent * column_count as f32 * (base_count as f32 + 1.0);
164 let shape_def = default_shape_def();
165
166 let mut ground_y = 0.0;
167
168 for _ in 0..row_count {
169 let segment = Segment {
170 point1: Vec2 {
171 x: -0.5 * ground_width,
172 y: ground_y,
173 },
174 point2: Vec2 {
175 x: 0.5 * ground_width,
176 y: ground_y,
177 },
178 };
179 create_segment_shape(world, ground_id, &shape_def, &segment);
180 ground_y += ground_delta_y;
181 }
182
183 let base_width = 2.0 * extent * base_count as f32;
184 let mut base_y = 0.0;
185
186 for _ in 0..row_count {
187 for j in 0..column_count {
188 let center_x =
189 -0.5 * ground_width + j as f32 * (base_width + 2.0 * extent) + 2.0 * extent;
190 create_small_pyramid(world, base_count, extent, center_x, base_y);
191 }
192
193 base_y += ground_delta_y;
194 }
195}
196
197// (CreateCompounds)
198// Lifted from samples/sample_benchmark.cpp BenchmarkBarrel (e_compoundShape
199// branch). Each dynamic body is a compound of two triangular polygon shapes.
200pub fn create_compounds(world: &mut World) {
201 {
202 let grid_size = 1.0;
203
204 let body_def = default_body_def();
205 let ground_id = create_body(world, &body_def);
206
207 let shape_def = default_shape_def();
208
209 let y = 0.0;
210 let mut x = -40.0 * grid_size;
211 for _ in 0..81 {
212 let box_shape = make_offset_box(
213 0.55 * grid_size,
214 0.5 * grid_size,
215 Vec2 { x, y },
216 ROT_IDENTITY,
217 );
218 create_polygon_shape(world, ground_id, &shape_def, &box_shape);
219 x += grid_size;
220 }
221
222 let mut y = grid_size;
223 let x = -40.0 * grid_size;
224 for _ in 0..100 {
225 let box_shape = make_offset_box(
226 0.5 * grid_size,
227 0.55 * grid_size,
228 Vec2 { x, y },
229 ROT_IDENTITY,
230 );
231 create_polygon_shape(world, ground_id, &shape_def, &box_shape);
232 y += grid_size;
233 }
234
235 let mut y = grid_size;
236 let x = 40.0 * grid_size;
237 for _ in 0..100 {
238 let box_shape = make_offset_box(
239 0.5 * grid_size,
240 0.55 * grid_size,
241 Vec2 { x, y },
242 ROT_IDENTITY,
243 );
244 create_polygon_shape(world, ground_id, &shape_def, &box_shape);
245 y += grid_size;
246 }
247
248 let segment = Segment {
249 point1: Vec2 {
250 x: -800.0,
251 y: -80.0,
252 },
253 point2: Vec2 { x: 800.0, y: -80.0 },
254 };
255 create_segment_shape(world, ground_id, &shape_def, &segment);
256 }
257
258 let column_count: i32 = if BENCHMARK_DEBUG { 10 } else { 20 };
259 let row_count: i32 = if BENCHMARK_DEBUG { 40 } else { 150 };
260
261 let left_points = [
262 Vec2 { x: -1.0, y: 0.0 },
263 Vec2 { x: 0.5, y: 1.0 },
264 Vec2 { x: 0.0, y: 2.0 },
265 ];
266 let left_hull = compute_hull(&left_points);
267 let left = make_polygon(&left_hull, 0.0);
268
269 let right_points = [
270 Vec2 { x: 1.0, y: 0.0 },
271 Vec2 { x: -0.5, y: 1.0 },
272 Vec2 { x: 0.0, y: 2.0 },
273 ];
274 let right_hull = compute_hull(&right_points);
275 let right = make_polygon(&right_hull, 0.0);
276
277 let mut body_def = default_body_def();
278 body_def.type_ = BodyType::Dynamic;
279
280 let mut shape_def = default_shape_def();
281 shape_def.density = 1.0;
282 shape_def.material.friction = 0.5;
283
284 // Match the sample exactly: centery is computed before shift is reset for
285 // the compound branch.
286 let shift = 2.0;
287 let extray = 0.25;
288 let mut side = 0.25;
289 let centerx = shift * column_count as f32 / 2.0 - 1.0;
290 let centery = 1.15 / 2.0;
291 let y_start = 5.0;
292
293 for i in 0..column_count {
294 let x = i as f32 * shift - centerx;
295
296 for j in 0..row_count {
297 let y = j as f32 * (shift + extray) + centery + y_start;
298
299 body_def.position = to_pos(Vec2 { x: x + side, y });
300 side = -side;
301
302 let body_id = create_body(world, &body_def);
303 create_polygon_shape(world, body_id, &shape_def, &left);
304 create_polygon_shape(world, body_id, &shape_def, &right);
305 }
306 }
307}examples/benchmark/scenes/machines.rs (line 83)
39pub fn create_spinner(world: &mut World) {
40 let ground_id;
41 {
42 let body_def = default_body_def();
43 ground_id = create_body(world, &body_def);
44
45 let q = make_rot(-2.0 * PI / SPINNER_POINT_COUNT as f32);
46 let mut p = Vec2 { x: 40.0, y: 0.0 };
47 let mut points: Vec<Vec2> = Vec::with_capacity(SPINNER_POINT_COUNT);
48 for _ in 0..SPINNER_POINT_COUNT {
49 points.push(Vec2 {
50 x: p.x,
51 y: p.y + 32.0,
52 });
53 p = rotate_vector(q, p);
54 }
55
56 // C: b2SurfaceMaterial material = { 0 }; material.friction = 0.1f;
57 let material = SurfaceMaterial {
58 friction: 0.1,
59 restitution: 0.0,
60 rolling_resistance: 0.0,
61 tangent_speed: 0.0,
62 user_material_id: 0,
63 custom_color: 0,
64 };
65
66 let mut chain_def = default_chain_def();
67 chain_def.points = points;
68 chain_def.is_loop = true;
69 chain_def.materials = vec![material];
70
71 create_chain(world, ground_id, &chain_def);
72 }
73
74 {
75 let mut body_def = default_body_def();
76 body_def.type_ = BodyType::Dynamic;
77 body_def.position = to_pos(Vec2 { x: 0.0, y: 12.0 });
78 body_def.enable_sleep = false;
79
80 let spinner_id = create_body(world, &body_def);
81
82 let box_shape = make_rounded_box(0.4, 20.0, 0.2);
83 let mut shape_def = default_shape_def();
84 shape_def.material.friction = 0.0;
85 create_polygon_shape(world, spinner_id, &shape_def, &box_shape);
86
87 let motor_speed = 5.0;
88 let max_motor_torque = f32::MAX;
89 let mut joint_def = default_revolute_joint_def();
90 joint_def.base.body_id_a = ground_id;
91 joint_def.base.body_id_b = spinner_id;
92 joint_def.base.local_frame_a.p = body_get_local_point(world, ground_id, body_def.position);
93 joint_def.enable_motor = true;
94 joint_def.motor_speed = motor_speed;
95 joint_def.max_motor_torque = max_motor_torque;
96
97 let joint_id = create_revolute_joint(world, &joint_def);
98 SPINNER_ID.with(|id| id.set(joint_id));
99 }
100
101 let capsule = Capsule {
102 center1: Vec2 { x: -0.25, y: 0.0 },
103 center2: Vec2 { x: 0.25, y: 0.0 },
104 radius: 0.25,
105 };
106 let circle = Circle {
107 center: Vec2 { x: 0.0, y: 0.0 },
108 radius: 0.35,
109 };
110 let square = make_square(0.35);
111
112 let mut body_def = default_body_def();
113 body_def.type_ = BodyType::Dynamic;
114 let mut shape_def = default_shape_def();
115 shape_def.material.friction = 0.1;
116 shape_def.material.restitution = 0.1;
117 shape_def.density = 0.25;
118
119 let body_count: i32 = if BENCHMARK_DEBUG { 499 } else { 2 * 3038 };
120
121 let mut x = -23.0;
122 let mut y = 2.0;
123 for i in 0..body_count {
124 body_def.position = to_pos(Vec2 { x, y });
125 let body_id = create_body(world, &body_def);
126
127 let remainder = i % 3;
128 if remainder == 0 {
129 create_capsule_shape(world, body_id, &shape_def, &capsule);
130 } else if remainder == 1 {
131 create_circle_shape(world, body_id, &shape_def, &circle);
132 } else if remainder == 2 {
133 create_polygon_shape(world, body_id, &shape_def, &square);
134 }
135
136 x += 0.5;
137
138 if x >= 23.0 {
139 x = -23.0;
140 y += 0.5;
141 }
142 }
143}
144
145// (StepSpinner)
146pub fn step_spinner(world: &mut World, _step_count: i32) -> f32 {
147 let joint_id = SPINNER_ID.with(|id| id.get());
148 revolute_joint_get_angle(world, joint_id)
149}
150
151// (CreateSmash)
152pub fn create_smash(world: &mut World) {
153 world_set_gravity(world, VEC2_ZERO);
154
155 {
156 let box_shape = make_box(4.0, 4.0);
157
158 let mut body_def = default_body_def();
159 body_def.type_ = BodyType::Dynamic;
160 body_def.position = to_pos(Vec2 { x: -20.0, y: 0.0 });
161 body_def.linear_velocity = Vec2 { x: 40.0, y: 0.0 };
162 let body_id = create_body(world, &body_def);
163
164 let mut shape_def = default_shape_def();
165 shape_def.density = 8.0;
166 create_polygon_shape(world, body_id, &shape_def, &box_shape);
167 }
168
169 let d = 0.4;
170 let box_shape = make_square(0.5 * d);
171
172 let mut body_def = default_body_def();
173 body_def.type_ = BodyType::Dynamic;
174 body_def.is_awake = false;
175
176 let shape_def = default_shape_def();
177
178 let columns: i32 = if BENCHMARK_DEBUG { 20 } else { 120 };
179 let rows: i32 = if BENCHMARK_DEBUG { 10 } else { 80 };
180
181 for i in 0..columns {
182 for j in 0..rows {
183 body_def.position = to_pos(Vec2 {
184 x: i as f32 * d + 30.0,
185 y: (j as f32 - rows as f32 / 2.0) * d,
186 });
187 let body_id = create_body(world, &body_def);
188 create_polygon_shape(world, body_id, &shape_def, &box_shape);
189 }
190 }
191}
192
193// (CreateTumbler)
194pub fn create_tumbler(world: &mut World) {
195 let ground_id;
196 {
197 let body_def = default_body_def();
198 ground_id = create_body(world, &body_def);
199 }
200
201 {
202 let mut body_def = default_body_def();
203 body_def.type_ = BodyType::Dynamic;
204 body_def.position = to_pos(Vec2 { x: 0.0, y: 10.0 });
205 let body_id = create_body(world, &body_def);
206
207 let mut shape_def = default_shape_def();
208 shape_def.density = 50.0;
209
210 let polygon = make_offset_box(0.5, 10.0, Vec2 { x: 10.0, y: 0.0 }, ROT_IDENTITY);
211 create_polygon_shape(world, body_id, &shape_def, &polygon);
212 let polygon = make_offset_box(0.5, 10.0, Vec2 { x: -10.0, y: 0.0 }, ROT_IDENTITY);
213 create_polygon_shape(world, body_id, &shape_def, &polygon);
214 let polygon = make_offset_box(10.0, 0.5, Vec2 { x: 0.0, y: 10.0 }, ROT_IDENTITY);
215 create_polygon_shape(world, body_id, &shape_def, &polygon);
216 let polygon = make_offset_box(10.0, 0.5, Vec2 { x: 0.0, y: -10.0 }, ROT_IDENTITY);
217 create_polygon_shape(world, body_id, &shape_def, &polygon);
218
219 let motor_speed = 25.0;
220
221 let mut joint_def = default_revolute_joint_def();
222 joint_def.base.body_id_a = ground_id;
223 joint_def.base.body_id_b = body_id;
224 joint_def.base.local_frame_a.p = Vec2 { x: 0.0, y: 10.0 };
225 joint_def.base.local_frame_b.p = Vec2 { x: 0.0, y: 0.0 };
226 joint_def.motor_speed = (PI / 180.0) * motor_speed;
227 joint_def.max_motor_torque = 1e8;
228 joint_def.enable_motor = true;
229
230 create_revolute_joint(world, &joint_def);
231 }
232
233 let grid_count: i32 = if BENCHMARK_DEBUG { 20 } else { 45 };
234
235 let polygon = make_box(0.125, 0.125);
236 let mut body_def = default_body_def();
237 body_def.type_ = BodyType::Dynamic;
238 let shape_def = default_shape_def();
239
240 let mut y = -0.2 * grid_count as f32 + 10.0;
241 for _ in 0..grid_count {
242 let mut x = -0.2 * grid_count as f32;
243
244 for _ in 0..grid_count {
245 body_def.position = to_pos(Vec2 { x, y });
246 let body_id = create_body(world, &body_def);
247
248 create_polygon_shape(world, body_id, &shape_def, &polygon);
249
250 x += 0.4;
251 }
252
253 y += 0.4;
254 }
255}
256
257// (CreateWasher)
258pub fn create_washer(world: &mut World) {
259 let kinematic = true;
260
261 {
262 let body_def = default_body_def();
263 // groundId is only used to anchor the (disabled) revolute joint branch.
264 let _ground_id = create_body(world, &body_def);
265 }
266
267 {
268 let motor_speed = 25.0;
269
270 let mut body_def = default_body_def();
271 body_def.position = to_pos(Vec2 { x: 0.0, y: 10.0 });
272
273 if kinematic {
274 body_def.type_ = BodyType::Kinematic;
275 body_def.angular_velocity = (PI / 180.0) * motor_speed;
276 body_def.linear_velocity = Vec2 {
277 x: 0.001,
278 y: -0.002,
279 };
280 } else {
281 body_def.type_ = BodyType::Dynamic;
282 }
283
284 let body_id = create_body(world, &body_def);
285
286 let shape_def = default_shape_def();
287
288 let r0 = 14.0;
289 let r1 = 16.0;
290 let r2 = 18.0;
291
292 let angle = PI / 18.0;
293 let q = Rot {
294 c: angle.cos(),
295 s: angle.sin(),
296 };
297 let qo = Rot {
298 c: (0.1 * angle).cos(),
299 s: (0.1 * angle).sin(),
300 };
301 let mut u1 = Vec2 { x: 1.0, y: 0.0 };
302 for i in 0..36 {
303 let u2 = if i == 35 {
304 Vec2 { x: 1.0, y: 0.0 }
305 } else {
306 rotate_vector(q, u1)
307 };
308
309 {
310 let a1 = inv_rotate_vector(qo, u1);
311 let a2 = rotate_vector(qo, u2);
312
313 let p1 = mul_sv(r1, a1);
314 let p2 = mul_sv(r2, a1);
315 let p3 = mul_sv(r1, a2);
316 let p4 = mul_sv(r2, a2);
317
318 let points = [p1, p2, p3, p4];
319 let hull = compute_hull(&points);
320
321 let polygon = make_polygon(&hull, 0.0);
322 create_polygon_shape(world, body_id, &shape_def, &polygon);
323 }
324
325 if i % 9 == 0 {
326 let p1 = mul_sv(r0, u1);
327 let p2 = mul_sv(r1, u1);
328 let p3 = mul_sv(r0, u2);
329 let p4 = mul_sv(r1, u2);
330
331 let points = [p1, p2, p3, p4];
332 let hull = compute_hull(&points);
333
334 let polygon = make_polygon(&hull, 0.0);
335 create_polygon_shape(world, body_id, &shape_def, &polygon);
336 }
337
338 u1 = u2;
339 }
340 }
341
342 let grid_count: i32 = if BENCHMARK_DEBUG { 20 } else { 90 };
343 let a = 0.1;
344
345 let polygon = make_square(a);
346 let mut body_def = default_body_def();
347 body_def.type_ = BodyType::Dynamic;
348 let mut shape_def = default_shape_def();
349 shape_def.enable_hit_events = true;
350
351 let mut y = -1.1 * a * grid_count as f32 + 10.0;
352 for _ in 0..grid_count {
353 let mut x = -1.1 * a * grid_count as f32;
354
355 for _ in 0..grid_count {
356 body_def.position = to_pos(Vec2 { x, y });
357 let body_id = create_body(world, &body_def);
358
359 create_polygon_shape(world, body_id, &shape_def, &polygon);
360
361 x += 2.1 * a;
362 }
363
364 y += 2.1 * a;
365 }
366}
367
368// (CreateJunkyard)
369pub fn create_junkyard(world: &mut World) {
370 {
371 let grid_size = 1.0;
372
373 let body_def = default_body_def();
374 let ground_id = create_body(world, &body_def);
375
376 let shape_def = default_shape_def();
377
378 let y = 0.0;
379 let mut x = -80.0 * grid_size;
380 for _ in 0..161 {
381 let box_shape = make_offset_box(
382 0.55 * grid_size,
383 0.5 * grid_size,
384 Vec2 { x, y },
385 ROT_IDENTITY,
386 );
387 create_polygon_shape(world, ground_id, &shape_def, &box_shape);
388 x += grid_size;
389 }
390
391 let mut y = grid_size;
392 let x = -80.0 * grid_size;
393 for _ in 0..50 {
394 let box_shape = make_offset_box(
395 0.5 * grid_size,
396 0.55 * grid_size,
397 Vec2 { x, y },
398 ROT_IDENTITY,
399 );
400 create_polygon_shape(world, ground_id, &shape_def, &box_shape);
401 y += grid_size;
402 }
403
404 let mut y = grid_size;
405 let x = 80.0 * grid_size;
406 for _ in 0..50 {
407 let box_shape = make_offset_box(
408 0.5 * grid_size,
409 0.55 * grid_size,
410 Vec2 { x, y },
411 ROT_IDENTITY,
412 );
413 create_polygon_shape(world, ground_id, &shape_def, &box_shape);
414 y += grid_size;
415 }
416 }
417
418 let column_count = 200;
419 let row_count: i32 = if BENCHMARK_DEBUG { 2 } else { 40 };
420
421 let radius = 0.25;
422 let polygon;
423 {
424 // Fibonacci sphere algorithm
425 let phi = PI * (5.0f32.sqrt() - 1.0);
426 let mut points = [Vec2 { x: 0.0, y: 0.0 }; 5];
427
428 for (i, point) in points.iter_mut().enumerate() {
429 let theta = phi * i as f32;
430 let cs = compute_cos_sin(theta);
431 point.x = radius * cs.cosine;
432 point.y = radius * cs.sine;
433 }
434
435 let hull = compute_hull(&points);
436 polygon = make_polygon(&hull, 0.0);
437 }
438
439 let mut body_def = default_body_def();
440 body_def.type_ = BodyType::Dynamic;
441 let shape_def = default_shape_def();
442
443 let mut side = -0.1;
444 let y_start = 15.0;
445
446 for i in 0..column_count {
447 let x = 1.5 * (2.0 * i as f32 - column_count as f32) * radius;
448
449 for j in 0..row_count {
450 let y = 4.0 * j as f32 * radius + y_start;
451
452 body_def.position = to_pos(Vec2 { x: x + side, y });
453 side = -side;
454
455 let body_id = create_body(world, &body_def);
456 create_polygon_shape(world, body_id, &shape_def, &polygon);
457 }
458 }
459
460 body_def.type_ = BodyType::Kinematic;
461 body_def.position = to_pos(VEC2_ZERO);
462 let pusher_id = create_body(world, &body_def);
463 JUNKYARD_PUSHER_ID.with(|id| id.set(pusher_id));
464 let box_shape = make_offset_box(2.0, 4.0, Vec2 { x: 0.0, y: 4.0 }, ROT_IDENTITY);
465 create_polygon_shape(world, pusher_id, &shape_def, &box_shape);
466}examples/benchmark/human/create.rs (line 54)
24pub fn create_human(
25 human: &mut Human,
26 world: &mut World,
27 position: Pos,
28 scale: f32,
29 friction_torque: f32,
30 hertz: f32,
31 damping_ratio: f32,
32 group_index: i32,
33 user_data: u64,
34 colorize: bool,
35) {
36 debug_assert!(!human.is_spawned);
37
38 for bone in human.bones.iter_mut() {
39 bone.body_id = BodyId::default();
40 bone.joint_id = JointId::default();
41 bone.friction_scale = 1.0;
42 bone.parent_index = -1;
43 }
44
45 human.original_scale = scale;
46 human.scale = scale;
47 human.friction_torque = friction_torque;
48
49 let mut body_def = default_body_def();
50 body_def.type_ = BodyType::Dynamic;
51 body_def.sleep_threshold = 0.1;
52 body_def.user_data = user_data;
53
54 let mut shape_def = default_shape_def();
55 shape_def.material.friction = 0.2;
56 shape_def.filter.group_index = -group_index;
57 shape_def.filter.category_bits = 2;
58 shape_def.filter.mask_bits = 1 | 2;
59
60 let mut foot_shape_def = shape_def;
61 foot_shape_def.material.friction = 0.05;
62 // feet don't collide with ragdolls
63 foot_shape_def.filter.category_bits = 2;
64 foot_shape_def.filter.mask_bits = 1;
65
66 if colorize {
67 foot_shape_def.material.custom_color = HexColor::SADDLE_BROWN.0;
68 }
69
70 let s = scale;
71 let max_torque = friction_torque * s;
72 let enable_motor = true;
73 let enable_limit = true;
74 let draw_size = 0.05;
75
76 let shirt_color = HexColor::MEDIUM_TURQUOISE;
77 let pant_color = HexColor::DODGER_BLUE;
78
79 let skin_colors = [
80 HexColor::NAVAJO_WHITE,
81 HexColor::LIGHT_YELLOW,
82 HexColor::PERU,
83 HexColor::TAN,
84 ];
85 let skin_color = skin_colors[(group_index % 4) as usize];
86
87 // hip
88 {
89 human.bones[BONE_HIP].parent_index = -1;
90
91 body_def.position = offset_pos(
92 position,
93 Vec2 {
94 x: 0.0,
95 y: 0.95 * s,
96 },
97 );
98 body_def.linear_damping = 0.0;
99 body_def.name = "hip".to_string();
100
101 let body_id = create_body(world, &body_def);
102 human.bones[BONE_HIP].body_id = body_id;
103
104 if colorize {
105 shape_def.material.custom_color = pant_color.0;
106 }
107
108 let capsule = Capsule {
109 center1: Vec2 {
110 x: 0.0,
111 y: -0.02 * s,
112 },
113 center2: Vec2 {
114 x: 0.0,
115 y: 0.02 * s,
116 },
117 radius: 0.095 * s,
118 };
119 create_capsule_shape(world, body_id, &shape_def, &capsule);
120 }
121
122 // torso
123 {
124 human.bones[BONE_TORSO].parent_index = BONE_HIP as i32;
125
126 body_def.position = offset_pos(position, Vec2 { x: 0.0, y: 1.2 * s });
127 body_def.linear_damping = 0.0;
128 body_def.name = "torso".to_string();
129
130 let body_id = create_body(world, &body_def);
131 human.bones[BONE_TORSO].body_id = body_id;
132 human.bones[BONE_TORSO].friction_scale = 0.5;
133 body_def.type_ = BodyType::Dynamic;
134
135 if colorize {
136 shape_def.material.custom_color = shirt_color.0;
137 }
138
139 let capsule = Capsule {
140 center1: Vec2 {
141 x: 0.0,
142 y: -0.135 * s,
143 },
144 center2: Vec2 {
145 x: 0.0,
146 y: 0.135 * s,
147 },
148 radius: 0.09 * s,
149 };
150 create_capsule_shape(world, body_id, &shape_def, &capsule);
151
152 let pivot = offset_pos(position, Vec2 { x: 0.0, y: 1.0 * s });
153 let parent = human.bones[BONE_HIP].body_id;
154 let joint_id = attach_revolute_joint(
155 world,
156 parent,
157 body_id,
158 pivot,
159 -0.25 * PI,
160 0.0,
161 enable_limit,
162 enable_motor,
163 human.bones[BONE_TORSO].friction_scale * max_torque,
164 hertz > 0.0,
165 hertz,
166 damping_ratio,
167 draw_size,
168 None,
169 );
170 human.bones[BONE_TORSO].joint_id = joint_id;
171 }
172
173 // head
174 {
175 human.bones[BONE_HEAD].parent_index = BONE_TORSO as i32;
176
177 body_def.position = offset_pos(
178 position,
179 Vec2 {
180 x: 0.0 * s,
181 y: 1.475 * s,
182 },
183 );
184 body_def.linear_damping = 0.1;
185 body_def.name = "head".to_string();
186
187 let body_id = create_body(world, &body_def);
188 human.bones[BONE_HEAD].body_id = body_id;
189 human.bones[BONE_HEAD].friction_scale = 0.25;
190
191 if colorize {
192 shape_def.material.custom_color = skin_color.0;
193 }
194
195 let capsule = Capsule {
196 center1: Vec2 {
197 x: 0.0,
198 y: -0.038 * s,
199 },
200 center2: Vec2 {
201 x: 0.0,
202 y: 0.039 * s,
203 },
204 radius: 0.075 * s,
205 };
206 create_capsule_shape(world, body_id, &shape_def, &capsule);
207
208 let pivot = offset_pos(position, Vec2 { x: 0.0, y: 1.4 * s });
209 let parent = human.bones[BONE_TORSO].body_id;
210 let joint_id = attach_revolute_joint(
211 world,
212 parent,
213 body_id,
214 pivot,
215 -0.3 * PI,
216 0.1 * PI,
217 enable_limit,
218 enable_motor,
219 human.bones[BONE_HEAD].friction_scale * max_torque,
220 hertz > 0.0,
221 hertz,
222 damping_ratio,
223 draw_size,
224 None,
225 );
226 human.bones[BONE_HEAD].joint_id = joint_id;
227 }
228
229 // upper left leg
230 {
231 human.bones[BONE_UPPER_LEFT_LEG].parent_index = BONE_HIP as i32;
232
233 body_def.position = offset_pos(
234 position,
235 Vec2 {
236 x: 0.0,
237 y: 0.775 * s,
238 },
239 );
240 body_def.linear_damping = 0.0;
241 body_def.name = "upper_left_leg".to_string();
242
243 let body_id = create_body(world, &body_def);
244 human.bones[BONE_UPPER_LEFT_LEG].body_id = body_id;
245 human.bones[BONE_UPPER_LEFT_LEG].friction_scale = 1.0;
246
247 if colorize {
248 shape_def.material.custom_color = pant_color.0;
249 }
250
251 let capsule = Capsule {
252 center1: Vec2 {
253 x: 0.0,
254 y: -0.125 * s,
255 },
256 center2: Vec2 {
257 x: 0.0,
258 y: 0.125 * s,
259 },
260 radius: 0.06 * s,
261 };
262 create_capsule_shape(world, body_id, &shape_def, &capsule);
263
264 let pivot = offset_pos(position, Vec2 { x: 0.0, y: 0.9 * s });
265 let parent = human.bones[BONE_HIP].body_id;
266 let joint_id = attach_revolute_joint(
267 world,
268 parent,
269 body_id,
270 pivot,
271 -0.05 * PI,
272 0.4 * PI,
273 enable_limit,
274 enable_motor,
275 human.bones[BONE_UPPER_LEFT_LEG].friction_scale * max_torque,
276 hertz > 0.0,
277 hertz,
278 damping_ratio,
279 draw_size,
280 None,
281 );
282 human.bones[BONE_UPPER_LEFT_LEG].joint_id = joint_id;
283 }
284
285 let foot_points = [
286 Vec2 {
287 x: -0.03 * s,
288 y: -0.185 * s,
289 },
290 Vec2 {
291 x: 0.11 * s,
292 y: -0.185 * s,
293 },
294 Vec2 {
295 x: 0.11 * s,
296 y: -0.16 * s,
297 },
298 Vec2 {
299 x: -0.03 * s,
300 y: -0.14 * s,
301 },
302 ];
303 let foot_hull = compute_hull(&foot_points);
304 let foot_polygon = make_polygon(&foot_hull, 0.015 * s);
305
306 // lower left leg
307 {
308 human.bones[BONE_LOWER_LEFT_LEG].parent_index = BONE_UPPER_LEFT_LEG as i32;
309
310 body_def.position = offset_pos(
311 position,
312 Vec2 {
313 x: 0.0,
314 y: 0.475 * s,
315 },
316 );
317 body_def.linear_damping = 0.0;
318 body_def.name = "lower_left_leg".to_string();
319
320 let body_id = create_body(world, &body_def);
321 human.bones[BONE_LOWER_LEFT_LEG].body_id = body_id;
322 human.bones[BONE_LOWER_LEFT_LEG].friction_scale = 0.5;
323
324 if colorize {
325 shape_def.material.custom_color = pant_color.0;
326 }
327
328 let capsule = Capsule {
329 center1: Vec2 {
330 x: 0.0,
331 y: -0.155 * s,
332 },
333 center2: Vec2 {
334 x: 0.0,
335 y: 0.125 * s,
336 },
337 radius: 0.045 * s,
338 };
339 create_capsule_shape(world, body_id, &shape_def, &capsule);
340
341 create_polygon_shape(world, body_id, &foot_shape_def, &foot_polygon);
342
343 let pivot = offset_pos(
344 position,
345 Vec2 {
346 x: 0.0,
347 y: 0.625 * s,
348 },
349 );
350 let parent = human.bones[BONE_UPPER_LEFT_LEG].body_id;
351 let joint_id = attach_revolute_joint(
352 world,
353 parent,
354 body_id,
355 pivot,
356 -0.5 * PI,
357 -0.02 * PI,
358 enable_limit,
359 enable_motor,
360 human.bones[BONE_LOWER_LEFT_LEG].friction_scale * max_torque,
361 hertz > 0.0,
362 hertz,
363 damping_ratio,
364 draw_size,
365 None,
366 );
367 human.bones[BONE_LOWER_LEFT_LEG].joint_id = joint_id;
368 }
369
370 // upper right leg
371 {
372 human.bones[BONE_UPPER_RIGHT_LEG].parent_index = BONE_HIP as i32;
373
374 body_def.position = offset_pos(
375 position,
376 Vec2 {
377 x: 0.0,
378 y: 0.775 * s,
379 },
380 );
381 body_def.linear_damping = 0.0;
382 body_def.name = "upper_right_leg".to_string();
383
384 let body_id = create_body(world, &body_def);
385 human.bones[BONE_UPPER_RIGHT_LEG].body_id = body_id;
386 human.bones[BONE_UPPER_RIGHT_LEG].friction_scale = 1.0;
387
388 if colorize {
389 shape_def.material.custom_color = pant_color.0;
390 }
391
392 let capsule = Capsule {
393 center1: Vec2 {
394 x: 0.0,
395 y: -0.125 * s,
396 },
397 center2: Vec2 {
398 x: 0.0,
399 y: 0.125 * s,
400 },
401 radius: 0.06 * s,
402 };
403 create_capsule_shape(world, body_id, &shape_def, &capsule);
404
405 let pivot = offset_pos(position, Vec2 { x: 0.0, y: 0.9 * s });
406 let parent = human.bones[BONE_HIP].body_id;
407 let joint_id = attach_revolute_joint(
408 world,
409 parent,
410 body_id,
411 pivot,
412 -0.05 * PI,
413 0.4 * PI,
414 enable_limit,
415 enable_motor,
416 human.bones[BONE_UPPER_RIGHT_LEG].friction_scale * max_torque,
417 hertz > 0.0,
418 hertz,
419 damping_ratio,
420 draw_size,
421 None,
422 );
423 human.bones[BONE_UPPER_RIGHT_LEG].joint_id = joint_id;
424 }
425
426 // lower right leg
427 {
428 human.bones[BONE_LOWER_RIGHT_LEG].parent_index = BONE_UPPER_RIGHT_LEG as i32;
429
430 body_def.position = offset_pos(
431 position,
432 Vec2 {
433 x: 0.0,
434 y: 0.475 * s,
435 },
436 );
437 body_def.linear_damping = 0.0;
438 body_def.name = "lower_right_leg".to_string();
439
440 let body_id = create_body(world, &body_def);
441 human.bones[BONE_LOWER_RIGHT_LEG].body_id = body_id;
442 human.bones[BONE_LOWER_RIGHT_LEG].friction_scale = 0.5;
443
444 if colorize {
445 shape_def.material.custom_color = pant_color.0;
446 }
447
448 let capsule = Capsule {
449 center1: Vec2 {
450 x: 0.0,
451 y: -0.155 * s,
452 },
453 center2: Vec2 {
454 x: 0.0,
455 y: 0.125 * s,
456 },
457 radius: 0.045 * s,
458 };
459 create_capsule_shape(world, body_id, &shape_def, &capsule);
460
461 create_polygon_shape(world, body_id, &foot_shape_def, &foot_polygon);
462
463 let pivot = offset_pos(
464 position,
465 Vec2 {
466 x: 0.0,
467 y: 0.625 * s,
468 },
469 );
470 let parent = human.bones[BONE_UPPER_RIGHT_LEG].body_id;
471 let joint_id = attach_revolute_joint(
472 world,
473 parent,
474 body_id,
475 pivot,
476 -0.5 * PI,
477 -0.02 * PI,
478 enable_limit,
479 enable_motor,
480 human.bones[BONE_LOWER_RIGHT_LEG].friction_scale * max_torque,
481 hertz > 0.0,
482 hertz,
483 damping_ratio,
484 draw_size,
485 None,
486 );
487 human.bones[BONE_LOWER_RIGHT_LEG].joint_id = joint_id;
488 }
489
490 // upper left arm
491 {
492 human.bones[BONE_UPPER_LEFT_ARM].parent_index = BONE_TORSO as i32;
493 human.bones[BONE_UPPER_LEFT_ARM].friction_scale = 0.5;
494
495 body_def.position = offset_pos(
496 position,
497 Vec2 {
498 x: 0.0,
499 y: 1.225 * s,
500 },
501 );
502 body_def.linear_damping = 0.0;
503 body_def.name = "upper_left_arm".to_string();
504
505 let body_id = create_body(world, &body_def);
506 human.bones[BONE_UPPER_LEFT_ARM].body_id = body_id;
507
508 if colorize {
509 shape_def.material.custom_color = shirt_color.0;
510 }
511
512 let capsule = Capsule {
513 center1: Vec2 {
514 x: 0.0,
515 y: -0.125 * s,
516 },
517 center2: Vec2 {
518 x: 0.0,
519 y: 0.125 * s,
520 },
521 radius: 0.035 * s,
522 };
523 create_capsule_shape(world, body_id, &shape_def, &capsule);
524
525 let pivot = offset_pos(
526 position,
527 Vec2 {
528 x: 0.0,
529 y: 1.35 * s,
530 },
531 );
532 let parent = human.bones[BONE_TORSO].body_id;
533 let joint_id = attach_revolute_joint(
534 world,
535 parent,
536 body_id,
537 pivot,
538 -0.1 * PI,
539 0.8 * PI,
540 enable_limit,
541 enable_motor,
542 human.bones[BONE_UPPER_LEFT_ARM].friction_scale * max_torque,
543 hertz > 0.0,
544 hertz,
545 damping_ratio,
546 draw_size,
547 None,
548 );
549 human.bones[BONE_UPPER_LEFT_ARM].joint_id = joint_id;
550 }
551
552 // lower left arm
553 {
554 human.bones[BONE_LOWER_LEFT_ARM].parent_index = BONE_UPPER_LEFT_ARM as i32;
555
556 body_def.position = offset_pos(
557 position,
558 Vec2 {
559 x: 0.0,
560 y: 0.975 * s,
561 },
562 );
563 body_def.linear_damping = 0.1;
564 body_def.name = "lower_left_arm".to_string();
565
566 let body_id = create_body(world, &body_def);
567 human.bones[BONE_LOWER_LEFT_ARM].body_id = body_id;
568 human.bones[BONE_LOWER_LEFT_ARM].friction_scale = 0.1;
569
570 if colorize {
571 shape_def.material.custom_color = skin_color.0;
572 }
573
574 let capsule = Capsule {
575 center1: Vec2 {
576 x: 0.0,
577 y: -0.125 * s,
578 },
579 center2: Vec2 {
580 x: 0.0,
581 y: 0.125 * s,
582 },
583 radius: 0.03 * s,
584 };
585 create_capsule_shape(world, body_id, &shape_def, &capsule);
586
587 let pivot = offset_pos(position, Vec2 { x: 0.0, y: 1.1 * s });
588 let parent = human.bones[BONE_UPPER_LEFT_ARM].body_id;
589 let joint_id = attach_revolute_joint(
590 world,
591 parent,
592 body_id,
593 pivot,
594 -0.2 * PI,
595 0.3 * PI,
596 enable_limit,
597 enable_motor,
598 human.bones[BONE_LOWER_LEFT_ARM].friction_scale * max_torque,
599 hertz > 0.0,
600 hertz,
601 damping_ratio,
602 draw_size,
603 Some(make_rot(0.25 * PI)),
604 );
605 human.bones[BONE_LOWER_LEFT_ARM].joint_id = joint_id;
606 }
607
608 // upper right arm
609 {
610 human.bones[BONE_UPPER_RIGHT_ARM].parent_index = BONE_TORSO as i32;
611
612 body_def.position = offset_pos(
613 position,
614 Vec2 {
615 x: 0.0,
616 y: 1.225 * s,
617 },
618 );
619 body_def.linear_damping = 0.0;
620 body_def.name = "upper_right_arm".to_string();
621
622 let body_id = create_body(world, &body_def);
623 human.bones[BONE_UPPER_RIGHT_ARM].body_id = body_id;
624 human.bones[BONE_UPPER_RIGHT_ARM].friction_scale = 0.5;
625
626 if colorize {
627 shape_def.material.custom_color = shirt_color.0;
628 }
629
630 let capsule = Capsule {
631 center1: Vec2 {
632 x: 0.0,
633 y: -0.125 * s,
634 },
635 center2: Vec2 {
636 x: 0.0,
637 y: 0.125 * s,
638 },
639 radius: 0.035 * s,
640 };
641 create_capsule_shape(world, body_id, &shape_def, &capsule);
642
643 let pivot = offset_pos(
644 position,
645 Vec2 {
646 x: 0.0,
647 y: 1.35 * s,
648 },
649 );
650 let parent = human.bones[BONE_TORSO].body_id;
651 let joint_id = attach_revolute_joint(
652 world,
653 parent,
654 body_id,
655 pivot,
656 -0.1 * PI,
657 0.8 * PI,
658 enable_limit,
659 enable_motor,
660 human.bones[BONE_UPPER_RIGHT_ARM].friction_scale * max_torque,
661 hertz > 0.0,
662 hertz,
663 damping_ratio,
664 draw_size,
665 None,
666 );
667 human.bones[BONE_UPPER_RIGHT_ARM].joint_id = joint_id;
668 }
669
670 // lower right arm
671 {
672 human.bones[BONE_LOWER_RIGHT_ARM].parent_index = BONE_UPPER_RIGHT_ARM as i32;
673
674 body_def.position = offset_pos(
675 position,
676 Vec2 {
677 x: 0.0,
678 y: 0.975 * s,
679 },
680 );
681 body_def.linear_damping = 0.1;
682 body_def.name = "lower_right_arm".to_string();
683
684 let body_id = create_body(world, &body_def);
685 human.bones[BONE_LOWER_RIGHT_ARM].body_id = body_id;
686 human.bones[BONE_LOWER_RIGHT_ARM].friction_scale = 0.1;
687
688 if colorize {
689 shape_def.material.custom_color = skin_color.0;
690 }
691
692 let capsule = Capsule {
693 center1: Vec2 {
694 x: 0.0,
695 y: -0.125 * s,
696 },
697 center2: Vec2 {
698 x: 0.0,
699 y: 0.125 * s,
700 },
701 radius: 0.03 * s,
702 };
703 create_capsule_shape(world, body_id, &shape_def, &capsule);
704
705 let pivot = offset_pos(position, Vec2 { x: 0.0, y: 1.1 * s });
706 let parent = human.bones[BONE_UPPER_RIGHT_ARM].body_id;
707 let joint_id = attach_revolute_joint(
708 world,
709 parent,
710 body_id,
711 pivot,
712 -0.2 * PI,
713 0.3 * PI,
714 enable_limit,
715 enable_motor,
716 human.bones[BONE_LOWER_RIGHT_ARM].friction_scale * max_torque,
717 hertz > 0.0,
718 hertz,
719 damping_ratio,
720 draw_size,
721 Some(make_rot(0.25 * PI)),
722 );
723 human.bones[BONE_LOWER_RIGHT_ARM].joint_id = joint_id;
724 }
725
726 human.is_spawned = true;
727}