Move benchmark demos into their own directory.

This commit is contained in:
Sébastien Crozet
2020-09-06 12:16:09 +02:00
parent 3080c6e7d2
commit ff2da7fb27
44 changed files with 897 additions and 148 deletions

View File

@@ -1,12 +1,12 @@
[workspace]
members = [ "build/rapier2d", "build/rapier_testbed2d", "examples2d",
"build/rapier3d", "build/rapier_testbed3d", "examples3d" ]
"build/rapier3d", "build/rapier_testbed3d", "examples3d", "benchmarks3d" ]
[patch.crates-io]
#wrapped2d = { git = "https://github.com/Bastacyclop/rust_box2d.git" }
[profile.release]
debug = false
debug = true
codegen-units = 1
#opt-level = 1
#lto = true

27
benchmarks3d/Cargo.toml Normal file
View File

@@ -0,0 +1,27 @@
[package]
name = "rapier-benchmarks-3d"
version = "0.1.0"
authors = [ "Sébastien Crozet <developer@crozet.re>" ]
edition = "2018"
[features]
parallel = [ "rapier3d/parallel", "rapier_testbed3d/parallel" ]
simd-stable = [ "rapier3d/simd-stable" ]
simd-nightly = [ "rapier3d/simd-nightly" ]
other-backends = [ "rapier_testbed3d/other-backends" ]
enhanced-determinism = [ "rapier3d/enhanced-determinism" ]
[dependencies]
rand = "0.7"
Inflector = "0.11"
nalgebra = "0.22"
[dependencies.rapier_testbed3d]
path = "../build/rapier_testbed3d"
[dependencies.rapier3d]
path = "../build/rapier3d"
[[bin]]
name = "all_benchmarks3"
path = "all_benchmarks3.rs"

View File

@@ -0,0 +1,91 @@
#![allow(dead_code)]
extern crate nalgebra as na;
#[cfg(target_arch = "wasm32")]
use wasm_bindgen::prelude::*;
use inflector::Inflector;
use rapier_testbed3d::Testbed;
use std::cmp::Ordering;
mod balls3;
mod boxes3;
mod capsules3;
mod compound3;
mod heightfield3;
mod joint_ball3;
mod joint_fixed3;
mod joint_prismatic3;
mod joint_revolute3;
mod keva3;
mod pyramid3;
mod stacks3;
mod trimesh3;
enum Command {
Run(String),
List,
RunAll,
}
fn parse_command_line() -> Command {
let mut args = std::env::args();
while let Some(arg) = args.next() {
if &arg[..] == "--example" {
return Command::Run(args.next().unwrap_or(String::new()));
} else if &arg[..] == "--list" {
return Command::List;
}
}
Command::RunAll
}
pub fn main() {
let command = parse_command_line();
let mut builders: Vec<(_, fn(&mut Testbed))> = vec![
("Balls", balls3::init_world),
("Boxes", boxes3::init_world),
("Capsules", capsules3::init_world),
("Compound", compound3::init_world),
("Heightfield", heightfield3::init_world),
("Stacks", stacks3::init_world),
("Pyramid", pyramid3::init_world),
("Trimesh", trimesh3::init_world),
("Joint ball", joint_ball3::init_world),
("Joint fixed", joint_fixed3::init_world),
("Joint revolute", joint_revolute3::init_world),
("Joint prismatic", joint_prismatic3::init_world),
("Keva tower", keva3::init_world),
];
// Lexicographic sort, with stress tests moved at the end of the list.
builders.sort_by(|a, b| match (a.0.starts_with("("), b.0.starts_with("(")) {
(true, true) | (false, false) => a.0.cmp(b.0),
(true, false) => Ordering::Greater,
(false, true) => Ordering::Less,
});
match command {
Command::Run(demo) => {
if let Some(i) = builders
.iter()
.position(|builder| builder.0.to_camel_case().as_str() == demo.as_str())
{
Testbed::from_builders(0, vec![builders[i]]).run()
} else {
eprintln!("Invalid example to run provided: '{}'", demo);
}
}
Command::RunAll => Testbed::from_builders(0, builders).run(),
Command::List => {
for builder in &builders {
println!("{}", builder.0.to_camel_case())
}
}
}
}

58
benchmarks3d/balls3.rs Normal file
View File

@@ -0,0 +1,58 @@
use na::Point3;
use rapier3d::dynamics::{BodyStatus, JointSet, RigidBodyBuilder, RigidBodySet};
use rapier3d::geometry::{ColliderBuilder, ColliderSet};
use rapier_testbed3d::Testbed;
pub fn init_world(testbed: &mut Testbed) {
/*
* World
*/
let mut bodies = RigidBodySet::new();
let mut colliders = ColliderSet::new();
let joints = JointSet::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 {
BodyStatus::Static
} else {
BodyStatus::Dynamic
};
let density = 0.477;
// Build the rigid body.
let rigid_body = RigidBodyBuilder::new(status).translation(x, y, z).build();
let handle = bodies.insert(rigid_body);
let collider = ColliderBuilder::ball(rad).density(density).build();
colliders.insert(collider, handle, &mut bodies);
}
}
}
/*
* Set up the testbed.
*/
testbed.set_world(bodies, colliders, joints);
testbed.look_at(Point3::new(100.0, 100.0, 100.0), Point3::origin());
}
fn main() {
let testbed = Testbed::from_builders(0, vec![("Balls", init_world)]);
testbed.run()
}

View File

@@ -47,7 +47,7 @@ pub fn init_world(testbed: &mut Testbed) {
// Build the rigid body.
let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y, z).build();
let handle = bodies.insert(rigid_body);
let collider = ColliderBuilder::cuboid(rad, rad, rad).density(1.0).build();
let collider = ColliderBuilder::cuboid(rad, rad, rad).build();
colliders.insert(collider, handle, &mut bodies);
}
}

View File

@@ -48,7 +48,7 @@ pub fn init_world(testbed: &mut Testbed) {
// Build the rigid body.
let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y, z).build();
let handle = bodies.insert(rigid_body);
let collider = ColliderBuilder::capsule_y(rad, rad).density(1.0).build();
let collider = ColliderBuilder::capsule_y(rad, rad).build();
colliders.insert(collider, handle, &mut bodies);
}
}

76
benchmarks3d/compound3.rs Normal file
View File

@@ -0,0 +1,76 @@
use na::Point3;
use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet};
use rapier3d::geometry::{ColliderBuilder, ColliderSet};
use rapier_testbed3d::Testbed;
pub fn init_world(testbed: &mut Testbed) {
/*
* World
*/
let mut bodies = RigidBodySet::new();
let mut colliders = ColliderSet::new();
let joints = JointSet::new();
/*
* Ground
*/
let ground_size = 200.1;
let ground_height = 0.1;
let rigid_body = RigidBodyBuilder::new_static()
.translation(0.0, -ground_height, 0.0)
.build();
let handle = bodies.insert(rigid_body);
let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size).build();
colliders.insert(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::new_dynamic().translation(x, y, z).build();
let handle = bodies.insert(rigid_body);
let collider1 = ColliderBuilder::cuboid(rad * 10.0, rad, rad).build();
let collider2 = ColliderBuilder::cuboid(rad, rad * 10.0, rad)
.translation(rad * 10.0, rad * 10.0, 0.0)
.build();
let collider3 = ColliderBuilder::cuboid(rad, rad * 10.0, rad)
.translation(-rad * 10.0, rad * 10.0, 0.0)
.build();
colliders.insert(collider1, handle, &mut bodies);
colliders.insert(collider2, handle, &mut bodies);
colliders.insert(collider3, handle, &mut bodies);
}
}
offset -= 0.05 * rad * (num as f32 - 1.0);
}
/*
* Set up the testbed.
*/
testbed.set_world(bodies, colliders, joints);
testbed.look_at(Point3::new(100.0, 100.0, 100.0), Point3::origin());
}
fn main() {
let testbed = Testbed::from_builders(0, vec![("Boxes", init_world)]);
testbed.run()
}

View File

@@ -0,0 +1,78 @@
use na::{DMatrix, Point3, Vector3};
use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet};
use rapier3d::geometry::{ColliderBuilder, ColliderSet};
use rapier_testbed3d::Testbed;
pub fn init_world(testbed: &mut Testbed) {
/*
* World
*/
let mut bodies = RigidBodySet::new();
let mut colliders = ColliderSet::new();
let joints = JointSet::new();
/*
* Ground
*/
let ground_size = Vector3::new(200.0, 1.0, 200.0);
let nsubdivs = 20;
let heights = DMatrix::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);
x.sin() + z.cos()
}
});
let rigid_body = RigidBodyBuilder::new_static().build();
let handle = bodies.insert(rigid_body);
let collider = ColliderBuilder::heightfield(heights, ground_size).build();
colliders.insert(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::new_dynamic().translation(x, y, z).build();
let handle = bodies.insert(rigid_body);
if j % 2 == 0 {
let collider = ColliderBuilder::cuboid(rad, rad, rad).build();
colliders.insert(collider, handle, &mut bodies);
} else {
let collider = ColliderBuilder::ball(rad).build();
colliders.insert(collider, handle, &mut bodies);
}
}
}
}
/*
* Set up the testbed.
*/
testbed.set_world(bodies, colliders, joints);
testbed.look_at(Point3::new(100.0, 100.0, 100.0), Point3::origin());
}
fn main() {
let testbed = Testbed::from_builders(0, vec![("Boxes", init_world)]);
testbed.run()
}

View File

@@ -32,7 +32,7 @@ pub fn init_world(testbed: &mut Testbed) {
.translation(fk * shift, 0.0, fi * shift)
.build();
let child_handle = bodies.insert(rigid_body);
let collider = ColliderBuilder::ball(rad).density(1.0).build();
let collider = ColliderBuilder::ball(rad).build();
colliders.insert(collider, child_handle, &mut bodies);
// Vertical joint.

View File

@@ -45,7 +45,7 @@ pub fn init_world(testbed: &mut Testbed) {
.translation(x + fk * shift, y, z + fi * shift)
.build();
let child_handle = bodies.insert(rigid_body);
let collider = ColliderBuilder::ball(rad).density(1.0).build();
let collider = ColliderBuilder::ball(rad).build();
colliders.insert(collider, child_handle, &mut bodies);
// Vertical joint.

View File

@@ -48,9 +48,7 @@ pub fn build_block(
)
.build();
let handle = bodies.insert(rigid_body);
let collider = ColliderBuilder::cuboid(dim.x, dim.y, dim.z)
.density(1.0)
.build();
let collider = ColliderBuilder::cuboid(dim.x, dim.y, dim.z).build();
colliders.insert(collider, handle, bodies);
testbed.set_body_color(handle, color0);
@@ -73,9 +71,7 @@ pub fn build_block(
)
.build();
let handle = bodies.insert(rigid_body);
let collider = ColliderBuilder::cuboid(dim.x, dim.y, dim.z)
.density(1.0)
.build();
let collider = ColliderBuilder::cuboid(dim.x, dim.y, dim.z).build();
colliders.insert(collider, handle, bodies);
testbed.set_body_color(handle, color0);
std::mem::swap(&mut color0, &mut color1);

View File

@@ -28,9 +28,7 @@ fn create_pyramid(
let rigid_body_handle = bodies.insert(rigid_body);
let collider =
ColliderBuilder::cuboid(half_extents.x, half_extents.y, half_extents.z)
.density(1.0)
.build();
ColliderBuilder::cuboid(half_extents.x, half_extents.y, half_extents.z).build();
colliders.insert(collider, rigid_body_handle, bodies);
}
}

191
benchmarks3d/stacks3.rs Normal file
View File

@@ -0,0 +1,191 @@
use na::{Point3, Translation3, UnitQuaternion, Vector3};
use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet};
use rapier3d::geometry::{ColliderBuilder, ColliderSet};
use rapier_testbed3d::Testbed;
fn create_tower_circle(
bodies: &mut RigidBodySet,
colliders: &mut ColliderSet,
offset: Vector3<f32>,
stack_height: usize,
nsubdivs: usize,
half_extents: Vector3<f32>,
) {
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 = Translation3::from(offset)
* UnitQuaternion::new(Vector3::y() * (fi / 2.0 + fj) * ang_step)
* Translation3::new(0.0, y, radius);
// Build the rigid body.
let rigid_body = RigidBodyBuilder::new_dynamic().position(pos).build();
let handle = bodies.insert(rigid_body);
let collider =
ColliderBuilder::cuboid(half_extents.x, half_extents.y, half_extents.z).build();
colliders.insert(collider, handle, bodies);
}
}
}
fn create_wall(
bodies: &mut RigidBodySet,
colliders: &mut ColliderSet,
offset: Vector3<f32>,
stack_height: usize,
half_extents: Vector3<f32>,
) {
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::new_dynamic().translation(x, y, z).build();
let handle = bodies.insert(rigid_body);
let collider =
ColliderBuilder::cuboid(half_extents.x, half_extents.y, half_extents.z).build();
colliders.insert(collider, handle, bodies);
}
}
}
fn create_pyramid(
bodies: &mut RigidBodySet,
colliders: &mut ColliderSet,
offset: Vector3<f32>,
stack_height: usize,
half_extents: Vector3<f32>,
) {
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::new_dynamic().translation(x, y, z).build();
let handle = bodies.insert(rigid_body);
let collider =
ColliderBuilder::cuboid(half_extents.x, half_extents.y, half_extents.z).build();
colliders.insert(collider, handle, bodies);
}
}
}
}
pub fn init_world(testbed: &mut Testbed) {
/*
* World
*/
let mut bodies = RigidBodySet::new();
let mut colliders = ColliderSet::new();
let joints = JointSet::new();
/*
* Ground
*/
let ground_size = 200.0;
let ground_height = 0.1;
let rigid_body = RigidBodyBuilder::new_static()
.translation(0.0, -ground_height, 0.0)
.build();
let handle = bodies.insert(rigid_body);
let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size).build();
colliders.insert(collider, handle, &mut bodies);
/*
* Create the cubes
*/
let cube_size = 1.0;
let hext = Vector3::repeat(cube_size);
let bottomy = cube_size * 50.0;
create_pyramid(
&mut bodies,
&mut colliders,
Vector3::new(-110.0, bottomy, 0.0),
12,
hext,
);
create_pyramid(
&mut bodies,
&mut colliders,
Vector3::new(-80.0, bottomy, 0.0),
12,
hext,
);
create_pyramid(
&mut bodies,
&mut colliders,
Vector3::new(-50.0, bottomy, 0.0),
12,
hext,
);
create_pyramid(
&mut bodies,
&mut colliders,
Vector3::new(-20.0, bottomy, 0.0),
12,
hext,
);
create_wall(
&mut bodies,
&mut colliders,
Vector3::new(-2.0, bottomy, 0.0),
12,
hext,
);
create_wall(
&mut bodies,
&mut colliders,
Vector3::new(4.0, bottomy, 0.0),
12,
hext,
);
create_wall(
&mut bodies,
&mut colliders,
Vector3::new(10.0, bottomy, 0.0),
12,
hext,
);
create_tower_circle(
&mut bodies,
&mut colliders,
Vector3::new(25.0, bottomy, 0.0),
8,
24,
hext,
);
/*
* Set up the testbed.
*/
testbed.set_world(bodies, colliders, joints);
testbed.look_at(Point3::new(100.0, 100.0, 100.0), Point3::origin());
}
fn main() {
let testbed = Testbed::from_builders(0, vec![("Boxes", init_world)]);
testbed.run()
}

88
benchmarks3d/trimesh3.rs Normal file
View File

@@ -0,0 +1,88 @@
use na::Point3;
use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet};
use rapier3d::geometry::{ColliderBuilder, ColliderSet};
use rapier_testbed3d::Testbed;
pub fn init_world(testbed: &mut Testbed) {
/*
* World
*/
let mut bodies = RigidBodySet::new();
let mut colliders = ColliderSet::new();
let joints = JointSet::new();
/*
* Ground
*/
let ground_size = 200.0f32;
let ground_height = 1.0;
let nsubdivs = 20;
let quad = rapier3d::ncollide::procedural::quad(ground_size, ground_size, nsubdivs, nsubdivs);
let indices = quad
.flat_indices()
.chunks(3)
.map(|is| Point3::new(is[0], is[2], is[1]))
.collect();
let mut vertices = quad.coords;
// ncollide generates a quad with `z` as the normal.
// so we switch z and y here and set a random altitude at each point.
for p in vertices.iter_mut() {
p.z = p.y;
p.y = (p.x.sin() + p.z.cos()) * ground_height;
if p.x.abs() == ground_size / 2.0 || p.z.abs() == ground_size / 2.0 {
p.y = 10.0;
}
}
let rigid_body = RigidBodyBuilder::new_static().build();
let handle = bodies.insert(rigid_body);
let collider = ColliderBuilder::trimesh(vertices, indices).build();
colliders.insert(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::new_dynamic().translation(x, y, z).build();
let handle = bodies.insert(rigid_body);
if j % 2 == 0 {
let collider = ColliderBuilder::cuboid(rad, rad, rad).build();
colliders.insert(collider, handle, &mut bodies);
} else {
let collider = ColliderBuilder::ball(rad).build();
colliders.insert(collider, handle, &mut bodies);
}
}
}
}
/*
* Set up the testbed.
*/
testbed.set_world(bodies, colliders, joints);
testbed.look_at(Point3::new(100.0, 100.0, 100.0), Point3::origin());
}
fn main() {
let testbed = Testbed::from_builders(0, vec![("Boxes", init_world)]);
testbed.run()
}

View File

@@ -15,7 +15,7 @@ pub fn init_world(testbed: &mut Testbed) {
.translation(0.0, 10.0)
.build();
let handle = physics.bodies.insert(rigid_body);
let collider = ColliderBuilder::cuboid(rad, rad).density(1.0).build();
let collider = ColliderBuilder::cuboid(rad, rad).build();
physics
.colliders
.insert(collider, handle, &mut physics.bodies);

View File

@@ -50,7 +50,7 @@ pub fn init_world(testbed: &mut Testbed) {
// Build the rigid body.
let rigid_body = RigidBodyBuilder::new(status).translation(x, y).build();
let handle = bodies.insert(rigid_body);
let collider = ColliderBuilder::ball(rad).density(1.0).build();
let collider = ColliderBuilder::ball(rad).build();
colliders.insert(collider, handle, &mut bodies);
}
}

View File

@@ -55,7 +55,7 @@ pub fn init_world(testbed: &mut Testbed) {
// Build the rigid body.
let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y).build();
let handle = bodies.insert(rigid_body);
let collider = ColliderBuilder::cuboid(rad, rad).density(1.0).build();
let collider = ColliderBuilder::cuboid(rad, rad).build();
colliders.insert(collider, handle, &mut bodies);
}
}

View File

@@ -56,9 +56,7 @@ pub fn init_world(testbed: &mut Testbed) {
// Build the rigid body.
let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y).build();
let handle = bodies.insert(rigid_body);
let collider = ColliderBuilder::capsule_y(rad * 1.5, rad)
.density(1.0)
.build();
let collider = ColliderBuilder::capsule_y(rad * 1.5, rad).build();
colliders.insert(collider, handle, &mut bodies);
}
}

View File

@@ -28,7 +28,7 @@ pub fn init_world(testbed: &mut Testbed) {
.can_sleep(false)
.build();
let handle = bodies.insert(rigid_body);
let collider = ColliderBuilder::ball(rad).density(1.0).build();
let collider = ColliderBuilder::ball(rad).build();
colliders.insert(collider, handle, &mut bodies);
/*

View File

@@ -50,10 +50,10 @@ pub fn init_world(testbed: &mut Testbed) {
let handle = bodies.insert(rigid_body);
if j % 2 == 0 {
let collider = ColliderBuilder::cuboid(rad, rad).density(1.0).build();
let collider = ColliderBuilder::cuboid(rad, rad).build();
colliders.insert(collider, handle, &mut bodies);
} else {
let collider = ColliderBuilder::ball(rad).density(1.0).build();
let collider = ColliderBuilder::ball(rad).build();
colliders.insert(collider, handle, &mut bodies);
}
}

View File

@@ -40,7 +40,7 @@ pub fn init_world(testbed: &mut Testbed) {
.translation(fk * shift, -fi * shift)
.build();
let child_handle = bodies.insert(rigid_body);
let collider = ColliderBuilder::ball(rad).density(1.0).build();
let collider = ColliderBuilder::ball(rad).build();
colliders.insert(collider, child_handle, &mut bodies);
// Vertical joint.

View File

@@ -42,7 +42,7 @@ pub fn init_world(testbed: &mut Testbed) {
// Build the rigid body.
let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y).build();
let handle = bodies.insert(rigid_body);
let collider = ColliderBuilder::cuboid(rad, rad).density(1.0).build();
let collider = ColliderBuilder::cuboid(rad, rad).build();
colliders.insert(collider, handle, &mut bodies);
}
}
@@ -54,9 +54,7 @@ pub fn init_world(testbed: &mut Testbed) {
.translation(-10.0 * rad, 1.5 + 0.8)
.build();
let platform_handle = bodies.insert(platform_body);
let collider = ColliderBuilder::cuboid(rad * 10.0, rad)
.density(1.0)
.build();
let collider = ColliderBuilder::cuboid(rad * 10.0, rad).build();
colliders.insert(collider, platform_handle, &mut bodies);
/*

View File

@@ -42,7 +42,7 @@ pub fn init_world(testbed: &mut Testbed) {
// Build the rigid body.
let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y).build();
let handle = bodies.insert(rigid_body);
let collider = ColliderBuilder::cuboid(rad, rad).density(1.0).build();
let collider = ColliderBuilder::cuboid(rad, rad).build();
colliders.insert(collider, handle, &mut bodies);
}
}

View File

@@ -40,7 +40,7 @@ pub fn init_world(testbed: &mut Testbed) {
// Build the rigid body.
let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y).build();
let handle = bodies.insert(rigid_body);
let collider = ColliderBuilder::cuboid(rad, rad).density(1.0).build();
let collider = ColliderBuilder::cuboid(rad, rad).build();
colliders.insert(collider, handle, &mut bodies);
testbed.set_body_color(handle, Point3::new(0.5, 0.5, 1.0));
@@ -58,7 +58,7 @@ pub fn init_world(testbed: &mut Testbed) {
// Solid cube attached to the sensor which
// other colliders can touch.
let collider = ColliderBuilder::cuboid(rad, rad).density(1.0).build();
let collider = ColliderBuilder::cuboid(rad, rad).build();
colliders.insert(collider, sensor_handle, &mut bodies);
// We create a collider desc without density because we don't

View File

@@ -37,7 +37,7 @@ pub fn init_world(testbed: &mut Testbed) {
.translation(fk * shift, -fi * shift)
.build();
let child_handle = bodies.insert(rigid_body);
let collider = ColliderBuilder::ball(rad).density(1.0).build();
let collider = ColliderBuilder::ball(rad).build();
colliders.insert(collider, child_handle, &mut bodies);
// Vertical joint.

View File

@@ -42,7 +42,7 @@ pub fn init_world(testbed: &mut Testbed) {
.translation(x + fk * shift, y - fi * shift)
.build();
let child_handle = bodies.insert(rigid_body);
let collider = ColliderBuilder::ball(rad).density(1.0).build();
let collider = ColliderBuilder::ball(rad).build();
colliders.insert(collider, child_handle, &mut bodies);
// Vertical joint.

View File

@@ -15,7 +15,7 @@ pub fn init_world(testbed: &mut Testbed) {
.translation(0.0, 10.0, 0.0)
.build();
let handle = physics.bodies.insert(rigid_body);
let collider = ColliderBuilder::cuboid(rad, rad, rad).density(1.0).build();
let collider = ColliderBuilder::cuboid(rad, rad, rad).build();
physics
.colliders
.insert(collider, handle, &mut physics.bodies);

View File

@@ -11,24 +11,17 @@ use rapier_testbed3d::Testbed;
use std::cmp::Ordering;
mod add_remove3;
mod balls3;
mod boxes3;
mod capsules3;
mod compound3;
mod debug_boxes3;
mod debug_triangle3;
mod domino3;
mod heightfield3;
mod joints3;
mod kinematic3;
mod pyramid3;
mod keva3;
mod platform3;
mod primitives3;
mod sensor3;
mod stacks3;
mod stress_joint_ball3;
mod stress_joint_fixed3;
mod stress_joint_prismatic3;
mod stress_joint_revolute3;
mod stress_keva3;
mod trimesh3;
fn demo_name_from_command_line() -> Option<String> {
@@ -69,31 +62,18 @@ pub fn main() {
let mut builders: Vec<(_, fn(&mut Testbed))> = vec![
("Add remove", add_remove3::init_world),
("Balls", balls3::init_world),
("Boxes", boxes3::init_world),
("Capsules", capsules3::init_world),
("Primitives", primitives3::init_world),
("Compound", compound3::init_world),
("Domino", domino3::init_world),
("Heightfield", heightfield3::init_world),
("Joints", joints3::init_world),
("Kinematic", kinematic3::init_world),
("Platform", platform3::init_world),
("Stacks", stacks3::init_world),
("Pyramid", pyramid3::init_world),
("Sensor", sensor3::init_world),
("Trimesh", trimesh3::init_world),
("Keva tower", keva3::init_world),
("(Debug) boxes", debug_boxes3::init_world),
("(Debug) triangle", debug_triangle3::init_world),
("(Stress test) joint ball", stress_joint_ball3::init_world),
("(Stress test) joint fixed", stress_joint_fixed3::init_world),
(
"(Stress test) joint revolute",
stress_joint_revolute3::init_world,
),
(
"(Stress test) joint prismatic",
stress_joint_prismatic3::init_world,
),
("(Stress test) keva tower", stress_keva3::init_world),
];
// Lexicographic sort, with stress tests moved at the end of the list.

View File

@@ -1,29 +0,0 @@
use na::Point3;
use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet};
use rapier3d::geometry::{ColliderBuilder, ColliderSet};
use rapier_testbed3d::Testbed;
pub fn init_world(testbed: &mut Testbed) {
/*
* World
*/
let mut bodies = RigidBodySet::new();
let mut colliders = ColliderSet::new();
let joints = JointSet::new();
let rb = RigidBodyBuilder::new_dynamic().build();
let co = ColliderBuilder::cuboid(0.5, 0.5, 0.5).build();
let h = bodies.insert(rb);
colliders.insert(co, h, &mut bodies);
/*
* Set up the testbed.
*/
testbed.set_world(bodies, colliders, joints);
testbed.look_at(Point3::new(100.0, 100.0, 100.0), Point3::origin());
}
fn main() {
let testbed = Testbed::from_builders(0, vec![("Balls", init_world)]);
testbed.run()
}

View File

@@ -14,7 +14,7 @@ pub fn init_world(testbed: &mut Testbed) {
/*
* Ground
*/
let ground_size = 200.1;
let ground_size = 50.0;
let ground_height = 0.1;
let rigid_body = RigidBodyBuilder::new_static()
@@ -37,7 +37,7 @@ pub fn init_world(testbed: &mut Testbed) {
let mut offset = -(num as f32) * (rad * 2.0 + rad) * 0.5;
for j in 0usize..25 {
for j in 0usize..15 {
for i in 0..num {
for k in 0usize..num {
let x = i as f32 * shift * 5.0 - centerx + offset;

View File

@@ -31,7 +31,7 @@ pub fn init_world(testbed: &mut Testbed) {
.can_sleep(false)
.build();
let handle = bodies.insert(rigid_body);
let collider = ColliderBuilder::cuboid(2.0, 0.1, 1.0).density(1.0).build();
let collider = ColliderBuilder::cuboid(2.0, 0.1, 1.0).build();
colliders.insert(collider, handle, &mut bodies);
/*

View File

@@ -32,7 +32,7 @@ pub fn init_world(testbed: &mut Testbed) {
.can_sleep(false)
.build();
let handle = bodies.insert(rigid_body);
let collider = ColliderBuilder::cuboid(20.0, 0.1, 1.0).density(1.0).build();
let collider = ColliderBuilder::cuboid(20.0, 0.1, 1.0).build();
colliders.insert(collider, handle, &mut bodies);
/*

View File

@@ -58,9 +58,7 @@ pub fn init_world(testbed: &mut Testbed) {
* rot;
let rigid_body = RigidBodyBuilder::new_dynamic().position(position).build();
let handle = bodies.insert(rigid_body);
let collider = ColliderBuilder::cuboid(thickness, width * 2.0, width)
.density(1.0)
.build();
let collider = ColliderBuilder::cuboid(thickness, width * 2.0, width).build();
colliders.insert(collider, handle, &mut bodies);
testbed.set_body_color(handle, colors[i % 2]);
} else {

View File

@@ -14,7 +14,7 @@ pub fn init_world(testbed: &mut Testbed) {
/*
* Ground
*/
let ground_size = Vector3::new(200.0, 1.0, 200.0);
let ground_size = Vector3::new(100.0, 1.0, 100.0);
let nsubdivs = 20;
let heights = DMatrix::from_fn(nsubdivs + 1, nsubdivs + 1, |i, j| {
@@ -43,7 +43,7 @@ pub fn init_world(testbed: &mut Testbed) {
let centery = shift / 2.0;
let centerz = shift * (num / 2) as f32;
for j in 0usize..47 {
for j in 0usize..20 {
for i in 0..num {
for k in 0usize..num {
let x = i as f32 * shift - centerx;
@@ -55,10 +55,10 @@ pub fn init_world(testbed: &mut Testbed) {
let handle = bodies.insert(rigid_body);
if j % 2 == 0 {
let collider = ColliderBuilder::cuboid(rad, rad, rad).density(1.0).build();
let collider = ColliderBuilder::cuboid(rad, rad, rad).build();
colliders.insert(collider, handle, &mut bodies);
} else {
let collider = ColliderBuilder::ball(rad).density(1.0).build();
let collider = ColliderBuilder::ball(rad).build();
colliders.insert(collider, handle, &mut bodies);
}
}

View File

@@ -150,7 +150,7 @@ fn create_fixed_joints(
.translation(origin.x + fk * shift, origin.y, origin.z + fi * shift)
.build();
let child_handle = bodies.insert(rigid_body);
let collider = ColliderBuilder::ball(rad).density(1.0).build();
let collider = ColliderBuilder::ball(rad).build();
colliders.insert(collider, child_handle, bodies);
// Vertical joint.
@@ -205,7 +205,7 @@ fn create_ball_joints(
.translation(fk * shift, 0.0, fi * shift)
.build();
let child_handle = bodies.insert(rigid_body);
let collider = ColliderBuilder::ball(rad).density(1.0).build();
let collider = ColliderBuilder::ball(rad).build();
colliders.insert(collider, child_handle, bodies);
// Vertical joint.

144
examples3d/keva3.rs Normal file
View File

@@ -0,0 +1,144 @@
use na::{Point3, Vector3};
use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet};
use rapier3d::geometry::{ColliderBuilder, ColliderSet};
use rapier_testbed3d::Testbed;
pub fn build_block(
testbed: &mut Testbed,
bodies: &mut RigidBodySet,
colliders: &mut ColliderSet,
half_extents: Vector3<f32>,
shift: Vector3<f32>,
mut numx: usize,
numy: usize,
mut numz: 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 = Point3::new(0.7, 0.5, 0.9);
let mut color1 = Point3::new(0.6, 1.0, 0.6);
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::new_dynamic()
.translation(
x + dim.x + shift.x,
y + dim.y + shift.y,
z + dim.z + shift.z,
)
.build();
let handle = bodies.insert(rigid_body);
let collider = ColliderBuilder::cuboid(dim.x, dim.y, dim.z).build();
colliders.insert(collider, handle, bodies);
testbed.set_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 as f32 * 2.0)) as usize {
for j in 0..(block_width / (dim.z as f32 * 2.0)) as usize {
// Build the rigid body.
let rigid_body = RigidBodyBuilder::new_dynamic()
.translation(
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,
)
.build();
let handle = bodies.insert(rigid_body);
let collider = ColliderBuilder::cuboid(dim.x, dim.y, dim.z).build();
colliders.insert(collider, handle, bodies);
testbed.set_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 joints = JointSet::new();
/*
* Ground
*/
let ground_size = 50.0;
let ground_height = 0.1;
let rigid_body = RigidBodyBuilder::new_static()
.translation(0.0, -ground_height, 0.0)
.build();
let handle = bodies.insert(rigid_body);
let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size).build();
colliders.insert(collider, handle, &mut bodies);
/*
* Create the cubes
*/
let half_extents = Vector3::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];
let mut num_blocks_built = 0;
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,
Vector3::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;
num_blocks_built += numx * numy * numz;
}
println!("Num keva blocks: {}", num_blocks_built);
/*
* Set up the testbed.
*/
testbed.set_world(bodies, colliders, joints);
testbed.look_at(Point3::new(100.0, 100.0, 100.0), Point3::origin());
}
fn main() {
let testbed = Testbed::from_builders(0, vec![("Boxes", init_world)]);
testbed.run()
}

View File

@@ -45,7 +45,7 @@ pub fn init_world(testbed: &mut Testbed) {
// Build the rigid body.
let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y, z).build();
let handle = bodies.insert(rigid_body);
let collider = ColliderBuilder::cuboid(rad, rad, rad).density(1.0).build();
let collider = ColliderBuilder::cuboid(rad, rad, rad).build();
colliders.insert(collider, handle, &mut bodies);
}
}
@@ -58,9 +58,7 @@ pub fn init_world(testbed: &mut Testbed) {
.translation(0.0, 1.5 + 0.8, -10.0 * rad)
.build();
let platform_handle = bodies.insert(platform_body);
let collider = ColliderBuilder::cuboid(rad * 10.0, rad, rad * 10.0)
.density(1.0)
.build();
let collider = ColliderBuilder::cuboid(rad * 10.0, rad, rad * 10.0).build();
colliders.insert(collider, platform_handle, &mut bodies);
/*

75
examples3d/primitives3.rs Normal file
View File

@@ -0,0 +1,75 @@
use na::Point3;
use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet};
use rapier3d::geometry::{ColliderBuilder, ColliderSet};
use rapier_testbed3d::Testbed;
pub fn init_world(testbed: &mut Testbed) {
/*
* World
*/
let mut bodies = RigidBodySet::new();
let mut colliders = ColliderSet::new();
let joints = JointSet::new();
/*
* Ground
*/
let ground_size = 100.1;
let ground_height = 0.1;
let rigid_body = RigidBodyBuilder::new_static()
.translation(0.0, -ground_height, 0.0)
.build();
let handle = bodies.insert(rigid_body);
let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size).build();
colliders.insert(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;
let mut offset = -(num as f32) * (rad * 2.0 + rad) * 0.5;
for j in 0usize..20 {
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;
// Build the rigid body.
let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y, z).build();
let handle = bodies.insert(rigid_body);
let collider = match j % 2 {
0 => ColliderBuilder::cuboid(rad, rad, rad).build(),
1 => ColliderBuilder::ball(rad).build(),
// 2 => ColliderBuilder::capsule_y(rad, rad).build(),
_ => unreachable!(),
};
colliders.insert(collider, handle, &mut bodies);
}
}
offset -= 0.05 * rad * (num as f32 - 1.0);
}
/*
* Set up the testbed.
*/
testbed.set_world(bodies, colliders, joints);
testbed.look_at(Point3::new(100.0, 100.0, 100.0), Point3::origin());
}
fn main() {
let testbed = Testbed::from_builders(0, vec![("Boxes", init_world)]);
testbed.run()
}

View File

@@ -43,7 +43,7 @@ pub fn init_world(testbed: &mut Testbed) {
// Build the rigid body.
let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y, z).build();
let handle = bodies.insert(rigid_body);
let collider = ColliderBuilder::cuboid(rad, rad, rad).density(1.0).build();
let collider = ColliderBuilder::cuboid(rad, rad, rad).build();
colliders.insert(collider, handle, &mut bodies);
testbed.set_body_color(handle, Point3::new(0.5, 0.5, 1.0));
@@ -56,13 +56,13 @@ pub fn init_world(testbed: &mut Testbed) {
// Rigid body so that the sensor can move.
let sensor = RigidBodyBuilder::new_dynamic()
.translation(0.0, 10.0, 0.0)
.translation(0.0, 5.0, 0.0)
.build();
let sensor_handle = bodies.insert(sensor);
// Solid cube attached to the sensor which
// other colliders can touch.
let collider = ColliderBuilder::cuboid(rad, rad, rad).density(1.0).build();
let collider = ColliderBuilder::cuboid(rad, rad, rad).build();
colliders.insert(collider, sensor_handle, &mut bodies);
// We create a collider desc without density because we don't

View File

@@ -27,9 +27,8 @@ fn create_tower_circle(
// Build the rigid body.
let rigid_body = RigidBodyBuilder::new_dynamic().position(pos).build();
let handle = bodies.insert(rigid_body);
let collider = ColliderBuilder::cuboid(half_extents.x, half_extents.y, half_extents.z)
.density(1.0)
.build();
let collider =
ColliderBuilder::cuboid(half_extents.x, half_extents.y, half_extents.z).build();
colliders.insert(collider, handle, bodies);
}
}
@@ -55,9 +54,8 @@ fn create_wall(
// Build the rigid body.
let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y, z).build();
let handle = bodies.insert(rigid_body);
let collider = ColliderBuilder::cuboid(half_extents.x, half_extents.y, half_extents.z)
.density(1.0)
.build();
let collider =
ColliderBuilder::cuboid(half_extents.x, half_extents.y, half_extents.z).build();
colliders.insert(collider, handle, bodies);
}
}
@@ -88,9 +86,7 @@ fn create_pyramid(
let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y, z).build();
let handle = bodies.insert(rigid_body);
let collider =
ColliderBuilder::cuboid(half_extents.x, half_extents.y, half_extents.z)
.density(1.0)
.build();
ColliderBuilder::cuboid(half_extents.x, half_extents.y, half_extents.z).build();
colliders.insert(collider, handle, bodies);
}
}
@@ -124,27 +120,7 @@ pub fn init_world(testbed: &mut Testbed) {
let cube_size = 1.0;
let hext = Vector3::repeat(cube_size);
let bottomy = cube_size * 50.0;
create_pyramid(
&mut bodies,
&mut colliders,
Vector3::new(-110.0, bottomy, 0.0),
12,
hext,
);
create_pyramid(
&mut bodies,
&mut colliders,
Vector3::new(-80.0, bottomy, 0.0),
12,
hext,
);
create_pyramid(
&mut bodies,
&mut colliders,
Vector3::new(-50.0, bottomy, 0.0),
12,
hext,
);
create_pyramid(
&mut bodies,
&mut colliders,

View File

@@ -14,7 +14,7 @@ pub fn init_world(testbed: &mut Testbed) {
/*
* Ground
*/
let ground_size = 200.0f32;
let ground_size = 100.0f32;
let ground_height = 1.0;
let nsubdivs = 20;
@@ -53,7 +53,7 @@ pub fn init_world(testbed: &mut Testbed) {
let centery = shift / 2.0;
let centerz = shift * (num / 2) as f32;
for j in 0usize..47 {
for j in 0usize..20 {
for i in 0..num {
for k in 0usize..num {
let x = i as f32 * shift - centerx;
@@ -65,10 +65,10 @@ pub fn init_world(testbed: &mut Testbed) {
let handle = bodies.insert(rigid_body);
if j % 2 == 0 {
let collider = ColliderBuilder::cuboid(rad, rad, rad).density(1.0).build();
let collider = ColliderBuilder::cuboid(rad, rad, rad).build();
colliders.insert(collider, handle, &mut bodies);
} else {
let collider = ColliderBuilder::ball(rad).density(1.0).build();
let collider = ColliderBuilder::ball(rad).build();
colliders.insert(collider, handle, &mut bodies);
}
}

View File

@@ -212,7 +212,7 @@ pub struct ColliderBuilder {
/// The shape of the collider to be built.
pub shape: Shape,
/// The density of the collider to be built.
pub density: f32,
density: Option<f32>,
/// The friction coefficient of the collider to be built.
pub friction: f32,
/// The restitution coefficient of the collider to be built.
@@ -228,7 +228,7 @@ impl ColliderBuilder {
pub fn new(shape: Shape) -> Self {
Self {
shape,
density: 1.0,
density: None,
friction: Self::default_friction(),
restitution: 0.0,
delta: Isometry::identity(),
@@ -236,6 +236,12 @@ impl ColliderBuilder {
}
}
/// The density of the collider being built.
pub fn get_density(&self) -> f32 {
let default_density = if self.is_sensor { 0.0 } else { 1.0 };
self.density.unwrap_or(default_density)
}
/// Initialize a new collider builder with a ball shape defined by its radius.
pub fn ball(radius: f32) -> Self {
Self::new(Shape::Ball(Ball::new(radius)))
@@ -349,7 +355,7 @@ impl ColliderBuilder {
/// Sets the density of the collider this builder will build.
pub fn density(mut self, density: f32) -> Self {
self.density = density;
self.density = Some(density);
self
}
@@ -395,9 +401,11 @@ impl ColliderBuilder {
/// Buildes a new collider attached to the given rigid-body.
pub fn build(&self) -> Collider {
let density = self.get_density();
Collider {
shape: self.shape.clone(),
density: self.density,
density,
friction: self.friction,
restitution: self.restitution,
delta: self.delta,