1use box2d_rust::body::create_body;
5use box2d_rust::collision::{Circle, Segment};
6use box2d_rust::geometry::{make_box, make_offset_box, make_polygon, make_square};
7use box2d_rust::hull::compute_hull;
8use box2d_rust::id::BodyId;
9use box2d_rust::joint::create_revolute_joint;
10use box2d_rust::math_functions::{to_pos, Vec2, ROT_IDENTITY};
11use box2d_rust::shape::{create_circle_shape, create_polygon_shape, create_segment_shape};
12use box2d_rust::types::{
13 default_body_def, default_revolute_joint_def, default_shape_def, BodyType,
14};
15use box2d_rust::world::{world_enable_sleeping, World};
16
17use super::BENCHMARK_DEBUG;
18
19pub 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
81pub 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
122fn 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
150pub 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
197pub 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 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}