Skip to main content

default_shape_def

Function default_shape_def 

Source
pub fn default_shape_def() -> ShapeDef
Expand 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
Hide additional 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}