1
- use rapier2d:: parry:: bounding_volume;
2
1
use rapier2d:: parry:: transformation:: voxelization:: FillMode ;
3
2
use rapier2d:: prelude:: * ;
4
3
use rapier_testbed2d:: Testbed ;
5
- use std:: fs:: File ;
6
- use std:: io:: BufReader ;
7
4
use std:: path:: Path ;
8
5
9
6
const VOXEL_SIZE : Real = 0.1 ; // 0.25;
@@ -18,13 +15,23 @@ pub fn init_world(testbed: &mut Testbed) {
18
15
let geometry_mode = settings. get_or_set_string (
19
16
"Voxels mode" ,
20
17
0 ,
21
- vec ! [ "PseudoBall" . to_string( ) , "PseudoCube" . to_string( ) ] ,
18
+ vec ! [ "PseudoCube" . to_string( ) , "PseudoBall" . to_string( ) ] ,
19
+ ) ;
20
+ let falling_objects = settings. get_or_set_string (
21
+ "Falling objects" ,
22
+ 3 , // Defaults to Mixed.
23
+ vec ! [
24
+ "Ball" . to_string( ) ,
25
+ "Cuboid" . to_string( ) ,
26
+ "Capsule" . to_string( ) ,
27
+ "Mixed" . to_string( ) ,
28
+ ] ,
22
29
) ;
23
30
24
31
let primitive_geometry = if geometry_mode == 0 {
25
- VoxelPrimitiveGeometry :: PseudoBall
26
- } else {
27
32
VoxelPrimitiveGeometry :: PseudoCube
33
+ } else {
34
+ VoxelPrimitiveGeometry :: PseudoBall
28
35
} ;
29
36
30
37
/*
@@ -36,79 +43,30 @@ pub fn init_world(testbed: &mut Testbed) {
36
43
let multibody_joints = MultibodyJointSet :: new ( ) ;
37
44
38
45
/*
39
- * Create the convex decompositions .
46
+ * Create dynamic objects to fall on voxels .
40
47
*/
41
- // let geoms = models();
42
- // let ngeoms = geoms.len();
43
- // let width = (ngeoms as f32).sqrt() as usize;
44
- // let num_duplications = 1; // 4;
45
- // let shift = 7.0f32;
46
- //
47
- // for (igeom, obj_path) in geoms.into_iter().enumerate() {
48
- // let deltas = Isometry::identity();
49
- //
50
- // let mut shapes = Vec::new();
51
- // println!("Parsing and decomposing: {}", obj_path);
52
- //
53
- // let input = BufReader::new(File::open(obj_path).unwrap());
54
- //
55
- // if let Ok(model) = obj::raw::parse_obj(input) {
56
- // let mut vertices: Vec<_> = model
57
- // .positions
58
- // .iter()
59
- // .map(|v| point![v.0, v.1, v.2])
60
- // .collect();
61
- // let indices: Vec<_> = model
62
- // .polygons
63
- // .into_iter()
64
- // .flat_map(|p| match p {
65
- // Polygon::P(idx) => idx.into_iter(),
66
- // Polygon::PT(idx) => Vec::from_iter(idx.into_iter().map(|i| i.0)).into_iter(),
67
- // Polygon::PN(idx) => Vec::from_iter(idx.into_iter().map(|i| i.0)).into_iter(),
68
- // Polygon::PTN(idx) => Vec::from_iter(idx.into_iter().map(|i| i.0)).into_iter(),
69
- // })
70
- // .collect();
71
- //
72
- // // Compute the size of the model, to scale it and have similar size for everything.
73
- // let aabb = bounding_volume::details::point_cloud_aabb(&deltas, &vertices);
74
- // let center = aabb.center();
75
- // let diag = (aabb.maxs - aabb.mins).norm();
76
- //
77
- // vertices
78
- // .iter_mut()
79
- // .for_each(|p| *p = (*p - center.coords) * 6.0 / diag);
80
- //
81
- // let indices: Vec<_> = indices
82
- // .chunks(3)
83
- // .map(|idx| [idx[0] as u32, idx[1] as u32, idx[2] as u32])
84
- // .collect();
85
- //
86
- // let decomposed_shape =
87
- // SharedShape::voxelized_mesh(&vertices, &indices, VOXEL_SIZE, FillMode::default());
88
- // shapes.push(decomposed_shape);
89
- //
90
- // for k in 1..num_duplications + 1 {
91
- // let x = (igeom % width) as f32 * shift - 3.0;
92
- // let y = (igeom / width) as f32 * shift + 4.0;
93
- // let z = k as f32 * shift - 3.0;
94
- //
95
- // let body = RigidBodyBuilder::fixed().translation(vector![x, y, z]);
96
- // let handle = bodies.insert(body);
97
- //
98
- // for shape in &shapes {
99
- // let collider = ColliderBuilder::new(shape.clone());
100
- // colliders.insert_with_parent(collider, handle, &mut bodies);
101
- // }
102
- // }
103
- // }
104
- // }
105
-
106
- for i in 0 ..30 {
107
- for j in 0 ..5 {
108
- let rb = RigidBodyBuilder :: dynamic ( )
109
- . translation ( vector ! [ i as f32 * 2.0 , 20.0 + j as f32 * 2.0 ] ) ;
48
+ let nx = 50 ;
49
+ for i in 0 ..nx {
50
+ for j in 0 ..10 {
51
+ let rb = RigidBodyBuilder :: dynamic ( ) . translation ( vector ! [
52
+ i as f32 * 2.0 - nx as f32 / 2.0 ,
53
+ 20.0 + j as f32 * 2.0
54
+ ] ) ;
110
55
let rb_handle = bodies. insert ( rb) ;
111
- let co = ColliderBuilder :: ball ( 1.0 ) ;
56
+
57
+ let falling_objects = if falling_objects == 3 {
58
+ j % 3
59
+ } else {
60
+ falling_objects
61
+ } ;
62
+
63
+ let ball_radius = 0.5 ;
64
+ let co = match falling_objects {
65
+ 0 => ColliderBuilder :: ball ( ball_radius) ,
66
+ 1 => ColliderBuilder :: cuboid ( ball_radius, ball_radius) ,
67
+ 2 => ColliderBuilder :: capsule_y ( ball_radius, ball_radius) ,
68
+ _ => unreachable ! ( ) ,
69
+ } ;
112
70
colliders. insert_with_parent ( co, rb_handle, & mut bodies) ;
113
71
}
114
72
}
@@ -129,7 +87,7 @@ pub fn init_world(testbed: &mut Testbed) {
129
87
let indices: Vec < _ > = ( 0 ..polyline. len ( ) as u32 )
130
88
. map ( |i| [ i, ( i + 1 ) % polyline. len ( ) as u32 ] )
131
89
. collect ( ) ;
132
- let rb = bodies. insert ( RigidBodyBuilder :: fixed ( ) ) ;
90
+ let rb = bodies. insert ( RigidBodyBuilder :: fixed ( ) . translation ( vector ! [ - 20.0 , - 10.0 ] ) ) ;
133
91
let shape = SharedShape :: voxelized_mesh (
134
92
primitive_geometry,
135
93
& polyline,
@@ -141,48 +99,19 @@ pub fn init_world(testbed: &mut Testbed) {
141
99
colliders. insert_with_parent ( ColliderBuilder :: new ( shape) , rb, & mut bodies) ;
142
100
143
101
/*
144
- * Load .vox file .
102
+ * A voxel wavy floor .
145
103
*/
146
- let path = "/Users/sebcrozet/Downloads/droid_one.vox" ;
147
-
148
- for i in 0 ..3 {
149
- for shape in voxels_from_dot_vox ( primitive_geometry, path, 1.0 ) {
150
- let rb = bodies. insert (
151
- RigidBodyBuilder :: fixed ( )
152
- . rotation ( -3.14 / 2.0 )
153
- . translation ( vector ! [ 0.0 , 10.0 + 50.0 * i as f32 ] ) ,
154
- ) ;
155
- colliders. insert_with_parent ( ColliderBuilder :: new ( shape) , rb, & mut bodies) ;
156
- }
157
- }
158
-
159
- /*
160
- * Floor
161
- */
162
- colliders. insert ( ColliderBuilder :: cuboid ( 100.0 , 1.0 ) . translation ( vector ! [ 0.0 , -40.0 ] ) ) ;
104
+ let voxels: Vec < _ > = ( 0 ..300 )
105
+ . map ( |i| {
106
+ let y = ( i as f32 / 20.0 ) . sin ( ) . clamp ( -0.5 , 0.5 ) * 20.0 ;
107
+ point ! [ ( i as f32 - 125.0 ) / 2.0 , y]
108
+ } )
109
+ . collect ( ) ;
110
+ colliders. insert ( ColliderBuilder :: voxels ( primitive_geometry, & voxels, 1.0 ) ) ;
163
111
164
112
/*
165
113
* Set up the testbed.
166
114
*/
167
115
testbed. set_world ( bodies, colliders, impulse_joints, multibody_joints) ;
168
116
testbed. look_at ( point ! [ 0.0 , 20.0 ] , 17.0 ) ;
169
117
}
170
-
171
- fn voxels_from_dot_vox (
172
- primitive_geometry : VoxelPrimitiveGeometry ,
173
- path : impl AsRef < Path > ,
174
- voxel_size : Real ,
175
- ) -> Vec < SharedShape > {
176
- let data = dot_vox:: load ( path. as_ref ( ) . to_str ( ) . unwrap ( ) ) . unwrap ( ) ;
177
- data. models
178
- . iter ( )
179
- . map ( |model| {
180
- let centers: Vec < _ > = model
181
- . voxels
182
- . iter ( )
183
- . map ( |v| Point :: new ( v. y as f32 , v. z as f32 ) * voxel_size) // FIXME: avoid duplicates
184
- . collect ( ) ;
185
- SharedShape :: voxels ( primitive_geometry, & centers, voxel_size)
186
- } )
187
- . collect ( )
188
- }
0 commit comments