-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathrbd_compound3.rs
More file actions
123 lines (112 loc) · 4.2 KB
/
Copy pathrbd_compound3.rs
File metadata and controls
123 lines (112 loc) · 4.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
use khal::backend::GpuTimestamps;
use nexus_viewer3d::NexusViewer;
use nexus3d::prelude::{NexusCapacities, NexusPipeline, NexusState, RbdCoupling};
use rapier3d::prelude::*;
/// Port of rapier's `compound3` demo, but every "U"-shaped body is assembled
/// from three separate colliders attached to one rigid body instead of a single
/// compound collider, which exercises multiple-colliders-per-body support.
pub async fn run(
viewer: &mut NexusViewer,
pipeline: &mut NexusPipeline,
) -> anyhow::Result<NexusState> {
let capacities = NexusCapacities::default().rbd_collisions(280_000);
let mut state = NexusState::new(capacities);
let no_coupling = RbdCoupling::None;
/*
* Floor made of large cuboids.
*/
{
let thick = 50.0;
let height = 7.0;
let walls_color = Vec4::new(0.6, 0.8, 1.0, 0.3);
let walls = [
(Vec3::new(0.0, -0.5, 0.0), Vec3::new(thick, 0.5, thick)),
(Vec3::new(thick, height, 0.0), Vec3::new(0.5, height, thick)),
(
Vec3::new(-thick, height, 0.0),
Vec3::new(0.5, height, thick),
),
(Vec3::new(0.0, height, thick), Vec3::new(thick, height, 0.5)),
(
Vec3::new(0.0, height, -thick),
Vec3::new(thick, height, 0.5),
),
];
for (wall_pos, wall_sz) in walls {
let body = RigidBodyBuilder::fixed().build();
let collider = ColliderBuilder::cuboid(wall_sz.x, wall_sz.y, wall_sz.z)
.translation(wall_pos)
.build();
let shape = collider.shared_shape().clone();
let handle = state.insert_rigid_body(body, collider, no_coupling);
viewer.insert_shape_with_color(
handle,
&shape,
Pose::from_translation(wall_pos),
walls_color,
);
}
}
/*
* "U"-shaped bodies, each made of three cuboid colliders: a horizontal base
* and two vertical walls, forming an upward-opening cup. `(local_pose,
* half_extents)` for the three parts.
*/
let rad = 0.2f32;
let parts: [(Vec3, Vec3); 3] = [
(Vec3::ZERO, Vec3::new(rad * 10.0, rad, rad)),
(
Vec3::new(rad * 10.0, rad * 10.0, 0.0),
Vec3::new(rad, rad * 10.0, rad),
),
(
Vec3::new(-rad * 10.0, rad * 10.0, 0.0),
Vec3::new(rad, rad * 10.0, rad),
),
];
let num = 10;
let numy = 100;
// Each U spans ~4 units in x; space the grid out so they don't start
// interpenetrating.
let shift = rad * 10.0 * 2.0 + 1.0;
let center = shift * (num as f32) / 2.0;
for j in 0..numy {
for i in 0..num {
for k in 0..num {
let x = i as f32 * shift - center;
let y = j as f32 * shift + 5.0;
let z = k as f32 * shift - center;
let body = RigidBodyBuilder::dynamic()
.translation(Vec3::new(x, y, z))
.build();
let handle = state.insert_body_in(0, body, no_coupling);
for (offset, he) in parts {
let collider = ColliderBuilder::cuboid(he.x, he.y, he.z)
.translation(offset)
.build();
viewer.insert_shape(
handle,
collider.shared_shape(),
Pose::from_translation(offset),
);
state.insert_collider_in(0, collider, Some(handle));
}
}
}
}
// Optional, useful so we can render even before starting the simulation.
let mut timestamps = GpuTimestamps::new(viewer.backend(), 2048);
viewer
.scene3d_mut()
.add_directional_light(glamx::Vec3::new(1.0, -2.0, 3.0));
state.finalize(viewer.backend()).await?;
while viewer.render_frame().await {
if viewer.simulating() {
pipeline
.simulate(viewer.backend(), &mut state, Some(&mut timestamps))
.await?;
}
viewer.sync(&mut state, Some(&mut timestamps)).await?;
}
Ok(state)
}