1- use rapier2d:: parry:: bounding_volume;
21use rapier2d:: parry:: transformation:: voxelization:: FillMode ;
32use rapier2d:: prelude:: * ;
43use rapier_testbed2d:: Testbed ;
5- use std:: fs:: File ;
6- use std:: io:: BufReader ;
74use std:: path:: Path ;
85
96const VOXEL_SIZE : Real = 0.1 ; // 0.25;
@@ -18,13 +15,23 @@ pub fn init_world(testbed: &mut Testbed) {
1815 let geometry_mode = settings. get_or_set_string (
1916 "Voxels mode" ,
2017 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+ ] ,
2229 ) ;
2330
2431 let primitive_geometry = if geometry_mode == 0 {
25- VoxelPrimitiveGeometry :: PseudoBall
26- } else {
2732 VoxelPrimitiveGeometry :: PseudoCube
33+ } else {
34+ VoxelPrimitiveGeometry :: PseudoBall
2835 } ;
2936
3037 /*
@@ -36,79 +43,30 @@ pub fn init_world(testbed: &mut Testbed) {
3643 let multibody_joints = MultibodyJointSet :: new ( ) ;
3744
3845 /*
39- * Create the convex decompositions .
46+ * Create dynamic objects to fall on voxels .
4047 */
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+ ] ) ;
11055 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+ } ;
11270 colliders. insert_with_parent ( co, rb_handle, & mut bodies) ;
11371 }
11472 }
@@ -129,7 +87,7 @@ pub fn init_world(testbed: &mut Testbed) {
12987 let indices: Vec < _ > = ( 0 ..polyline. len ( ) as u32 )
13088 . map ( |i| [ i, ( i + 1 ) % polyline. len ( ) as u32 ] )
13189 . collect ( ) ;
132- let rb = bodies. insert ( RigidBodyBuilder :: fixed ( ) ) ;
90+ let rb = bodies. insert ( RigidBodyBuilder :: fixed ( ) . translation ( vector ! [ - 20.0 , - 10.0 ] ) ) ;
13391 let shape = SharedShape :: voxelized_mesh (
13492 primitive_geometry,
13593 & polyline,
@@ -141,48 +99,19 @@ pub fn init_world(testbed: &mut Testbed) {
14199 colliders. insert_with_parent ( ColliderBuilder :: new ( shape) , rb, & mut bodies) ;
142100
143101 /*
144- * Load .vox file .
102+ * A voxel wavy floor .
145103 */
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 ) ) ;
163111
164112 /*
165113 * Set up the testbed.
166114 */
167115 testbed. set_world ( bodies, colliders, impulse_joints, multibody_joints) ;
168116 testbed. look_at ( point ! [ 0.0 , 20.0 ] , 17.0 ) ;
169117}
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