feat: migrate to glam whenever relevant + migrate testbed to kiss3d instead of bevy + release v0.32.0 (#909)
* feat: migrate to glam whenever relevant + migrate testbed to kiss3d instead of bevy * chore: update changelog * Fix warnings and tests * Release v0.32.0
This commit is contained in:
53
examples3d/stress_tests/balls3.rs
Normal file
53
examples3d/stress_tests/balls3.rs
Normal file
@@ -0,0 +1,53 @@
|
||||
use glam::Vec3;
|
||||
use rapier_testbed3d::Testbed;
|
||||
use rapier3d::prelude::*;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* World
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Create the balls
|
||||
*/
|
||||
let num = 20;
|
||||
let rad = 1.0;
|
||||
|
||||
let shift = rad * 2.0 + 1.0;
|
||||
let centerx = shift * (num as f32) / 2.0;
|
||||
let centery = shift / 2.0;
|
||||
let centerz = shift * (num as f32) / 2.0;
|
||||
|
||||
for i in 0..num {
|
||||
for j in 0usize..num {
|
||||
for k in 0..num {
|
||||
let x = i as f32 * shift - centerx;
|
||||
let y = j as f32 * shift + centery;
|
||||
let z = k as f32 * shift - centerz;
|
||||
|
||||
let status = if j == 0 {
|
||||
RigidBodyType::Fixed
|
||||
} else {
|
||||
RigidBodyType::Dynamic
|
||||
};
|
||||
let density = 0.477;
|
||||
|
||||
// Build the rigid body.
|
||||
let rigid_body = RigidBodyBuilder::new(status).translation(Vec3::new(x, y, z));
|
||||
let handle = bodies.insert(rigid_body);
|
||||
let collider = ColliderBuilder::ball(rad).density(density);
|
||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(Vec3::new(100.0, 100.0, 100.0), Vec3::ZERO);
|
||||
}
|
||||
60
examples3d/stress_tests/boxes3.rs
Normal file
60
examples3d/stress_tests/boxes3.rs
Normal file
@@ -0,0 +1,60 @@
|
||||
use rapier_testbed3d::Testbed;
|
||||
use rapier3d::prelude::*;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* World
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
*/
|
||||
let ground_size = 200.1;
|
||||
let ground_height = 0.1;
|
||||
|
||||
let rigid_body = RigidBodyBuilder::fixed().translation(Vec3::new(0.0, -ground_height, 0.0));
|
||||
let handle = bodies.insert(rigid_body);
|
||||
let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size);
|
||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||
|
||||
/*
|
||||
* Create the cubes
|
||||
*/
|
||||
let num = 10;
|
||||
let rad = 1.0;
|
||||
|
||||
let shift = rad * 2.0;
|
||||
let centerx = shift * (num / 2) as f32;
|
||||
let centery = shift / 2.0;
|
||||
let centerz = shift * (num / 2) as f32;
|
||||
|
||||
let mut offset = -(num as f32) * (rad * 2.0) * 0.5;
|
||||
|
||||
for j in 0usize..num {
|
||||
for i in 0..num {
|
||||
for k in 0usize..num {
|
||||
let x = i as f32 * shift - centerx + offset;
|
||||
let y = j as f32 * shift + centery;
|
||||
let z = k as f32 * shift - centerz + offset;
|
||||
|
||||
// Build the rigid body.
|
||||
let rigid_body = RigidBodyBuilder::dynamic().translation(Vec3::new(x, y, z));
|
||||
let handle = bodies.insert(rigid_body);
|
||||
let collider = ColliderBuilder::cuboid(rad, rad, rad);
|
||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||
}
|
||||
}
|
||||
|
||||
offset -= 0.05 * rad * (num as f32 - 1.0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(Vec3::new(100.0, 100.0, 100.0), Vec3::ZERO);
|
||||
}
|
||||
61
examples3d/stress_tests/capsules3.rs
Normal file
61
examples3d/stress_tests/capsules3.rs
Normal file
@@ -0,0 +1,61 @@
|
||||
use rapier_testbed3d::Testbed;
|
||||
use rapier3d::prelude::*;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* World
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
*/
|
||||
let ground_size = 200.1;
|
||||
let ground_height = 0.1;
|
||||
|
||||
let rigid_body = RigidBodyBuilder::fixed().translation(Vec3::new(0.0, -ground_height, 0.0));
|
||||
let handle = bodies.insert(rigid_body);
|
||||
let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size);
|
||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||
|
||||
/*
|
||||
* Create the cubes
|
||||
*/
|
||||
let num = 8;
|
||||
let rad = 1.0;
|
||||
|
||||
let shift = rad * 2.0 + rad;
|
||||
let shifty = rad * 4.0;
|
||||
let centerx = shift * (num / 2) as f32;
|
||||
let centery = shift / 2.0;
|
||||
let centerz = shift * (num / 2) as f32;
|
||||
|
||||
let mut offset = -(num as f32) * (rad * 2.0 + rad) * 0.5;
|
||||
|
||||
for j in 0usize..47 {
|
||||
for i in 0..num {
|
||||
for k in 0usize..num {
|
||||
let x = i as f32 * shift - centerx + offset;
|
||||
let y = j as f32 * shifty + centery + 3.0;
|
||||
let z = k as f32 * shift - centerz + offset;
|
||||
|
||||
// Build the rigid body.
|
||||
let rigid_body = RigidBodyBuilder::dynamic().translation(Vec3::new(x, y, z));
|
||||
let handle = bodies.insert(rigid_body);
|
||||
let collider = ColliderBuilder::capsule_y(rad, rad);
|
||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||
}
|
||||
}
|
||||
|
||||
offset -= 0.05 * rad * (num as f32 - 1.0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(Vec3::new(100.0, 100.0, 100.0), Vec3::ZERO);
|
||||
}
|
||||
76
examples3d/stress_tests/ccd3.rs
Normal file
76
examples3d/stress_tests/ccd3.rs
Normal file
@@ -0,0 +1,76 @@
|
||||
use rapier_testbed3d::Testbed;
|
||||
use rapier3d::prelude::*;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* World
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
*/
|
||||
let ground_size = 100.1;
|
||||
let ground_height = 0.1;
|
||||
|
||||
let rigid_body = RigidBodyBuilder::fixed().translation(Vec3::new(0.0, -ground_height, 0.0));
|
||||
let handle = bodies.insert(rigid_body);
|
||||
let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size);
|
||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||
|
||||
/*
|
||||
* Create the cubes
|
||||
*/
|
||||
let num = 4;
|
||||
let numj = 20;
|
||||
let rad = 1.0;
|
||||
|
||||
let shiftx = rad * 2.0 + rad;
|
||||
let shifty = rad * 2.0 + rad;
|
||||
let shiftz = rad * 2.0 + rad;
|
||||
let centerx = shiftx * (num / 2) as f32;
|
||||
let centery = shifty / 2.0;
|
||||
let centerz = shiftz * (num / 2) as f32;
|
||||
|
||||
let mut offset = -(num as f32) * (rad * 2.0 + rad) * 0.5;
|
||||
|
||||
for j in 0usize..numj {
|
||||
for i in 0..num {
|
||||
for k in 0usize..num {
|
||||
let x = i as f32 * shiftx - centerx + offset;
|
||||
let y = j as f32 * shifty + centery + 3.0;
|
||||
let z = k as f32 * shiftz - centerz + offset;
|
||||
|
||||
// Build the rigid body.
|
||||
let rigid_body = RigidBodyBuilder::dynamic()
|
||||
.translation(Vec3::new(x, y, z))
|
||||
.linvel(Vec3::new(0.0, -1000.0, 0.0))
|
||||
.ccd_enabled(true);
|
||||
let handle = bodies.insert(rigid_body);
|
||||
|
||||
let collider = match j % 5 {
|
||||
0 => ColliderBuilder::cuboid(rad, rad, rad),
|
||||
1 => ColliderBuilder::ball(rad),
|
||||
// Rounded cylinders are much more efficient that cylinder, even if the
|
||||
// rounding margin is small.
|
||||
2 => ColliderBuilder::round_cylinder(rad, rad, rad / 10.0),
|
||||
3 => ColliderBuilder::cone(rad, rad),
|
||||
_ => ColliderBuilder::capsule_y(rad, rad),
|
||||
};
|
||||
|
||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||
}
|
||||
}
|
||||
|
||||
offset -= 0.05 * rad * (num as f32 - 1.0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(Vec3::new(100.0, 100.0, 100.0), Vec3::ZERO);
|
||||
}
|
||||
66
examples3d/stress_tests/compound3.rs
Normal file
66
examples3d/stress_tests/compound3.rs
Normal file
@@ -0,0 +1,66 @@
|
||||
use rapier_testbed3d::Testbed;
|
||||
use rapier3d::prelude::*;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* World
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
*/
|
||||
let ground_size = 200.1;
|
||||
let ground_height = 0.1;
|
||||
|
||||
let rigid_body = RigidBodyBuilder::fixed().translation(Vec3::new(0.0, -ground_height, 0.0));
|
||||
let handle = bodies.insert(rigid_body);
|
||||
let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size);
|
||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||
|
||||
/*
|
||||
* Create the cubes
|
||||
*/
|
||||
let num = 8;
|
||||
let rad = 0.2;
|
||||
|
||||
let shift = rad * 4.0 + rad;
|
||||
let centerx = shift * (num / 2) as f32;
|
||||
let centery = shift / 2.0;
|
||||
let centerz = shift * (num / 2) as f32;
|
||||
|
||||
let mut offset = -(num as f32) * (rad * 2.0 + rad) * 0.5;
|
||||
|
||||
for j in 0usize..25 {
|
||||
for i in 0..num {
|
||||
for k in 0usize..num {
|
||||
let x = i as f32 * shift * 5.0 - centerx + offset;
|
||||
let y = j as f32 * (shift * 5.0) + centery + 3.0;
|
||||
let z = k as f32 * shift * 2.0 - centerz + offset;
|
||||
|
||||
// Build the rigid body.
|
||||
let rigid_body = RigidBodyBuilder::dynamic().translation(Vec3::new(x, y, z));
|
||||
let handle = bodies.insert(rigid_body);
|
||||
let collider1 = ColliderBuilder::cuboid(rad * 10.0, rad, rad);
|
||||
let collider2 = ColliderBuilder::cuboid(rad, rad * 10.0, rad)
|
||||
.translation(Vec3::new(rad * 10.0, rad * 10.0, 0.0));
|
||||
let collider3 = ColliderBuilder::cuboid(rad, rad * 10.0, rad)
|
||||
.translation(Vec3::new(-rad * 10.0, rad * 10.0, 0.0));
|
||||
colliders.insert_with_parent(collider1, handle, &mut bodies);
|
||||
colliders.insert_with_parent(collider2, handle, &mut bodies);
|
||||
colliders.insert_with_parent(collider3, handle, &mut bodies);
|
||||
}
|
||||
}
|
||||
|
||||
offset -= 0.05 * rad * (num as f32 - 1.0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(Vec3::new(100.0, 100.0, 100.0), Vec3::ZERO);
|
||||
}
|
||||
73
examples3d/stress_tests/convex_polyhedron3.rs
Normal file
73
examples3d/stress_tests/convex_polyhedron3.rs
Normal file
@@ -0,0 +1,73 @@
|
||||
use rand::distr::{Distribution, StandardUniform};
|
||||
use rand::{SeedableRng, rngs::StdRng};
|
||||
use rapier_testbed3d::Testbed;
|
||||
use rapier3d::prelude::*;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* World
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
*/
|
||||
let ground_size = 200.1;
|
||||
let ground_height = 0.1;
|
||||
|
||||
let rigid_body = RigidBodyBuilder::fixed().translation(Vec3::new(0.0, -ground_height, 0.0));
|
||||
let handle = bodies.insert(rigid_body);
|
||||
let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size);
|
||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||
|
||||
/*
|
||||
* Create the cubes
|
||||
*/
|
||||
let num = 8;
|
||||
let scale = 2.0;
|
||||
let rad = 1.0;
|
||||
let border_rad = 0.1;
|
||||
|
||||
let shift = border_rad * 2.0 + scale;
|
||||
let centerx = shift * (num / 2) as f32;
|
||||
let centery = shift / 2.0;
|
||||
let centerz = shift * (num / 2) as f32;
|
||||
|
||||
let mut offset = -(num as f32) * shift * 0.5;
|
||||
|
||||
let mut rng = StdRng::seed_from_u64(0);
|
||||
let distribution = StandardUniform;
|
||||
|
||||
for j in 0usize..47 {
|
||||
for i in 0..num {
|
||||
for k in 0usize..num {
|
||||
let x = i as f32 * shift - centerx + offset;
|
||||
let y = j as f32 * shift + centery + 3.0;
|
||||
let z = k as f32 * shift - centerz + offset;
|
||||
|
||||
let mut points = Vec::new();
|
||||
for _ in 0..10 {
|
||||
let pt: [f32; 3] = distribution.sample(&mut rng);
|
||||
points.push(Vec3::from(pt) * scale);
|
||||
}
|
||||
|
||||
// Build the rigid body.
|
||||
let rigid_body = RigidBodyBuilder::dynamic().translation(Vec3::new(x, y, z));
|
||||
let handle = bodies.insert(rigid_body);
|
||||
let collider = ColliderBuilder::round_convex_hull(&points, border_rad).unwrap();
|
||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||
}
|
||||
}
|
||||
|
||||
offset -= 0.05 * rad * (num as f32 - 1.0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(Vec3::new(100.0, 100.0, 100.0), Vec3::ZERO);
|
||||
}
|
||||
77
examples3d/stress_tests/heightfield3.rs
Normal file
77
examples3d/stress_tests/heightfield3.rs
Normal file
@@ -0,0 +1,77 @@
|
||||
use rapier_testbed3d::Testbed;
|
||||
use rapier3d::na::ComplexField;
|
||||
use rapier3d::prelude::*;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* World
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
*/
|
||||
let ground_size = Vec3::new(200.0, 1.0, 200.0);
|
||||
let nsubdivs = 20;
|
||||
|
||||
let heights = Array2::from_fn(nsubdivs + 1, nsubdivs + 1, |i, j| {
|
||||
if i == 0 || i == nsubdivs || j == 0 || j == nsubdivs {
|
||||
10.0
|
||||
} else {
|
||||
let x = i as f32 * ground_size.x / (nsubdivs as f32);
|
||||
let z = j as f32 * ground_size.z / (nsubdivs as f32);
|
||||
|
||||
// NOTE: make sure we use the sin/cos from simba to ensure
|
||||
// cross-platform determinism of the example when the
|
||||
// enhanced_determinism feature is enabled.
|
||||
<f32 as ComplexField>::sin(x) + <f32 as ComplexField>::cos(z)
|
||||
}
|
||||
});
|
||||
|
||||
let rigid_body = RigidBodyBuilder::fixed();
|
||||
let handle = bodies.insert(rigid_body);
|
||||
let collider = ColliderBuilder::heightfield(heights, ground_size);
|
||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||
|
||||
/*
|
||||
* Create the cubes
|
||||
*/
|
||||
let num = 8;
|
||||
let rad = 1.0;
|
||||
|
||||
let shift = rad * 2.0 + rad;
|
||||
let centerx = shift * (num / 2) as f32;
|
||||
let centery = shift / 2.0;
|
||||
let centerz = shift * (num / 2) as f32;
|
||||
|
||||
for j in 0usize..47 {
|
||||
for i in 0..num {
|
||||
for k in 0usize..num {
|
||||
let x = i as f32 * shift - centerx;
|
||||
let y = j as f32 * shift + centery + 3.0;
|
||||
let z = k as f32 * shift - centerz;
|
||||
|
||||
// Build the rigid body.
|
||||
let rigid_body = RigidBodyBuilder::dynamic().translation(Vec3::new(x, y, z));
|
||||
let handle = bodies.insert(rigid_body);
|
||||
|
||||
if j % 2 == 0 {
|
||||
let collider = ColliderBuilder::cuboid(rad, rad, rad);
|
||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||
} else {
|
||||
let collider = ColliderBuilder::ball(rad);
|
||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(Vec3::new(100.0, 100.0, 100.0), Vec3::ZERO);
|
||||
}
|
||||
63
examples3d/stress_tests/joint_ball3.rs
Normal file
63
examples3d/stress_tests/joint_ball3.rs
Normal file
@@ -0,0 +1,63 @@
|
||||
use rapier_testbed3d::Testbed;
|
||||
use rapier3d::prelude::*;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* World
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let mut impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
let rad = 0.4;
|
||||
let num = 100;
|
||||
let shift = 1.0;
|
||||
|
||||
let mut body_handles = Vec::new();
|
||||
|
||||
for k in 0..num {
|
||||
for i in 0..num {
|
||||
let fk = k as f32;
|
||||
let fi = i as f32;
|
||||
|
||||
let status = if i == 0 && (k % 4 == 0 || k == num - 1) {
|
||||
RigidBodyType::Fixed
|
||||
} else {
|
||||
RigidBodyType::Dynamic
|
||||
};
|
||||
|
||||
let rigid_body =
|
||||
RigidBodyBuilder::new(status).translation(Vec3::new(fk * shift, 0.0, fi * shift));
|
||||
let child_handle = bodies.insert(rigid_body);
|
||||
let collider = ColliderBuilder::ball(rad);
|
||||
colliders.insert_with_parent(collider, child_handle, &mut bodies);
|
||||
|
||||
// Vertical joint.
|
||||
if i > 0 {
|
||||
let parent_handle = *body_handles.last().unwrap();
|
||||
let joint = SphericalJointBuilder::new().local_anchor2(Vec3::new(0.0, 0.0, -shift));
|
||||
impulse_joints.insert(parent_handle, child_handle, joint, true);
|
||||
}
|
||||
|
||||
// Horizontal joint.
|
||||
if k > 0 {
|
||||
let parent_index = body_handles.len() - num;
|
||||
let parent_handle = body_handles[parent_index];
|
||||
let joint = SphericalJointBuilder::new().local_anchor2(Vec3::new(-shift, 0.0, 0.0));
|
||||
impulse_joints.insert(parent_handle, child_handle, joint, true);
|
||||
}
|
||||
|
||||
body_handles.push(child_handle);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(
|
||||
Vec3::new(-110.0, -46.0, 170.0),
|
||||
Vec3::new(54.0, -38.0, 29.0),
|
||||
);
|
||||
}
|
||||
81
examples3d/stress_tests/joint_fixed3.rs
Normal file
81
examples3d/stress_tests/joint_fixed3.rs
Normal file
@@ -0,0 +1,81 @@
|
||||
use rapier_testbed3d::Testbed;
|
||||
use rapier3d::prelude::*;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* World
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let mut impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
let rad = 0.4;
|
||||
let num = 5;
|
||||
let shift = 1.0;
|
||||
|
||||
let mut body_handles = Vec::new();
|
||||
|
||||
for m in 0..10 {
|
||||
let z = m as f32 * shift * (num as f32 + 2.0);
|
||||
|
||||
for l in 0..10 {
|
||||
let y = l as f32 * shift * 3.0;
|
||||
|
||||
for j in 0..5 {
|
||||
let x = j as f32 * shift * (num as f32) * 2.0;
|
||||
|
||||
for k in 0..num {
|
||||
for i in 0..num {
|
||||
let fk = k as f32;
|
||||
let fi = i as f32;
|
||||
|
||||
// NOTE: the num - 2 test is to avoid two consecutive
|
||||
// fixed bodies. Because physx will crash if we add
|
||||
// a joint between these.
|
||||
|
||||
let status = if i == 0 && (k % 4 == 0 && k != num - 2 || k == num - 1) {
|
||||
RigidBodyType::Fixed
|
||||
} else {
|
||||
RigidBodyType::Dynamic
|
||||
};
|
||||
|
||||
let rigid_body = RigidBodyBuilder::new(status).translation(Vec3::new(
|
||||
x + fk * shift,
|
||||
y,
|
||||
z + fi * shift,
|
||||
));
|
||||
let child_handle = bodies.insert(rigid_body);
|
||||
let collider = ColliderBuilder::ball(rad);
|
||||
colliders.insert_with_parent(collider, child_handle, &mut bodies);
|
||||
|
||||
// Vertical joint.
|
||||
if i > 0 {
|
||||
let parent_handle = *body_handles.last().unwrap();
|
||||
let joint =
|
||||
FixedJointBuilder::new().local_anchor2(Vec3::new(0.0, 0.0, -shift));
|
||||
impulse_joints.insert(parent_handle, child_handle, joint, true);
|
||||
}
|
||||
|
||||
// Horizontal joint.
|
||||
if k > 0 {
|
||||
let parent_index = body_handles.len() - num;
|
||||
let parent_handle = body_handles[parent_index];
|
||||
let joint =
|
||||
FixedJointBuilder::new().local_anchor2(Vec3::new(-shift, 0.0, 0.0));
|
||||
impulse_joints.insert(parent_handle, child_handle, joint, true);
|
||||
}
|
||||
|
||||
body_handles.push(child_handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(Vec3::new(-38.0, 14.0, 108.0), Vec3::new(46.0, 12.0, 23.0));
|
||||
}
|
||||
61
examples3d/stress_tests/joint_prismatic3.rs
Normal file
61
examples3d/stress_tests/joint_prismatic3.rs
Normal file
@@ -0,0 +1,61 @@
|
||||
use rapier_testbed3d::Testbed;
|
||||
use rapier3d::prelude::*;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* World
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let mut impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
let rad = 0.4;
|
||||
let num = 5;
|
||||
let shift = 1.0;
|
||||
|
||||
for m in 0..8 {
|
||||
let z = m as f32 * shift * (num as f32 + 2.0);
|
||||
|
||||
for l in 0..8 {
|
||||
let y = l as f32 * shift * (num as f32) * 2.0;
|
||||
|
||||
for j in 0..50 {
|
||||
let x = j as f32 * shift * 4.0;
|
||||
|
||||
let ground = RigidBodyBuilder::fixed().translation(Vec3::new(x, y, z));
|
||||
let mut curr_parent = bodies.insert(ground);
|
||||
let collider = ColliderBuilder::cuboid(rad, rad, rad);
|
||||
colliders.insert_with_parent(collider, curr_parent, &mut bodies);
|
||||
|
||||
for i in 0..num {
|
||||
let z = z + (i + 1) as f32 * shift;
|
||||
let density = 1.0;
|
||||
let rigid_body = RigidBodyBuilder::dynamic().translation(Vec3::new(x, y, z));
|
||||
let curr_child = bodies.insert(rigid_body);
|
||||
let collider = ColliderBuilder::cuboid(rad, rad, rad).density(density);
|
||||
colliders.insert_with_parent(collider, curr_child, &mut bodies);
|
||||
|
||||
let axis = if i % 2 == 0 {
|
||||
Vec3::new(1.0, 1.0, 0.0).normalize()
|
||||
} else {
|
||||
Vec3::new(-1.0, 1.0, 0.0).normalize()
|
||||
};
|
||||
|
||||
let prism = PrismaticJointBuilder::new(axis)
|
||||
.local_anchor2(Vec3::new(0.0, 0.0, -shift))
|
||||
.limits([-2.0, 0.0]);
|
||||
impulse_joints.insert(curr_parent, curr_child, prism, true);
|
||||
|
||||
curr_parent = curr_child;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(Vec3::new(262.0, 63.0, 124.0), Vec3::new(101.0, 4.0, -3.0));
|
||||
}
|
||||
76
examples3d/stress_tests/joint_revolute3.rs
Normal file
76
examples3d/stress_tests/joint_revolute3.rs
Normal file
@@ -0,0 +1,76 @@
|
||||
use rapier_testbed3d::Testbed;
|
||||
use rapier3d::prelude::*;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* World
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let mut impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
let rad = 0.4;
|
||||
let num = 10;
|
||||
let shift = 2.0;
|
||||
|
||||
for l in 0..4 {
|
||||
let y = l as f32 * shift * (num as f32) * 3.0;
|
||||
|
||||
for j in 0..50 {
|
||||
let x = j as f32 * shift * 4.0;
|
||||
|
||||
let ground = RigidBodyBuilder::fixed().translation(Vec3::new(x, y, 0.0));
|
||||
let mut curr_parent = bodies.insert(ground);
|
||||
let collider = ColliderBuilder::cuboid(rad, rad, rad);
|
||||
colliders.insert_with_parent(collider, curr_parent, &mut bodies);
|
||||
|
||||
for i in 0..num {
|
||||
// Create four bodies.
|
||||
let z = i as f32 * shift * 2.0 + shift;
|
||||
let positions = [
|
||||
Pose3::translation(x, y, z),
|
||||
Pose3::translation(x + shift, y, z),
|
||||
Pose3::translation(x + shift, y, z + shift),
|
||||
Pose3::translation(x, y, z + shift),
|
||||
];
|
||||
|
||||
let mut handles = [curr_parent; 4];
|
||||
for k in 0..4 {
|
||||
let density = 1.0;
|
||||
let rigid_body = RigidBodyBuilder::dynamic().pose(positions[k]);
|
||||
handles[k] = bodies.insert(rigid_body);
|
||||
let collider = ColliderBuilder::cuboid(rad, rad, rad).density(density);
|
||||
colliders.insert_with_parent(collider, handles[k], &mut bodies);
|
||||
}
|
||||
|
||||
// Setup four impulse_joints.
|
||||
let x = Vec3::X;
|
||||
let z = Vec3::Z;
|
||||
|
||||
let revs = [
|
||||
RevoluteJointBuilder::new(z).local_anchor2(Vec3::new(0.0, 0.0, -shift)),
|
||||
RevoluteJointBuilder::new(x).local_anchor2(Vec3::new(-shift, 0.0, 0.0)),
|
||||
RevoluteJointBuilder::new(z).local_anchor2(Vec3::new(0.0, 0.0, -shift)),
|
||||
RevoluteJointBuilder::new(x).local_anchor2(Vec3::new(shift, 0.0, 0.0)),
|
||||
];
|
||||
|
||||
impulse_joints.insert(curr_parent, handles[0], revs[0], true);
|
||||
impulse_joints.insert(handles[0], handles[1], revs[1], true);
|
||||
impulse_joints.insert(handles[1], handles[2], revs[2], true);
|
||||
impulse_joints.insert(handles[2], handles[3], revs[3], true);
|
||||
|
||||
curr_parent = handles[3];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(
|
||||
Vec3::new(478.0, 83.0, 228.0),
|
||||
Vec3::new(134.0, 83.0, -116.0),
|
||||
);
|
||||
}
|
||||
126
examples3d/stress_tests/keva3.rs
Normal file
126
examples3d/stress_tests/keva3.rs
Normal file
@@ -0,0 +1,126 @@
|
||||
use kiss3d::color::Color;
|
||||
use rapier_testbed3d::Testbed;
|
||||
use rapier3d::glamx::Vec3Swizzles;
|
||||
use rapier3d::prelude::*;
|
||||
|
||||
pub fn build_block(
|
||||
testbed: &mut Testbed,
|
||||
bodies: &mut RigidBodySet,
|
||||
colliders: &mut ColliderSet,
|
||||
half_extents: Vec3,
|
||||
shift: Vec3,
|
||||
(mut numx, numy, mut numz): (usize, usize, usize),
|
||||
) {
|
||||
let dimensions = [half_extents.xyz(), half_extents.zyx()];
|
||||
let block_width = 2.0 * half_extents.z * numx as f32;
|
||||
let block_height = 2.0 * half_extents.y * numy as f32;
|
||||
let spacing = (half_extents.z * numx as f32 - half_extents.x) / (numz as f32 - 1.0);
|
||||
let mut color0 = Color::new(0.7, 0.5, 0.9, 1.0);
|
||||
let mut color1 = Color::new(0.6, 1.0, 0.6, 1.0);
|
||||
|
||||
for i in 0..numy {
|
||||
std::mem::swap(&mut numx, &mut numz);
|
||||
let dim = dimensions[i % 2];
|
||||
let y = dim.y * i as f32 * 2.0;
|
||||
|
||||
for j in 0..numx {
|
||||
let x = if i % 2 == 0 {
|
||||
spacing * j as f32 * 2.0
|
||||
} else {
|
||||
dim.x * j as f32 * 2.0
|
||||
};
|
||||
|
||||
for k in 0..numz {
|
||||
let z = if i % 2 == 0 {
|
||||
dim.z * k as f32 * 2.0
|
||||
} else {
|
||||
spacing * k as f32 * 2.0
|
||||
};
|
||||
|
||||
// Build the rigid body.
|
||||
let rigid_body = RigidBodyBuilder::dynamic().translation(Vec3::new(
|
||||
x + dim.x + shift.x,
|
||||
y + dim.y + shift.y,
|
||||
z + dim.z + shift.z,
|
||||
));
|
||||
let handle = bodies.insert(rigid_body);
|
||||
let collider = ColliderBuilder::cuboid(dim.x, dim.y, dim.z);
|
||||
colliders.insert_with_parent(collider, handle, bodies);
|
||||
|
||||
testbed.set_initial_body_color(handle, color0);
|
||||
std::mem::swap(&mut color0, &mut color1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Close the top.
|
||||
let dim = half_extents.zxy();
|
||||
|
||||
for i in 0..(block_width / (dim.x * 2.0)) as usize {
|
||||
for j in 0..(block_width / (dim.z * 2.0)) as usize {
|
||||
// Build the rigid body.
|
||||
let rigid_body = RigidBodyBuilder::dynamic().translation(Vec3::new(
|
||||
i as f32 * dim.x * 2.0 + dim.x + shift.x,
|
||||
dim.y + shift.y + block_height,
|
||||
j as f32 * dim.z * 2.0 + dim.z + shift.z,
|
||||
));
|
||||
let handle = bodies.insert(rigid_body);
|
||||
let collider = ColliderBuilder::cuboid(dim.x, dim.y, dim.z);
|
||||
colliders.insert_with_parent(collider, handle, bodies);
|
||||
testbed.set_initial_body_color(handle, color0);
|
||||
std::mem::swap(&mut color0, &mut color1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* World
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
*/
|
||||
let ground_size = 50.0;
|
||||
let ground_height = 0.1;
|
||||
|
||||
let rigid_body = RigidBodyBuilder::fixed().translation(Vec3::new(0.0, -ground_height, 0.0));
|
||||
let handle = bodies.insert(rigid_body);
|
||||
let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size);
|
||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||
|
||||
/*
|
||||
* Create the cubes
|
||||
*/
|
||||
let half_extents = Vec3::new(0.02, 0.1, 0.4) / 2.0 * 10.0;
|
||||
let mut block_height = 0.0;
|
||||
// These should only be set to odd values otherwise
|
||||
// the blocks won't align in the nicest way.
|
||||
let numy = [0, 9, 13, 17, 21, 41];
|
||||
|
||||
for i in (1..=5).rev() {
|
||||
let numx = i;
|
||||
let numy = numy[i];
|
||||
let numz = numx * 3 + 1;
|
||||
let block_width = numx as f32 * half_extents.z * 2.0;
|
||||
build_block(
|
||||
testbed,
|
||||
&mut bodies,
|
||||
&mut colliders,
|
||||
half_extents,
|
||||
Vec3::new(-block_width / 2.0, block_height, -block_width / 2.0),
|
||||
(numx, numy, numz),
|
||||
);
|
||||
block_height += numy as f32 * half_extents.y * 2.0 + half_extents.x * 2.0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(Vec3::new(100.0, 100.0, 100.0), Vec3::ZERO);
|
||||
}
|
||||
68
examples3d/stress_tests/many_kinematics3.rs
Normal file
68
examples3d/stress_tests/many_kinematics3.rs
Normal file
@@ -0,0 +1,68 @@
|
||||
use rapier_testbed3d::Testbed;
|
||||
use rapier3d::prelude::*;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* World
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Create the balls
|
||||
*/
|
||||
let num = 30;
|
||||
let rad = 1.0;
|
||||
|
||||
let shift = rad * 6.0 + 1.0;
|
||||
let centerx = shift * (num as f32) / 2.0;
|
||||
let centery = shift * (num as f32) / 2.0;
|
||||
let centerz = shift * (num as f32) / 2.0;
|
||||
|
||||
for i in 0..num {
|
||||
for j in 0usize..num {
|
||||
for k in 0..num {
|
||||
let x = i as f32 * shift - centerx;
|
||||
let y = j as f32 * shift - centery;
|
||||
let z = k as f32 * shift - centerz;
|
||||
|
||||
// Build the rigid body.
|
||||
let velocity = Vec3::new(
|
||||
rand::random::<f32>() - 0.5,
|
||||
rand::random::<f32>() - 0.5,
|
||||
rand::random::<f32>() - 0.5,
|
||||
) * 30.0;
|
||||
let rigid_body = RigidBodyBuilder::new(RigidBodyType::KinematicVelocityBased)
|
||||
.translation(Vec3::new(x, y, z))
|
||||
.linvel(velocity);
|
||||
let handle = bodies.insert(rigid_body);
|
||||
let collider = ColliderBuilder::ball(rad);
|
||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
testbed.add_callback(move |_, physics, _, _| {
|
||||
for (_, rb) in physics.bodies.iter_mut() {
|
||||
let mut linvel = rb.linvel();
|
||||
|
||||
for dim in 0..3 {
|
||||
if (linvel[dim] > 0.0 && rb.translation()[dim] > (shift * num as f32) / 2.0)
|
||||
|| (linvel[dim] < 0.0 && rb.translation()[dim] < -(shift * num as f32) / 2.0)
|
||||
{
|
||||
linvel[dim] = -linvel[dim];
|
||||
}
|
||||
}
|
||||
|
||||
rb.set_linvel(linvel, false);
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(Vec3::new(100.0, 100.0, 100.0), Vec3::ZERO);
|
||||
}
|
||||
80
examples3d/stress_tests/many_pyramids3.rs
Normal file
80
examples3d/stress_tests/many_pyramids3.rs
Normal file
@@ -0,0 +1,80 @@
|
||||
use rapier_testbed3d::Testbed;
|
||||
use rapier3d::prelude::*;
|
||||
|
||||
fn create_pyramid(
|
||||
bodies: &mut RigidBodySet,
|
||||
colliders: &mut ColliderSet,
|
||||
offset: Vec3,
|
||||
stack_height: usize,
|
||||
rad: f32,
|
||||
) {
|
||||
let shift = rad * 2.0;
|
||||
|
||||
for i in 0usize..stack_height {
|
||||
for j in i..stack_height {
|
||||
let fj = j as f32;
|
||||
let fi = i as f32;
|
||||
let x = (fi * shift / 2.0) + (fj - fi) * shift;
|
||||
let y = fi * shift;
|
||||
|
||||
// Build the rigid body.
|
||||
let rigid_body = RigidBodyBuilder::dynamic().translation(Vec3::new(x, y, 0.0) + offset);
|
||||
let handle = bodies.insert(rigid_body);
|
||||
let collider = ColliderBuilder::cuboid(rad, rad, rad);
|
||||
colliders.insert_with_parent(collider, handle, bodies);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* World
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
let rad = 0.5;
|
||||
let pyramid_count = 40;
|
||||
let spacing = 4.0;
|
||||
|
||||
/*
|
||||
* Ground
|
||||
*/
|
||||
let ground_size = 50.0;
|
||||
let ground_height = 0.1;
|
||||
|
||||
let rigid_body = RigidBodyBuilder::fixed().translation(Vec3::new(0.0, -ground_height, 0.0));
|
||||
let ground_handle = bodies.insert(rigid_body);
|
||||
let collider = ColliderBuilder::cuboid(
|
||||
ground_size,
|
||||
ground_height,
|
||||
pyramid_count as f32 * spacing / 2.0 + ground_size,
|
||||
);
|
||||
colliders.insert_with_parent(collider, ground_handle, &mut bodies);
|
||||
|
||||
/*
|
||||
* Create the cubes
|
||||
*/
|
||||
for pyramid_index in 0..pyramid_count {
|
||||
let bottomy = rad;
|
||||
create_pyramid(
|
||||
&mut bodies,
|
||||
&mut colliders,
|
||||
Vec3::new(
|
||||
0.0,
|
||||
bottomy,
|
||||
(pyramid_index as f32 - pyramid_count as f32 / 2.0) * spacing,
|
||||
),
|
||||
20,
|
||||
rad,
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(Vec3::new(100.0, 100.0, 100.0), Vec3::ZERO);
|
||||
}
|
||||
54
examples3d/stress_tests/many_sleep3.rs
Normal file
54
examples3d/stress_tests/many_sleep3.rs
Normal file
@@ -0,0 +1,54 @@
|
||||
use rapier_testbed3d::Testbed;
|
||||
use rapier3d::prelude::*;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* World
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Create the balls
|
||||
*/
|
||||
let num = 50;
|
||||
let rad = 1.0;
|
||||
|
||||
let shift = rad * 2.0 + 1.0;
|
||||
let centerx = shift * (num as f32) / 2.0;
|
||||
let centery = shift / 2.0;
|
||||
let centerz = shift * (num as f32) / 2.0;
|
||||
|
||||
for i in 0..num {
|
||||
for j in 0usize..num {
|
||||
for k in 0..num {
|
||||
let x = i as f32 * shift - centerx;
|
||||
let y = j as f32 * shift + centery;
|
||||
let z = k as f32 * shift - centerz;
|
||||
|
||||
let status = if j == 0 {
|
||||
RigidBodyType::Fixed
|
||||
} else {
|
||||
RigidBodyType::Dynamic
|
||||
};
|
||||
let density = 0.477;
|
||||
|
||||
// Build the rigid body.
|
||||
let rigid_body = RigidBodyBuilder::new(status)
|
||||
.translation(Vec3::new(x, y, z))
|
||||
.sleeping(true); // j < num - 1);
|
||||
let handle = bodies.insert(rigid_body);
|
||||
let collider = ColliderBuilder::ball(rad).density(density);
|
||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(Vec3::new(100.0, 100.0, 100.0), Vec3::ZERO);
|
||||
}
|
||||
52
examples3d/stress_tests/many_static3.rs
Normal file
52
examples3d/stress_tests/many_static3.rs
Normal file
@@ -0,0 +1,52 @@
|
||||
use rapier_testbed3d::Testbed;
|
||||
use rapier3d::prelude::*;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* World
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Create the balls
|
||||
*/
|
||||
let num = 50;
|
||||
let rad = 1.0;
|
||||
|
||||
let shift = rad * 2.0 + 1.0;
|
||||
let centerx = shift * (num as f32) / 2.0;
|
||||
let centery = shift / 2.0;
|
||||
let centerz = shift * (num as f32) / 2.0;
|
||||
|
||||
for i in 0..num {
|
||||
for j in 0usize..num {
|
||||
for k in 0..num {
|
||||
let x = i as f32 * shift - centerx;
|
||||
let y = j as f32 * shift + centery;
|
||||
let z = k as f32 * shift - centerz;
|
||||
|
||||
let status = if j < num - 1 {
|
||||
RigidBodyType::Fixed
|
||||
} else {
|
||||
RigidBodyType::Dynamic
|
||||
};
|
||||
let density = 0.477;
|
||||
|
||||
// Build the rigid body.
|
||||
let rigid_body = RigidBodyBuilder::new(status).translation(Vec3::new(x, y, z));
|
||||
let handle = bodies.insert(rigid_body);
|
||||
let collider = ColliderBuilder::ball(rad).density(density);
|
||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(Vec3::new(100.0, 100.0, 100.0), Vec3::ZERO);
|
||||
}
|
||||
53
examples3d/stress_tests/mod.rs
Normal file
53
examples3d/stress_tests/mod.rs
Normal file
@@ -0,0 +1,53 @@
|
||||
use rapier_testbed3d::Example;
|
||||
|
||||
mod balls3;
|
||||
mod boxes3;
|
||||
mod capsules3;
|
||||
mod ccd3;
|
||||
mod compound3;
|
||||
mod convex_polyhedron3;
|
||||
mod heightfield3;
|
||||
mod joint_ball3;
|
||||
mod joint_fixed3;
|
||||
mod joint_prismatic3;
|
||||
mod joint_revolute3;
|
||||
mod keva3;
|
||||
mod many_kinematics3;
|
||||
mod many_pyramids3;
|
||||
mod many_sleep3;
|
||||
mod many_static3;
|
||||
mod pyramid3;
|
||||
mod ray_cast3;
|
||||
mod stacks3;
|
||||
mod trimesh3;
|
||||
|
||||
pub fn builders() -> Vec<Example> {
|
||||
const STRESS: &str = "Stress Tests";
|
||||
|
||||
vec![
|
||||
Example::new(STRESS, "Balls", balls3::init_world),
|
||||
Example::new(STRESS, "Boxes", boxes3::init_world),
|
||||
Example::new(STRESS, "Capsules", capsules3::init_world),
|
||||
Example::new(STRESS, "CCD", ccd3::init_world),
|
||||
Example::new(STRESS, "Compound", compound3::init_world),
|
||||
Example::new(STRESS, "Convex polyhedron", convex_polyhedron3::init_world),
|
||||
Example::new(STRESS, "Many kinematics", many_kinematics3::init_world),
|
||||
Example::new(STRESS, "Many static", many_static3::init_world),
|
||||
Example::new(STRESS, "Many sleep", many_sleep3::init_world),
|
||||
Example::new(STRESS, "Heightfield", heightfield3::init_world),
|
||||
Example::new(STRESS, "Stacks", stacks3::init_world),
|
||||
Example::new(STRESS, "Pyramid", pyramid3::init_world),
|
||||
Example::new(STRESS, "Trimesh", trimesh3::init_world),
|
||||
Example::new(STRESS, "ImpulseJoint ball", joint_ball3::init_world),
|
||||
Example::new(STRESS, "ImpulseJoint fixed", joint_fixed3::init_world),
|
||||
Example::new(STRESS, "ImpulseJoint revolute", joint_revolute3::init_world),
|
||||
Example::new(
|
||||
STRESS,
|
||||
"ImpulseJoint prismatic",
|
||||
joint_prismatic3::init_world,
|
||||
),
|
||||
Example::new(STRESS, "Many pyramids", many_pyramids3::init_world),
|
||||
Example::new(STRESS, "Keva tower", keva3::init_world),
|
||||
Example::new(STRESS, "Ray cast", ray_cast3::init_world),
|
||||
]
|
||||
}
|
||||
75
examples3d/stress_tests/pyramid3.rs
Normal file
75
examples3d/stress_tests/pyramid3.rs
Normal file
@@ -0,0 +1,75 @@
|
||||
use rapier_testbed3d::Testbed;
|
||||
use rapier3d::prelude::*;
|
||||
|
||||
fn create_pyramid(
|
||||
bodies: &mut RigidBodySet,
|
||||
colliders: &mut ColliderSet,
|
||||
offset: Vec3,
|
||||
stack_height: usize,
|
||||
half_extents: Vec3,
|
||||
) {
|
||||
let shift = half_extents * 2.5;
|
||||
for i in 0usize..stack_height {
|
||||
for j in i..stack_height {
|
||||
for k in i..stack_height {
|
||||
let fi = i as f32;
|
||||
let fj = j as f32;
|
||||
let fk = k as f32;
|
||||
let x = (fi * shift.x / 2.0) + (fk - fi) * shift.x + offset.x
|
||||
- stack_height as f32 * half_extents.x;
|
||||
let y = fi * shift.y + offset.y;
|
||||
let z = (fi * shift.z / 2.0) + (fj - fi) * shift.z + offset.z
|
||||
- stack_height as f32 * half_extents.z;
|
||||
|
||||
// Build the rigid body.
|
||||
let rigid_body = RigidBodyBuilder::dynamic().translation(Vec3::new(x, y, z));
|
||||
let rigid_body_handle = bodies.insert(rigid_body);
|
||||
|
||||
let collider =
|
||||
ColliderBuilder::cuboid(half_extents.x, half_extents.y, half_extents.z);
|
||||
colliders.insert_with_parent(collider, rigid_body_handle, bodies);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* World
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
*/
|
||||
let ground_size = 50.0;
|
||||
let ground_height = 0.1;
|
||||
|
||||
let rigid_body = RigidBodyBuilder::fixed().translation(Vec3::new(0.0, -ground_height, 0.0));
|
||||
let ground_handle = bodies.insert(rigid_body);
|
||||
let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size);
|
||||
colliders.insert_with_parent(collider, ground_handle, &mut bodies);
|
||||
|
||||
/*
|
||||
* Create the cubes
|
||||
*/
|
||||
let cube_size = 1.0;
|
||||
let hext = Vec3::splat(cube_size);
|
||||
let bottomy = cube_size;
|
||||
create_pyramid(
|
||||
&mut bodies,
|
||||
&mut colliders,
|
||||
Vec3::new(0.0, bottomy, 0.0),
|
||||
24,
|
||||
hext,
|
||||
);
|
||||
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(Vec3::new(100.0, 100.0, 100.0), Vec3::ZERO);
|
||||
}
|
||||
82
examples3d/stress_tests/ray_cast3.rs
Normal file
82
examples3d/stress_tests/ray_cast3.rs
Normal file
@@ -0,0 +1,82 @@
|
||||
use crate::{Example, stress_tests};
|
||||
use kiss3d::prelude::*;
|
||||
use rapier_testbed3d::Testbed;
|
||||
use rapier3d::prelude::*;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
let settings = testbed.example_settings_mut();
|
||||
|
||||
// NOTE: this demo is a bit special. It takes as a setting the builder of another demo,
|
||||
// builds it, and add a ton of rays into it. This gives us an easy way to check
|
||||
// ray-casting in a wide variety of situations.
|
||||
let demos: Vec<Example> = stress_tests::builders()
|
||||
.into_iter()
|
||||
.filter(|demo| !std::ptr::fn_addr_eq(demo.builder, self::init_world as fn(&mut Testbed)))
|
||||
.collect();
|
||||
let demo_names: Vec<_> = demos.iter().map(|demo| demo.name.to_string()).collect();
|
||||
let selected = settings.get_or_set_string("Scene", 0, demo_names);
|
||||
(demos[selected].builder)(testbed);
|
||||
|
||||
/*
|
||||
* Cast rays at each frame.
|
||||
*/
|
||||
let ray_ball_radius = 100.0;
|
||||
let ray_ball = Ball::new(ray_ball_radius);
|
||||
let (ray_origins, _) = ray_ball.to_trimesh(100, 100);
|
||||
let rays: Vec<_> = ray_origins
|
||||
.into_iter()
|
||||
.map(|pt| Ray::new(pt, -pt.normalize()))
|
||||
.collect();
|
||||
let mut centered_rays = rays.clone();
|
||||
|
||||
testbed.add_callback(move |graphics, physics, _, _| {
|
||||
let Some(graphics) = graphics else {
|
||||
return;
|
||||
};
|
||||
|
||||
// Re-center the ray relative to the current position of all objects.
|
||||
// This ensures demos with falling objects don’t end up with a boring situation
|
||||
// where all the rays point into the void.
|
||||
let mut center = Vec3::ZERO;
|
||||
for (_, b) in physics.bodies.iter() {
|
||||
center += b.translation();
|
||||
}
|
||||
center /= physics.bodies.len() as Real;
|
||||
|
||||
for (centered, ray) in centered_rays.iter_mut().zip(rays.iter()) {
|
||||
centered.origin = center + ray.origin;
|
||||
}
|
||||
|
||||
// Cast the rays.
|
||||
let t1 = std::time::Instant::now();
|
||||
let max_toi = ray_ball_radius - 1.0;
|
||||
|
||||
let query_pipeline = physics.broad_phase.as_query_pipeline(
|
||||
physics.narrow_phase.query_dispatcher(),
|
||||
&physics.bodies,
|
||||
&physics.colliders,
|
||||
Default::default(),
|
||||
);
|
||||
|
||||
for ray in ¢ered_rays {
|
||||
if let Some((_, toi)) = query_pipeline.cast_ray(ray, max_toi, true) {
|
||||
let a = ray.origin;
|
||||
let b = ray.point_at(toi);
|
||||
graphics.window.draw_line(a, b, GREEN, 100.0, true);
|
||||
} else {
|
||||
let a = ray.origin;
|
||||
let b = ray.point_at(max_toi);
|
||||
graphics.window.draw_line(a, b, RED, 100.0, true);
|
||||
}
|
||||
}
|
||||
let main_check_time = t1.elapsed().as_secs_f32();
|
||||
|
||||
if let Some(settings) = &mut graphics.settings {
|
||||
settings.set_label("Ray count:", format!("{}", rays.len()));
|
||||
settings.set_label(
|
||||
"Ray-cast time",
|
||||
format!("{:.2}ms", main_check_time * 1000.0,),
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
180
examples3d/stress_tests/stacks3.rs
Normal file
180
examples3d/stress_tests/stacks3.rs
Normal file
@@ -0,0 +1,180 @@
|
||||
use rapier_testbed3d::Testbed;
|
||||
use rapier3d::prelude::*;
|
||||
|
||||
fn create_tower_circle(
|
||||
bodies: &mut RigidBodySet,
|
||||
colliders: &mut ColliderSet,
|
||||
offset: Vec3,
|
||||
stack_height: usize,
|
||||
nsubdivs: usize,
|
||||
half_extents: Vec3,
|
||||
) {
|
||||
let ang_step = std::f32::consts::PI * 2.0 / nsubdivs as f32;
|
||||
let radius = 1.3 * nsubdivs as f32 * half_extents.x / std::f32::consts::PI;
|
||||
|
||||
let shift = half_extents * 2.0;
|
||||
for i in 0usize..stack_height {
|
||||
for j in 0..nsubdivs {
|
||||
let fj = j as f32;
|
||||
let fi = i as f32;
|
||||
let y = fi * shift.y;
|
||||
let pos = Pose3::new(offset, Vec3::Y * (fi / 2.0 + fj) * ang_step)
|
||||
.prepend_translation(Vec3::new(0.0, y, radius));
|
||||
|
||||
// Build the rigid body.
|
||||
let rigid_body = RigidBodyBuilder::dynamic().pose(pos);
|
||||
let handle = bodies.insert(rigid_body);
|
||||
let collider = ColliderBuilder::cuboid(half_extents.x, half_extents.y, half_extents.z);
|
||||
colliders.insert_with_parent(collider, handle, bodies);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn create_wall(
|
||||
bodies: &mut RigidBodySet,
|
||||
colliders: &mut ColliderSet,
|
||||
offset: Vec3,
|
||||
stack_height: usize,
|
||||
half_extents: Vec3,
|
||||
) {
|
||||
let shift = half_extents * 2.0;
|
||||
for i in 0usize..stack_height {
|
||||
for j in i..stack_height {
|
||||
let fj = j as f32;
|
||||
let fi = i as f32;
|
||||
let x = offset.x;
|
||||
let y = fi * shift.y + offset.y;
|
||||
let z = (fi * shift.z / 2.0) + (fj - fi) * shift.z + offset.z
|
||||
- stack_height as f32 * half_extents.z;
|
||||
|
||||
// Build the rigid body.
|
||||
let rigid_body = RigidBodyBuilder::dynamic().translation(Vec3::new(x, y, z));
|
||||
let handle = bodies.insert(rigid_body);
|
||||
let collider = ColliderBuilder::cuboid(half_extents.x, half_extents.y, half_extents.z);
|
||||
colliders.insert_with_parent(collider, handle, bodies);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn create_pyramid(
|
||||
bodies: &mut RigidBodySet,
|
||||
colliders: &mut ColliderSet,
|
||||
offset: Vec3,
|
||||
stack_height: usize,
|
||||
half_extents: Vec3,
|
||||
) {
|
||||
let shift = half_extents * 2.0;
|
||||
|
||||
for i in 0usize..stack_height {
|
||||
for j in i..stack_height {
|
||||
for k in i..stack_height {
|
||||
let fi = i as f32;
|
||||
let fj = j as f32;
|
||||
let fk = k as f32;
|
||||
let x = (fi * shift.x / 2.0) + (fk - fi) * shift.x + offset.x
|
||||
- stack_height as f32 * half_extents.x;
|
||||
let y = fi * shift.y + offset.y;
|
||||
let z = (fi * shift.z / 2.0) + (fj - fi) * shift.z + offset.z
|
||||
- stack_height as f32 * half_extents.z;
|
||||
|
||||
// Build the rigid body.
|
||||
let rigid_body = RigidBodyBuilder::dynamic().translation(Vec3::new(x, y, z));
|
||||
let handle = bodies.insert(rigid_body);
|
||||
let collider =
|
||||
ColliderBuilder::cuboid(half_extents.x, half_extents.y, half_extents.z);
|
||||
colliders.insert_with_parent(collider, handle, bodies);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* World
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
*/
|
||||
let ground_size = 200.0;
|
||||
let ground_height = 0.1;
|
||||
|
||||
let rigid_body = RigidBodyBuilder::fixed().translation(Vec3::new(0.0, -ground_height, 0.0));
|
||||
let handle = bodies.insert(rigid_body);
|
||||
let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size);
|
||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||
|
||||
/*
|
||||
* Create the cubes
|
||||
*/
|
||||
let cube_size = 1.0;
|
||||
let hext = Vec3::splat(cube_size);
|
||||
let bottomy = cube_size * 50.0;
|
||||
create_pyramid(
|
||||
&mut bodies,
|
||||
&mut colliders,
|
||||
Vec3::new(-110.0, bottomy, 0.0),
|
||||
12,
|
||||
hext,
|
||||
);
|
||||
create_pyramid(
|
||||
&mut bodies,
|
||||
&mut colliders,
|
||||
Vec3::new(-80.0, bottomy, 0.0),
|
||||
12,
|
||||
hext,
|
||||
);
|
||||
create_pyramid(
|
||||
&mut bodies,
|
||||
&mut colliders,
|
||||
Vec3::new(-50.0, bottomy, 0.0),
|
||||
12,
|
||||
hext,
|
||||
);
|
||||
create_pyramid(
|
||||
&mut bodies,
|
||||
&mut colliders,
|
||||
Vec3::new(-20.0, bottomy, 0.0),
|
||||
12,
|
||||
hext,
|
||||
);
|
||||
create_wall(
|
||||
&mut bodies,
|
||||
&mut colliders,
|
||||
Vec3::new(-2.0, bottomy, 0.0),
|
||||
12,
|
||||
hext,
|
||||
);
|
||||
create_wall(
|
||||
&mut bodies,
|
||||
&mut colliders,
|
||||
Vec3::new(4.0, bottomy, 0.0),
|
||||
12,
|
||||
hext,
|
||||
);
|
||||
create_wall(
|
||||
&mut bodies,
|
||||
&mut colliders,
|
||||
Vec3::new(10.0, bottomy, 0.0),
|
||||
12,
|
||||
hext,
|
||||
);
|
||||
create_tower_circle(
|
||||
&mut bodies,
|
||||
&mut colliders,
|
||||
Vec3::new(25.0, bottomy, 0.0),
|
||||
8,
|
||||
24,
|
||||
hext,
|
||||
);
|
||||
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(Vec3::new(100.0, 100.0, 100.0), Vec3::ZERO);
|
||||
}
|
||||
82
examples3d/stress_tests/trimesh3.rs
Normal file
82
examples3d/stress_tests/trimesh3.rs
Normal file
@@ -0,0 +1,82 @@
|
||||
use rapier_testbed3d::Testbed;
|
||||
use rapier3d::na::ComplexField;
|
||||
use rapier3d::prelude::*;
|
||||
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* World
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
*/
|
||||
let ground_size = Vec3::new(200.0, 1.0, 200.0);
|
||||
let nsubdivs = 20;
|
||||
|
||||
let heights = Array2::from_fn(nsubdivs + 1, nsubdivs + 1, |i, j| {
|
||||
if i == 0 || i == nsubdivs || j == 0 || j == nsubdivs {
|
||||
10.0
|
||||
} else {
|
||||
let x = i as f32 * ground_size.x / (nsubdivs as f32);
|
||||
let z = j as f32 * ground_size.z / (nsubdivs as f32);
|
||||
|
||||
// NOTE: make sure we use the sin/cos from simba to ensure
|
||||
// cross-platform determinism of the example when the
|
||||
// enhanced_determinism feature is enabled.
|
||||
<f32 as ComplexField>::sin(x) + <f32 as ComplexField>::cos(z)
|
||||
}
|
||||
});
|
||||
|
||||
// Here we will build our trimesh from the mesh representation of an
|
||||
// heightfield.
|
||||
let heightfield = HeightField::new(heights, ground_size);
|
||||
let (vertices, indices) = heightfield.to_trimesh();
|
||||
|
||||
let rigid_body = RigidBodyBuilder::fixed();
|
||||
let handle = bodies.insert(rigid_body);
|
||||
let collider = ColliderBuilder::trimesh(vertices, indices).unwrap();
|
||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||
|
||||
/*
|
||||
* Create the cubes
|
||||
*/
|
||||
let num = 8;
|
||||
let rad = 1.0;
|
||||
|
||||
let shift = rad * 2.0 + rad;
|
||||
let centerx = shift * (num / 2) as f32;
|
||||
let centery = shift / 2.0;
|
||||
let centerz = shift * (num / 2) as f32;
|
||||
|
||||
for j in 0usize..47 {
|
||||
for i in 0..num {
|
||||
for k in 0usize..num {
|
||||
let x = i as f32 * shift - centerx;
|
||||
let y = j as f32 * shift + centery + 3.0;
|
||||
let z = k as f32 * shift - centerz;
|
||||
|
||||
// Build the rigid body.
|
||||
let rigid_body = RigidBodyBuilder::dynamic().translation(Vec3::new(x, y, z));
|
||||
let handle = bodies.insert(rigid_body);
|
||||
|
||||
if j % 2 == 0 {
|
||||
let collider = ColliderBuilder::cuboid(rad, rad, rad);
|
||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||
} else {
|
||||
let collider = ColliderBuilder::ball(rad);
|
||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(Vec3::new(100.0, 100.0, 100.0), Vec3::ZERO);
|
||||
}
|
||||
Reference in New Issue
Block a user