Implement multibody joints and the new solver
This commit is contained in:
24
.github/workflows/rapier-ci-build.yml
vendored
24
.github/workflows/rapier-ci-build.yml
vendored
@@ -28,13 +28,13 @@ jobs:
|
||||
- name: Build rapier3d
|
||||
run: cargo build --verbose -p rapier3d;
|
||||
- name: Build rapier2d SIMD
|
||||
run: cd build/rapier2d; cargo build --verbose --features simd-stable;
|
||||
run: cd crates/rapier2d; cargo build --verbose --features simd-stable;
|
||||
- name: Build rapier3d SIMD
|
||||
run: cd build/rapier3d; cargo build --verbose --features simd-stable;
|
||||
run: cd crates/rapier3d; cargo build --verbose --features simd-stable;
|
||||
- name: Build rapier2d SIMD Parallel
|
||||
run: cd build/rapier2d; cargo build --verbose --features simd-stable --features parallel;
|
||||
run: cd crates/rapier2d; cargo build --verbose --features simd-stable --features parallel;
|
||||
- name: Build rapier3d SIMD Parallel
|
||||
run: cd build/rapier3d; cargo build --verbose --features simd-stable --features parallel;
|
||||
run: cd crates/rapier3d; cargo build --verbose --features simd-stable --features parallel;
|
||||
- name: Run tests
|
||||
run: cargo test
|
||||
- name: Check rapier_testbed2d
|
||||
@@ -42,9 +42,9 @@ jobs:
|
||||
- name: Check rapier_testbed3d
|
||||
run: cargo check --verbose -p rapier_testbed3d;
|
||||
- name: Check rapier_testbed2d --features parallel
|
||||
run: cd build/rapier_testbed2d; cargo check --verbose --features parallel;
|
||||
run: cd crates/rapier_testbed2d; cargo check --verbose --features parallel;
|
||||
- name: Check rapier_testbed3d --features parallel
|
||||
run: cd build/rapier_testbed3d; cargo check --verbose --features parallel;
|
||||
run: cd crates/rapier_testbed3d; cargo check --verbose --features parallel;
|
||||
- name: Check rapier-examples-2d
|
||||
run: cargo check -j 1 --verbose -p rapier-examples-2d;
|
||||
- name: Check rapier-examples-3d
|
||||
@@ -57,9 +57,9 @@ jobs:
|
||||
- uses: actions/checkout@v2
|
||||
- run: rustup target add wasm32-unknown-unknown
|
||||
- name: build rapier2d
|
||||
run: cd build/rapier2d && cargo build --verbose --features wasm-bindgen --target wasm32-unknown-unknown;
|
||||
run: cd crates/rapier2d && cargo build --verbose --features wasm-bindgen --target wasm32-unknown-unknown;
|
||||
- name: build rapier3d
|
||||
run: cd build/rapier3d && cargo build --verbose --features wasm-bindgen --target wasm32-unknown-unknown;
|
||||
run: cd crates/rapier3d && cargo build --verbose --features wasm-bindgen --target wasm32-unknown-unknown;
|
||||
build-wasm-emscripten:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
@@ -68,10 +68,10 @@ jobs:
|
||||
- uses: actions/checkout@v2
|
||||
- run: rustup target add wasm32-unknown-emscripten
|
||||
- name: build rapier2d
|
||||
run: cd build/rapier2d && cargo build --verbose --target wasm32-unknown-emscripten;
|
||||
run: cd crates/rapier2d && cargo build --verbose --target wasm32-unknown-emscripten;
|
||||
- name: build rapier3d
|
||||
run: cd build/rapier3d && cargo build --verbose --target wasm32-unknown-emscripten;
|
||||
run: cd crates/rapier3d && cargo build --verbose --target wasm32-unknown-emscripten;
|
||||
- name: build rapier2d --features simd-stable
|
||||
run: cd build/rapier2d && cargo build --verbose --target wasm32-unknown-emscripten --features simd-stable;
|
||||
run: cd crates/rapier2d && cargo build --verbose --target wasm32-unknown-emscripten --features simd-stable;
|
||||
- name: build rapier3d --features simd-stable
|
||||
run: cd build/rapier3d && cargo build --verbose --target wasm32-unknown-emscripten --features simd-stable;
|
||||
run: cd crates/rapier3d && cargo build --verbose --target wasm32-unknown-emscripten --features simd-stable;
|
||||
|
||||
22
Cargo.toml
22
Cargo.toml
@@ -1,21 +1,17 @@
|
||||
[workspace]
|
||||
members = [ "build/rapier2d", "build/rapier2d-f64", "build/rapier_testbed2d", "examples2d", "benchmarks2d",
|
||||
"build/rapier3d", "build/rapier3d-f64", "build/rapier_testbed3d", "examples3d", "benchmarks3d" ]
|
||||
members = [ "crates/rapier2d", "crates/rapier2d-f64", "crates/rapier_testbed2d", "examples2d", "benchmarks2d",
|
||||
"crates/rapier3d", "crates/rapier3d-f64", "crates/rapier_testbed3d", "examples3d", "benchmarks3d" ]
|
||||
resolver = "2"
|
||||
|
||||
[patch.crates-io]
|
||||
#wrapped2d = { git = "https://github.com/Bastacyclop/rust_box2d.git" }
|
||||
|
||||
#simba = { path = "../simba" }
|
||||
#ncollide2d = { path = "../ncollide/build/ncollide2d" }
|
||||
#ncollide3d = { path = "../ncollide/build/ncollide3d" }
|
||||
#nphysics2d = { path = "../nphysics/build/nphysics2d" }
|
||||
#nphysics3d = { path = "../nphysics/build/nphysics3d" }
|
||||
#kiss3d = { path = "../kiss3d" }
|
||||
#parry2d = { path = "../parry/build/parry2d" }
|
||||
#parry3d = { path = "../parry/build/parry3d" }
|
||||
#parry2d-f64 = { path = "../parry/build/parry2d-f64" }
|
||||
#parry3d-f64 = { path = "../parry/build/parry3d-f64" }
|
||||
#parry2d = { path = "../parry/crates/parry2d" }
|
||||
#parry3d = { path = "../parry/crates/parry3d" }
|
||||
#parry2d-f64 = { path = "../parry/crates/parry2d-f64" }
|
||||
#parry3d-f64 = { path = "../parry/crates/parry3d-f64" }
|
||||
#nalgebra = { path = "../nalgebra" }
|
||||
|
||||
#kiss3d = { git = "https://github.com/sebcrozet/kiss3d" }
|
||||
@@ -24,14 +20,10 @@ resolver = "2"
|
||||
#parry3d = { git = "https://github.com/dimforge/parry", branch = "special_cases" }
|
||||
#parry2d-f64 = { git = "https://github.com/dimforge/parry", branch = "special_cases" }
|
||||
#parry3d-f64 = { git = "https://github.com/dimforge/parry", branch = "special_cases" }
|
||||
#ncollide2d = { git = "https://github.com/dimforge/ncollide" }
|
||||
#ncollide3d = { git = "https://github.com/dimforge/ncollide" }
|
||||
#nphysics2d = { git = "https://github.com/dimforge/nphysics" }
|
||||
#nphysics3d = { git = "https://github.com/dimforge/nphysics" }
|
||||
|
||||
[profile.release]
|
||||
#debug = true
|
||||
codegen-units = 1
|
||||
#codegen-units = 1
|
||||
#opt-level = 1
|
||||
#lto = true
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
name = "rapier-benchmarks-2d"
|
||||
version = "0.1.0"
|
||||
authors = [ "Sébastien Crozet <developer@crozet.re>" ]
|
||||
edition = "2018"
|
||||
edition = "2021"
|
||||
|
||||
[features]
|
||||
parallel = [ "rapier2d/parallel", "rapier_testbed2d/parallel" ]
|
||||
@@ -16,10 +16,10 @@ rand = "0.8"
|
||||
Inflector = "0.11"
|
||||
|
||||
[dependencies.rapier_testbed2d]
|
||||
path = "../build/rapier_testbed2d"
|
||||
path = "../crates/rapier_testbed2d"
|
||||
|
||||
[dependencies.rapier2d]
|
||||
path = "../build/rapier2d"
|
||||
path = "../crates/rapier2d"
|
||||
|
||||
[[bin]]
|
||||
name = "all_benchmarks2"
|
||||
|
||||
@@ -7,7 +7,9 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
*/
|
||||
@@ -58,6 +60,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![0.0, 2.5], 5.0);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
@@ -63,6 +64,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![0.0, 50.0], 10.0);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
@@ -65,6 +66,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![0.0, 50.0], 10.0);
|
||||
}
|
||||
|
||||
@@ -9,7 +9,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
@@ -76,6 +77,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![0.0, 50.0], 10.0);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
@@ -63,6 +64,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![0.0, 50.0], 10.0);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let mut joints = JointSet::new();
|
||||
let mut impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Create the balls
|
||||
@@ -41,16 +42,16 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
// Vertical joint.
|
||||
if i > 0 {
|
||||
let parent_handle = *body_handles.last().unwrap();
|
||||
let joint = BallJoint::new(Point::origin(), point![0.0, shift]);
|
||||
joints.insert(parent_handle, child_handle, joint);
|
||||
let joint = RevoluteJoint::new().local_anchor2(point![0.0, shift]);
|
||||
impulse_joints.insert(parent_handle, child_handle, joint);
|
||||
}
|
||||
|
||||
// Horizontal joint.
|
||||
if k > 0 {
|
||||
let parent_index = body_handles.len() - numi;
|
||||
let parent_handle = body_handles[parent_index];
|
||||
let joint = BallJoint::new(Point::origin(), point![-shift, 0.0]);
|
||||
joints.insert(parent_handle, child_handle, joint);
|
||||
let joint = RevoluteJoint::new().local_anchor2(point![-shift, 0.0]);
|
||||
impulse_joints.insert(parent_handle, child_handle, joint);
|
||||
}
|
||||
|
||||
body_handles.push(child_handle);
|
||||
@@ -60,6 +61,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![numk as f32 * rad, numi as f32 * -rad], 5.0);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let mut joints = JointSet::new();
|
||||
let mut impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Create the balls
|
||||
@@ -46,22 +47,18 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
// Vertical joint.
|
||||
if i > 0 {
|
||||
let parent_handle = *body_handles.last().unwrap();
|
||||
let joint = FixedJoint::new(
|
||||
Isometry::identity(),
|
||||
Isometry::translation(0.0, shift),
|
||||
);
|
||||
joints.insert(parent_handle, child_handle, joint);
|
||||
let joint =
|
||||
FixedJoint::new().local_frame2(Isometry::translation(0.0, shift));
|
||||
impulse_joints.insert(parent_handle, child_handle, joint);
|
||||
}
|
||||
|
||||
// Horizontal joint.
|
||||
if k > 0 {
|
||||
let parent_index = body_handles.len() - num;
|
||||
let parent_handle = body_handles[parent_index];
|
||||
let joint = FixedJoint::new(
|
||||
Isometry::identity(),
|
||||
Isometry::translation(-shift, 0.0),
|
||||
);
|
||||
joints.insert(parent_handle, child_handle, joint);
|
||||
let joint =
|
||||
FixedJoint::new().local_frame2(Isometry::translation(-shift, 0.0));
|
||||
impulse_joints.insert(parent_handle, child_handle, joint);
|
||||
}
|
||||
|
||||
body_handles.push(child_handle);
|
||||
@@ -73,6 +70,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![50.0, 50.0], 5.0);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let mut joints = JointSet::new();
|
||||
let mut impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Create the balls
|
||||
@@ -46,12 +47,10 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
UnitVector::new_normalize(vector![-1.0, 1.0])
|
||||
};
|
||||
|
||||
let mut prism =
|
||||
PrismaticJoint::new(Point::origin(), axis, point![0.0, shift], axis);
|
||||
prism.limits_enabled = true;
|
||||
prism.limits[0] = -1.5;
|
||||
prism.limits[1] = 1.5;
|
||||
joints.insert(curr_parent, curr_child, prism);
|
||||
let mut prism = PrismaticJoint::new(axis)
|
||||
.local_anchor2(point![0.0, shift])
|
||||
.limit_axis([-1.5, 1.5]);
|
||||
impulse_joints.insert(curr_parent, curr_child, prism);
|
||||
|
||||
curr_parent = curr_child;
|
||||
}
|
||||
@@ -61,6 +60,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![80.0, 80.0], 15.0);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
@@ -50,6 +51,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![0.0, 2.5], 5.0);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
name = "rapier-benchmarks-3d"
|
||||
version = "0.1.0"
|
||||
authors = [ "Sébastien Crozet <developer@crozet.re>" ]
|
||||
edition = "2018"
|
||||
edition = "2021"
|
||||
|
||||
[features]
|
||||
parallel = [ "rapier3d/parallel", "rapier_testbed3d/parallel" ]
|
||||
@@ -16,10 +16,10 @@ rand = "0.8"
|
||||
Inflector = "0.11"
|
||||
|
||||
[dependencies.rapier_testbed3d]
|
||||
path = "../build/rapier_testbed3d"
|
||||
path = "../crates/rapier_testbed3d"
|
||||
|
||||
[dependencies.rapier3d]
|
||||
path = "../build/rapier3d"
|
||||
path = "../crates/rapier3d"
|
||||
|
||||
[[bin]]
|
||||
name = "all_benchmarks3"
|
||||
|
||||
@@ -58,10 +58,10 @@ pub fn main() {
|
||||
("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),
|
||||
("ImpulseJoint ball", joint_ball3::init_world),
|
||||
("ImpulseJoint fixed", joint_fixed3::init_world),
|
||||
("ImpulseJoint revolute", joint_revolute3::init_world),
|
||||
("ImpulseJoint prismatic", joint_prismatic3::init_world),
|
||||
("Keva tower", keva3::init_world),
|
||||
];
|
||||
|
||||
|
||||
@@ -7,7 +7,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Create the balls
|
||||
@@ -48,6 +49,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![100.0, 100.0, 100.0], Point::origin());
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
@@ -58,6 +59,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![100.0, 100.0, 100.0], Point::origin());
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
@@ -59,6 +60,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![100.0, 100.0, 100.0], Point::origin());
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
@@ -73,6 +74,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![100.0, 100.0, 100.0], Point::origin());
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
@@ -66,6 +67,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![100.0, 100.0, 100.0], Point::origin());
|
||||
}
|
||||
|
||||
@@ -9,7 +9,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
@@ -73,6 +74,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![100.0, 100.0, 100.0], Point::origin());
|
||||
}
|
||||
|
||||
@@ -8,7 +8,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
@@ -73,6 +74,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![100.0, 100.0, 100.0], Point::origin());
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let mut joints = JointSet::new();
|
||||
let mut impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
let rad = 0.4;
|
||||
let num = 100;
|
||||
@@ -36,16 +37,16 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
// Vertical joint.
|
||||
if i > 0 {
|
||||
let parent_handle = *body_handles.last().unwrap();
|
||||
let joint = BallJoint::new(Point::origin(), point![0.0, 0.0, -shift]);
|
||||
joints.insert(parent_handle, child_handle, joint);
|
||||
let joint = SphericalJoint::new().local_anchor2(point![0.0, 0.0, -shift]);
|
||||
impulse_joints.insert(parent_handle, child_handle, joint);
|
||||
}
|
||||
|
||||
// Horizontal joint.
|
||||
if k > 0 {
|
||||
let parent_index = body_handles.len() - num;
|
||||
let parent_handle = body_handles[parent_index];
|
||||
let joint = BallJoint::new(Point::origin(), point![-shift, 0.0, 0.0]);
|
||||
joints.insert(parent_handle, child_handle, joint);
|
||||
let joint = SphericalJoint::new().local_anchor2(point![-shift, 0.0, 0.0]);
|
||||
impulse_joints.insert(parent_handle, child_handle, joint);
|
||||
}
|
||||
|
||||
body_handles.push(child_handle);
|
||||
@@ -55,6 +56,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![-110.0, -46.0, 170.0], point![54.0, -38.0, 29.0]);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let mut joints = JointSet::new();
|
||||
let mut impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
let rad = 0.4;
|
||||
let num = 5;
|
||||
@@ -49,22 +50,16 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
// Vertical joint.
|
||||
if i > 0 {
|
||||
let parent_handle = *body_handles.last().unwrap();
|
||||
let joint = FixedJoint::new(
|
||||
Isometry::identity(),
|
||||
Isometry::translation(0.0, 0.0, -shift),
|
||||
);
|
||||
joints.insert(parent_handle, child_handle, joint);
|
||||
let joint = FixedJoint::new().local_anchor2(point![0.0, 0.0, -shift]);
|
||||
impulse_joints.insert(parent_handle, child_handle, joint);
|
||||
}
|
||||
|
||||
// Horizontal joint.
|
||||
if k > 0 {
|
||||
let parent_index = body_handles.len() - num;
|
||||
let parent_handle = body_handles[parent_index];
|
||||
let joint = FixedJoint::new(
|
||||
Isometry::identity(),
|
||||
Isometry::translation(-shift, 0.0, 0.0),
|
||||
);
|
||||
joints.insert(parent_handle, child_handle, joint);
|
||||
let joint = FixedJoint::new().local_anchor2(point![-shift, 0.0, 0.0]);
|
||||
impulse_joints.insert(parent_handle, child_handle, joint);
|
||||
}
|
||||
|
||||
body_handles.push(child_handle);
|
||||
@@ -77,6 +72,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![-38.0, 14.0, 108.0], point![46.0, 12.0, 23.0]);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let mut joints = JointSet::new();
|
||||
let mut impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
let rad = 0.4;
|
||||
let num = 5;
|
||||
@@ -47,19 +48,10 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
UnitVector::new_normalize(vector![-1.0, 1.0, 0.0])
|
||||
};
|
||||
|
||||
let z = Vector::z();
|
||||
let mut prism = PrismaticJoint::new(
|
||||
Point::origin(),
|
||||
axis,
|
||||
z,
|
||||
point![0.0, 0.0, -shift],
|
||||
axis,
|
||||
z,
|
||||
);
|
||||
prism.limits_enabled = true;
|
||||
prism.limits[0] = -2.0;
|
||||
prism.limits[1] = 2.0;
|
||||
joints.insert(curr_parent, curr_child, prism);
|
||||
let prism = PrismaticJoint::new(axis)
|
||||
.local_anchor2(point![0.0, 0.0, -shift])
|
||||
.limit_axis([-2.0, 0.0]);
|
||||
impulse_joints.insert(curr_parent, curr_child, prism);
|
||||
|
||||
curr_parent = curr_child;
|
||||
}
|
||||
@@ -70,6 +62,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![262.0, 63.0, 124.0], point![101.0, 4.0, -3.0]);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let mut joints = JointSet::new();
|
||||
let mut impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
let rad = 0.4;
|
||||
let num = 10;
|
||||
@@ -49,22 +50,21 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
colliders.insert_with_parent(collider, handles[k], &mut bodies);
|
||||
}
|
||||
|
||||
// Setup four joints.
|
||||
let o = Point::origin();
|
||||
// Setup four impulse_joints.
|
||||
let x = Vector::x_axis();
|
||||
let z = Vector::z_axis();
|
||||
|
||||
let revs = [
|
||||
RevoluteJoint::new(o, z, point![0.0, 0.0, -shift], z),
|
||||
RevoluteJoint::new(o, x, point![-shift, 0.0, 0.0], x),
|
||||
RevoluteJoint::new(o, z, point![0.0, 0.0, -shift], z),
|
||||
RevoluteJoint::new(o, x, point![shift, 0.0, 0.0], x),
|
||||
RevoluteJoint::new(z).local_anchor2(point![0.0, 0.0, -shift]),
|
||||
RevoluteJoint::new(x).local_anchor2(point![-shift, 0.0, 0.0]),
|
||||
RevoluteJoint::new(z).local_anchor2(point![0.0, 0.0, -shift]),
|
||||
RevoluteJoint::new(x).local_anchor2(point![shift, 0.0, 0.0]),
|
||||
];
|
||||
|
||||
joints.insert(curr_parent, handles[0], revs[0]);
|
||||
joints.insert(handles[0], handles[1], revs[1]);
|
||||
joints.insert(handles[1], handles[2], revs[2]);
|
||||
joints.insert(handles[2], handles[3], revs[3]);
|
||||
impulse_joints.insert(curr_parent, handles[0], revs[0]);
|
||||
impulse_joints.insert(handles[0], handles[1], revs[1]);
|
||||
impulse_joints.insert(handles[1], handles[2], revs[2]);
|
||||
impulse_joints.insert(handles[2], handles[3], revs[3]);
|
||||
|
||||
curr_parent = handles[3];
|
||||
}
|
||||
@@ -74,6 +74,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![478.0, 83.0, 228.0], point![134.0, 83.0, -116.0]);
|
||||
}
|
||||
|
||||
@@ -83,7 +83,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
@@ -132,6 +133,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![100.0, 100.0, 100.0], Point::origin());
|
||||
}
|
||||
|
||||
@@ -41,7 +41,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
@@ -73,6 +74,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![100.0, 100.0, 100.0], Point::origin());
|
||||
}
|
||||
|
||||
@@ -101,7 +101,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
@@ -183,6 +184,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![100.0, 100.0, 100.0], Point::origin());
|
||||
}
|
||||
|
||||
@@ -8,7 +8,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
@@ -78,6 +79,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![100.0, 100.0, 100.0], Point::origin());
|
||||
}
|
||||
|
||||
@@ -8,9 +8,9 @@ homepage = "http://rapier.rs"
|
||||
repository = "https://github.com/dimforge/rapier"
|
||||
readme = "README.md"
|
||||
categories = [ "science", "game-development", "mathematics", "simulation", "wasm"]
|
||||
keywords = [ "physics", "dynamics", "rigid", "real-time", "joints" ]
|
||||
keywords = [ "physics", "dynamics", "rigid", "real-time", "impulse_joints" ]
|
||||
license = "Apache-2.0"
|
||||
edition = "2018"
|
||||
edition = "2021"
|
||||
|
||||
[badges]
|
||||
maintenance = { status = "actively-developed" }
|
||||
@@ -47,9 +47,9 @@ required-features = [ "dim2", "f64" ]
|
||||
vec_map = { version = "0.8", optional = true }
|
||||
instant = { version = "0.1", features = [ "now" ]}
|
||||
num-traits = "0.2"
|
||||
nalgebra = "0.29"
|
||||
parry2d-f64 = "^0.7.1"
|
||||
simba = "0.6"
|
||||
nalgebra = "0.30"
|
||||
parry2d-f64 = "0.8"
|
||||
simba = "0.7"
|
||||
approx = "0.5"
|
||||
rayon = { version = "1", optional = true }
|
||||
crossbeam = "0.8"
|
||||
@@ -8,9 +8,9 @@ homepage = "http://rapier.rs"
|
||||
repository = "https://github.com/dimforge/rapier"
|
||||
readme = "README.md"
|
||||
categories = [ "science", "game-development", "mathematics", "simulation", "wasm"]
|
||||
keywords = [ "physics", "dynamics", "rigid", "real-time", "joints" ]
|
||||
keywords = [ "physics", "dynamics", "rigid", "real-time", "impulse_joints" ]
|
||||
license = "Apache-2.0"
|
||||
edition = "2018"
|
||||
edition = "2021"
|
||||
|
||||
[badges]
|
||||
maintenance = { status = "actively-developed" }
|
||||
@@ -47,9 +47,9 @@ required-features = [ "dim2", "f32" ]
|
||||
vec_map = { version = "0.8", optional = true }
|
||||
instant = { version = "0.1", features = [ "now" ]}
|
||||
num-traits = "0.2"
|
||||
nalgebra = "0.29"
|
||||
parry2d = "^0.7.1"
|
||||
simba = "0.6"
|
||||
nalgebra = "0.30"
|
||||
parry2d = "0.8"
|
||||
simba = "0.7"
|
||||
approx = "0.5"
|
||||
rayon = { version = "1", optional = true }
|
||||
crossbeam = "0.8"
|
||||
@@ -8,9 +8,9 @@ homepage = "http://rapier.rs"
|
||||
repository = "https://github.com/dimforge/rapier"
|
||||
readme = "README.md"
|
||||
categories = [ "science", "game-development", "mathematics", "simulation", "wasm"]
|
||||
keywords = [ "physics", "dynamics", "rigid", "real-time", "joints" ]
|
||||
keywords = [ "physics", "dynamics", "rigid", "real-time", "impulse_joints" ]
|
||||
license = "Apache-2.0"
|
||||
edition = "2018"
|
||||
edition = "2021"
|
||||
|
||||
[badges]
|
||||
maintenance = { status = "actively-developed" }
|
||||
@@ -47,9 +47,9 @@ required-features = [ "dim3", "f64" ]
|
||||
vec_map = { version = "0.8", optional = true }
|
||||
instant = { version = "0.1", features = [ "now" ]}
|
||||
num-traits = "0.2"
|
||||
nalgebra = "0.29"
|
||||
parry3d-f64 = "^0.7.1"
|
||||
simba = "0.6"
|
||||
nalgebra = "0.30"
|
||||
parry3d-f64 = "0.8"
|
||||
simba = "0.7"
|
||||
approx = "0.5"
|
||||
rayon = { version = "1", optional = true }
|
||||
crossbeam = "0.8"
|
||||
@@ -8,9 +8,9 @@ homepage = "http://rapier.rs"
|
||||
repository = "https://github.com/dimforge/rapier"
|
||||
readme = "README.md"
|
||||
categories = [ "science", "game-development", "mathematics", "simulation", "wasm"]
|
||||
keywords = [ "physics", "dynamics", "rigid", "real-time", "joints" ]
|
||||
keywords = [ "physics", "dynamics", "rigid", "real-time", "impulse_joints" ]
|
||||
license = "Apache-2.0"
|
||||
edition = "2018"
|
||||
edition = "2021"
|
||||
|
||||
[badges]
|
||||
maintenance = { status = "actively-developed" }
|
||||
@@ -47,9 +47,9 @@ required-features = [ "dim3", "f32" ]
|
||||
vec_map = { version = "0.8", optional = true }
|
||||
instant = { version = "0.1", features = [ "now" ]}
|
||||
num-traits = "0.2"
|
||||
nalgebra = "0.29"
|
||||
parry3d = "^0.7.1"
|
||||
simba = "0.6"
|
||||
nalgebra = "0.30"
|
||||
parry3d = "0.8"
|
||||
simba = "0.7"
|
||||
approx = "0.5"
|
||||
rayon = { version = "1", optional = true }
|
||||
crossbeam = "0.8"
|
||||
@@ -6,9 +6,9 @@ description = "Testbed for the Rapier 2-dimensional physics engine in Rust."
|
||||
homepage = "http://rapier.org"
|
||||
repository = "https://github.com/dimforge/rapier"
|
||||
categories = [ "science", "game-development", "mathematics", "simulation", "wasm"]
|
||||
keywords = [ "physics", "dynamics", "rigid", "real-time", "joints" ]
|
||||
keywords = [ "physics", "dynamics", "rigid", "real-time", "impulse_joints" ]
|
||||
license = "Apache-2.0"
|
||||
edition = "2018"
|
||||
edition = "2021"
|
||||
|
||||
[badges]
|
||||
maintenance = { status = "actively-developed" }
|
||||
@@ -22,20 +22,18 @@ required-features = [ "dim2" ]
|
||||
default = [ "dim2" ]
|
||||
dim2 = [ ]
|
||||
parallel = [ "rapier2d/parallel", "num_cpus" ]
|
||||
other-backends = [ "wrapped2d", "nphysics2d", "ncollide2d" ]
|
||||
other-backends = [ "wrapped2d" ]
|
||||
|
||||
|
||||
[dependencies]
|
||||
nalgebra = { version = "0.29", features = [ "rand" ] }
|
||||
nalgebra = { version = "0.30", features = [ "rand" ] }
|
||||
rand = "0.8"
|
||||
rand_pcg = "0.3"
|
||||
instant = { version = "0.1", features = [ "web-sys", "now" ]}
|
||||
bitflags = "1"
|
||||
num_cpus = { version = "1", optional = true }
|
||||
wrapped2d = { version = "0.4", optional = true }
|
||||
parry2d = "0.7"
|
||||
ncollide2d = { version = "0.32", optional = true }
|
||||
nphysics2d = { version = "0.24", optional = true }
|
||||
parry2d = "0.8"
|
||||
crossbeam = "0.8"
|
||||
bincode = "1"
|
||||
Inflector = "0.11"
|
||||
@@ -6,9 +6,9 @@ description = "Testbed for the Rapier 3-dimensional physics engine in Rust."
|
||||
homepage = "http://rapier.org"
|
||||
repository = "https://github.com/dimforge/rapier"
|
||||
categories = [ "science", "game-development", "mathematics", "simulation", "wasm"]
|
||||
keywords = [ "physics", "dynamics", "rigid", "real-time", "joints" ]
|
||||
keywords = [ "physics", "dynamics", "rigid", "real-time", "impulse_joints" ]
|
||||
license = "Apache-2.0"
|
||||
edition = "2018"
|
||||
edition = "2021"
|
||||
|
||||
[badges]
|
||||
maintenance = { status = "actively-developed" }
|
||||
@@ -22,19 +22,17 @@ required-features = [ "dim3" ]
|
||||
default = [ "dim3" ]
|
||||
dim3 = [ ]
|
||||
parallel = [ "rapier3d/parallel", "num_cpus" ]
|
||||
other-backends = [ "physx", "physx-sys", "glam", "nphysics3d", "ncollide3d" ]
|
||||
other-backends = [ "physx", "physx-sys", "glam" ]
|
||||
|
||||
[dependencies]
|
||||
nalgebra = { version = "0.29", features = [ "rand" ] }
|
||||
nalgebra = { version = "0.30", features = [ "rand" ] }
|
||||
rand = "0.8"
|
||||
rand_pcg = "0.3"
|
||||
instant = { version = "0.1", features = [ "web-sys", "now" ]}
|
||||
bitflags = "1"
|
||||
glam = { version = "0.12", optional = true }
|
||||
num_cpus = { version = "1", optional = true }
|
||||
parry3d = "0.7"
|
||||
ncollide3d = { version = "0.32", optional = true }
|
||||
nphysics3d = { version = "0.24", optional = true }
|
||||
parry3d = "0.8"
|
||||
physx = { version = "0.11", optional = true }
|
||||
physx-sys = { version = "0.4", optional = true }
|
||||
crossbeam = "0.8"
|
||||
@@ -2,7 +2,7 @@
|
||||
name = "rapier-examples-2d"
|
||||
version = "0.1.0"
|
||||
authors = [ "Sébastien Crozet <developer@crozet.re>" ]
|
||||
edition = "2018"
|
||||
edition = "2021"
|
||||
default-run = "all_examples2"
|
||||
|
||||
[features]
|
||||
@@ -19,10 +19,10 @@ lyon = "0.17"
|
||||
usvg = "0.14"
|
||||
|
||||
[dependencies.rapier_testbed2d]
|
||||
path = "../build/rapier_testbed2d"
|
||||
path = "../crates/rapier_testbed2d"
|
||||
|
||||
[dependencies.rapier2d]
|
||||
path = "../build/rapier2d"
|
||||
path = "../crates/rapier2d"
|
||||
|
||||
[[bin]]
|
||||
name = "all_examples2"
|
||||
|
||||
@@ -4,12 +4,15 @@ use rapier_testbed2d::Testbed;
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
let rad = 0.5;
|
||||
|
||||
let positions = [vector![5.0, -1.0], vector![-5.0, -1.0]];
|
||||
|
||||
let platform_handles = std::array::IntoIter::new(positions)
|
||||
let platform_handles = positions
|
||||
.into_iter()
|
||||
.map(|pos| {
|
||||
let rigid_body = RigidBodyBuilder::new_kinematic_position_based()
|
||||
.translation(pos)
|
||||
@@ -57,7 +60,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
handle,
|
||||
&mut physics.islands,
|
||||
&mut physics.colliders,
|
||||
&mut physics.joints,
|
||||
&mut physics.impulse_joints,
|
||||
&mut physics.multibody_joints,
|
||||
);
|
||||
|
||||
if let Some(graphics) = &mut graphics {
|
||||
@@ -69,6 +73,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![0.0, 0.0], 20.0);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
@@ -123,6 +124,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![0.0, 2.5], 20.0);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
@@ -89,6 +90,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![0.0, 1.0], 100.0);
|
||||
}
|
||||
|
||||
@@ -9,7 +9,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
@@ -76,6 +77,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![0.0, 50.0], 10.0);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Create the balls
|
||||
@@ -38,6 +39,13 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world_with_params(bodies, colliders, joints, Vector::zeros(), ());
|
||||
testbed.set_world_with_params(
|
||||
bodies,
|
||||
colliders,
|
||||
impulse_joints,
|
||||
multibody_joints,
|
||||
Vector::zeros(),
|
||||
(),
|
||||
);
|
||||
testbed.look_at(point![3.0, 2.0], 50.0);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
@@ -33,6 +34,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![0.0, 0.0], 50.0);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
@@ -63,6 +64,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![0.0, 0.0], 10.0);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let mut joints = JointSet::new();
|
||||
let mut impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Create the balls
|
||||
@@ -44,16 +45,16 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
// Vertical joint.
|
||||
if i > 0 {
|
||||
let parent_handle = *body_handles.last().unwrap();
|
||||
let joint = BallJoint::new(Point::origin(), point![0.0, shift]);
|
||||
joints.insert(parent_handle, child_handle, joint);
|
||||
let joint = RevoluteJoint::new().local_anchor2(point![0.0, shift]);
|
||||
impulse_joints.insert(parent_handle, child_handle, joint);
|
||||
}
|
||||
|
||||
// Horizontal joint.
|
||||
if k > 0 {
|
||||
let parent_index = body_handles.len() - numi;
|
||||
let parent_handle = body_handles[parent_index];
|
||||
let joint = BallJoint::new(Point::origin(), point![-shift, 0.0]);
|
||||
joints.insert(parent_handle, child_handle, joint);
|
||||
let joint = RevoluteJoint::new().local_anchor2(point![-shift, 0.0]);
|
||||
impulse_joints.insert(parent_handle, child_handle, joint);
|
||||
}
|
||||
|
||||
body_handles.push(child_handle);
|
||||
@@ -63,6 +64,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![numk as f32 * rad, numi as f32 * -rad], 20.0);
|
||||
}
|
||||
|
||||
@@ -10,7 +10,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* The ground
|
||||
@@ -51,6 +52,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![0.0, 0.0], 40.0);
|
||||
}
|
||||
|
||||
@@ -62,7 +62,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
@@ -126,7 +127,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
testbed.set_world_with_params(
|
||||
bodies,
|
||||
colliders,
|
||||
joints,
|
||||
impulse_joints,
|
||||
multibody_joints,
|
||||
vector![0.0, -9.81],
|
||||
physics_hooks,
|
||||
);
|
||||
|
||||
@@ -7,7 +7,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground.
|
||||
@@ -89,6 +90,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Run the simulation.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![0.0, 1.0], 40.0);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
@@ -65,6 +66,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![0.0, 0.0], 10.0);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
@@ -50,6 +51,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![0.0, 2.5], 20.0);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
@@ -44,6 +45,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![0.0, 1.0], 25.0);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground.
|
||||
@@ -98,6 +99,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![0.0, 1.0], 100.0);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
@@ -103,7 +104,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![0.0, 20.0], 17.0);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
name = "rapier-examples-3d"
|
||||
version = "0.1.0"
|
||||
authors = [ "Sébastien Crozet <developer@crozet.re>" ]
|
||||
edition = "2018"
|
||||
edition = "2021"
|
||||
default-run = "all_examples3"
|
||||
|
||||
[features]
|
||||
@@ -20,10 +20,10 @@ wasm-bindgen = "0.2"
|
||||
obj-rs = { version = "0.6", default-features = false }
|
||||
|
||||
[dependencies.rapier_testbed3d]
|
||||
path = "../build/rapier_testbed3d"
|
||||
path = "../crates/rapier_testbed3d"
|
||||
|
||||
[dependencies.rapier3d]
|
||||
path = "../build/rapier3d"
|
||||
path = "../crates/rapier3d"
|
||||
|
||||
[[bin]]
|
||||
name = "all_examples3"
|
||||
|
||||
@@ -8,6 +8,7 @@ use inflector::Inflector;
|
||||
use rapier_testbed3d::{Testbed, TestbedApp};
|
||||
use std::cmp::Ordering;
|
||||
|
||||
mod articulations3;
|
||||
mod ccd3;
|
||||
mod collision_groups3;
|
||||
mod compound3;
|
||||
@@ -15,6 +16,7 @@ mod convex_decomposition3;
|
||||
mod convex_polyhedron3;
|
||||
mod damping3;
|
||||
mod debug_add_remove_collider3;
|
||||
mod debug_articulations3;
|
||||
mod debug_big_colliders3;
|
||||
mod debug_boxes3;
|
||||
mod debug_cylinder3;
|
||||
@@ -29,7 +31,7 @@ mod debug_trimesh3;
|
||||
mod domino3;
|
||||
mod fountain3;
|
||||
mod heightfield3;
|
||||
mod joints3;
|
||||
// mod joints3;
|
||||
mod keva3;
|
||||
mod locked_rotations3;
|
||||
mod one_way_platforms3;
|
||||
@@ -78,6 +80,10 @@ pub fn main() {
|
||||
let mut builders: Vec<(_, fn(&mut Testbed))> = vec![
|
||||
("Fountain", fountain3::init_world),
|
||||
("Primitives", primitives3::init_world),
|
||||
(
|
||||
"Multibody joints",
|
||||
articulations3::init_world_with_articulations,
|
||||
),
|
||||
("CCD", ccd3::init_world),
|
||||
("Collision groups", collision_groups3::init_world),
|
||||
("Compound", compound3::init_world),
|
||||
@@ -86,7 +92,7 @@ pub fn main() {
|
||||
("Damping", damping3::init_world),
|
||||
("Domino", domino3::init_world),
|
||||
("Heightfield", heightfield3::init_world),
|
||||
("Joints", joints3::init_world),
|
||||
("Impulse Joints", articulations3::init_world_with_joints),
|
||||
("Locked rotations", locked_rotations3::init_world),
|
||||
("One-way platforms", one_way_platforms3::init_world),
|
||||
("Platform", platform3::init_world),
|
||||
@@ -94,6 +100,7 @@ pub fn main() {
|
||||
("Sensor", sensor3::init_world),
|
||||
("TriMesh", trimesh3::init_world),
|
||||
("Keva tower", keva3::init_world),
|
||||
("(Debug) multibody_joints", debug_articulations3::init_world),
|
||||
(
|
||||
"(Debug) add/rm collider",
|
||||
debug_add_remove_collider3::init_world,
|
||||
|
||||
678
examples3d/articulations3.rs
Normal file
678
examples3d/articulations3.rs
Normal file
@@ -0,0 +1,678 @@
|
||||
use rapier3d::prelude::*;
|
||||
use rapier_testbed3d::Testbed;
|
||||
|
||||
fn create_prismatic_joints(
|
||||
bodies: &mut RigidBodySet,
|
||||
colliders: &mut ColliderSet,
|
||||
impulse_joints: &mut ImpulseJointSet,
|
||||
multibody_joints: &mut MultibodyJointSet,
|
||||
origin: Point<f32>,
|
||||
num: usize,
|
||||
use_articulations: bool,
|
||||
) {
|
||||
let rad = 0.4;
|
||||
let shift = 2.0;
|
||||
|
||||
let ground = RigidBodyBuilder::new_static()
|
||||
.translation(vector![origin.x, origin.y, origin.z])
|
||||
.build();
|
||||
let mut curr_parent = bodies.insert(ground);
|
||||
let collider = ColliderBuilder::cuboid(rad, rad, rad).build();
|
||||
colliders.insert_with_parent(collider, curr_parent, bodies);
|
||||
|
||||
for i in 0..num {
|
||||
let z = origin.z + (i + 1) as f32 * shift;
|
||||
let rigid_body = RigidBodyBuilder::new_dynamic()
|
||||
.translation(vector![origin.x, origin.y, z])
|
||||
.build();
|
||||
let curr_child = bodies.insert(rigid_body);
|
||||
let collider = ColliderBuilder::cuboid(rad, rad, rad).build();
|
||||
colliders.insert_with_parent(collider, curr_child, bodies);
|
||||
|
||||
let axis = if i % 2 == 0 {
|
||||
UnitVector::new_normalize(vector![1.0f32, 1.0, 0.0])
|
||||
} else {
|
||||
UnitVector::new_normalize(vector![-1.0f32, 1.0, 0.0])
|
||||
};
|
||||
|
||||
let prism = PrismaticJoint::new(axis)
|
||||
.local_anchor1(point![0.0, 0.0, 0.0])
|
||||
.local_anchor2(point![0.0, 0.0, -shift])
|
||||
.limit_axis([-2.0, 2.0]);
|
||||
|
||||
if use_articulations {
|
||||
multibody_joints.insert(curr_parent, curr_child, prism);
|
||||
} else {
|
||||
impulse_joints.insert(curr_parent, curr_child, prism);
|
||||
}
|
||||
curr_parent = curr_child;
|
||||
}
|
||||
}
|
||||
|
||||
fn create_actuated_prismatic_joints(
|
||||
bodies: &mut RigidBodySet,
|
||||
colliders: &mut ColliderSet,
|
||||
impulse_joints: &mut ImpulseJointSet,
|
||||
multibody_joints: &mut MultibodyJointSet,
|
||||
origin: Point<f32>,
|
||||
num: usize,
|
||||
use_articulations: bool,
|
||||
) {
|
||||
let rad = 0.4;
|
||||
let shift = 2.0;
|
||||
|
||||
let ground = RigidBodyBuilder::new_static()
|
||||
.translation(vector![origin.x, origin.y, origin.z])
|
||||
.build();
|
||||
let mut curr_parent = bodies.insert(ground);
|
||||
let collider = ColliderBuilder::cuboid(rad, rad, rad).build();
|
||||
colliders.insert_with_parent(collider, curr_parent, bodies);
|
||||
|
||||
for i in 0..num {
|
||||
let z = origin.z + (i + 1) as f32 * shift;
|
||||
let rigid_body = RigidBodyBuilder::new_dynamic()
|
||||
.translation(vector![origin.x, origin.y, z])
|
||||
.build();
|
||||
let curr_child = bodies.insert(rigid_body);
|
||||
let collider = ColliderBuilder::cuboid(rad, rad, rad).build();
|
||||
colliders.insert_with_parent(collider, curr_child, bodies);
|
||||
|
||||
let axis = if i % 2 == 0 {
|
||||
UnitVector::new_normalize(vector![1.0, 1.0, 0.0])
|
||||
} else {
|
||||
UnitVector::new_normalize(vector![-1.0, 1.0, 0.0])
|
||||
};
|
||||
|
||||
let mut prism = PrismaticJoint::new(axis)
|
||||
.local_anchor1(point![0.0, 0.0, 0.0])
|
||||
.local_anchor2(point![0.0, 0.0, -shift]);
|
||||
|
||||
if i == 1 {
|
||||
prism = prism
|
||||
.limit_axis([-Real::MAX, 5.0])
|
||||
.motor_velocity(1.0, 1.0)
|
||||
// We set a max impulse so that the motor doesn't fight
|
||||
// the limits with large forces.
|
||||
.motor_max_impulse(1.0);
|
||||
} else if i > 1 {
|
||||
prism = prism.motor_position(2.0, 0.01, 1.0);
|
||||
} else {
|
||||
prism = prism
|
||||
.motor_velocity(1.0, 1.0)
|
||||
// We set a max impulse so that the motor doesn't fight
|
||||
// the limits with large forces.
|
||||
.motor_max_impulse(0.7)
|
||||
.limit_axis([-2.0, 5.0]);
|
||||
}
|
||||
|
||||
if use_articulations {
|
||||
multibody_joints.insert(curr_parent, curr_child, prism);
|
||||
} else {
|
||||
impulse_joints.insert(curr_parent, curr_child, prism);
|
||||
}
|
||||
|
||||
curr_parent = curr_child;
|
||||
}
|
||||
}
|
||||
|
||||
fn create_revolute_joints(
|
||||
bodies: &mut RigidBodySet,
|
||||
colliders: &mut ColliderSet,
|
||||
impulse_joints: &mut ImpulseJointSet,
|
||||
multibody_joints: &mut MultibodyJointSet,
|
||||
origin: Point<f32>,
|
||||
num: usize,
|
||||
use_articulations: bool,
|
||||
) {
|
||||
let rad = 0.4;
|
||||
let shift = 2.0;
|
||||
|
||||
let ground = RigidBodyBuilder::new_static()
|
||||
.translation(vector![origin.x, origin.y, 0.0])
|
||||
.build();
|
||||
let mut curr_parent = bodies.insert(ground);
|
||||
let collider = ColliderBuilder::cuboid(rad, rad, rad).build();
|
||||
colliders.insert_with_parent(collider, curr_parent, bodies);
|
||||
|
||||
for i in 0..num {
|
||||
// Create four bodies.
|
||||
let z = origin.z + i as f32 * shift * 2.0 + shift;
|
||||
let positions = [
|
||||
Isometry::translation(origin.x, origin.y, z),
|
||||
Isometry::translation(origin.x + shift, origin.y, z),
|
||||
Isometry::translation(origin.x + shift, origin.y, z + shift),
|
||||
Isometry::translation(origin.x, origin.y, z + shift),
|
||||
];
|
||||
|
||||
let mut handles = [curr_parent; 4];
|
||||
for k in 0..4 {
|
||||
let rigid_body = RigidBodyBuilder::new_dynamic()
|
||||
.position(positions[k])
|
||||
.build();
|
||||
handles[k] = bodies.insert(rigid_body);
|
||||
let collider = ColliderBuilder::cuboid(rad, rad, rad).build();
|
||||
colliders.insert_with_parent(collider, handles[k], bodies);
|
||||
}
|
||||
|
||||
// Setup four impulse_joints.
|
||||
let x = Vector::x_axis();
|
||||
let z = Vector::z_axis();
|
||||
let revs = [
|
||||
RevoluteJoint::new(z).local_anchor2(point![0.0, 0.0, -shift]),
|
||||
RevoluteJoint::new(x).local_anchor2(point![-shift, 0.0, 0.0]),
|
||||
RevoluteJoint::new(z).local_anchor2(point![0.0, 0.0, -shift]),
|
||||
RevoluteJoint::new(x).local_anchor2(point![shift, 0.0, 0.0]),
|
||||
];
|
||||
|
||||
if use_articulations {
|
||||
multibody_joints.insert(curr_parent, handles[0], revs[0]);
|
||||
multibody_joints.insert(handles[0], handles[1], revs[1]);
|
||||
multibody_joints.insert(handles[1], handles[2], revs[2]);
|
||||
multibody_joints.insert(handles[2], handles[3], revs[3]);
|
||||
} else {
|
||||
impulse_joints.insert(curr_parent, handles[0], revs[0]);
|
||||
impulse_joints.insert(handles[0], handles[1], revs[1]);
|
||||
impulse_joints.insert(handles[1], handles[2], revs[2]);
|
||||
impulse_joints.insert(handles[2], handles[3], revs[3]);
|
||||
}
|
||||
|
||||
curr_parent = handles[3];
|
||||
}
|
||||
}
|
||||
|
||||
fn create_revolute_joints_with_limits(
|
||||
bodies: &mut RigidBodySet,
|
||||
colliders: &mut ColliderSet,
|
||||
impulse_joints: &mut ImpulseJointSet,
|
||||
multibody_joints: &mut MultibodyJointSet,
|
||||
origin: Point<f32>,
|
||||
use_articulations: bool,
|
||||
) {
|
||||
let ground = bodies.insert(
|
||||
RigidBodyBuilder::new_static()
|
||||
.translation(origin.coords)
|
||||
.build(),
|
||||
);
|
||||
|
||||
let platform1 = bodies.insert(
|
||||
RigidBodyBuilder::new_dynamic()
|
||||
.translation(origin.coords)
|
||||
.build(),
|
||||
);
|
||||
colliders.insert_with_parent(
|
||||
ColliderBuilder::cuboid(4.0, 0.2, 2.0).build(),
|
||||
platform1,
|
||||
bodies,
|
||||
);
|
||||
|
||||
let shift = vector![0.0, 0.0, 6.0];
|
||||
let platform2 = bodies.insert(
|
||||
RigidBodyBuilder::new_dynamic()
|
||||
.translation(origin.coords + shift)
|
||||
.build(),
|
||||
);
|
||||
colliders.insert_with_parent(
|
||||
ColliderBuilder::cuboid(4.0, 0.2, 2.0).build(),
|
||||
platform2,
|
||||
bodies,
|
||||
);
|
||||
|
||||
let z = Vector::z_axis();
|
||||
let joint1 = RevoluteJoint::new(z).limit_axis([-0.2, 0.2]);
|
||||
|
||||
if use_articulations {
|
||||
multibody_joints.insert(ground, platform1, joint1);
|
||||
} else {
|
||||
impulse_joints.insert(ground, platform1, joint1);
|
||||
}
|
||||
|
||||
let joint2 = RevoluteJoint::new(z)
|
||||
.local_anchor2(-Point::from(shift))
|
||||
.limit_axis([-0.2, 0.2]);
|
||||
|
||||
if use_articulations {
|
||||
multibody_joints.insert(platform1, platform2, joint2);
|
||||
} else {
|
||||
impulse_joints.insert(platform1, platform2, joint2);
|
||||
}
|
||||
|
||||
// Let’s add a couple of cuboids that will fall on the platforms, triggering the joint limits.
|
||||
let cuboid_body1 = bodies.insert(
|
||||
RigidBodyBuilder::new_dynamic()
|
||||
.translation(origin.coords + vector![-2.0, 4.0, 0.0])
|
||||
.build(),
|
||||
);
|
||||
colliders.insert_with_parent(
|
||||
ColliderBuilder::cuboid(0.6, 0.6, 0.6).friction(1.0).build(),
|
||||
cuboid_body1,
|
||||
bodies,
|
||||
);
|
||||
|
||||
let cuboid_body2 = bodies.insert(
|
||||
RigidBodyBuilder::new_dynamic()
|
||||
.translation(origin.coords + shift + vector![2.0, 16.0, 0.0])
|
||||
.build(),
|
||||
);
|
||||
colliders.insert_with_parent(
|
||||
ColliderBuilder::cuboid(0.6, 0.6, 0.6).friction(1.0).build(),
|
||||
cuboid_body2,
|
||||
bodies,
|
||||
);
|
||||
}
|
||||
|
||||
fn create_fixed_joints(
|
||||
bodies: &mut RigidBodySet,
|
||||
colliders: &mut ColliderSet,
|
||||
impulse_joints: &mut ImpulseJointSet,
|
||||
multibody_joints: &mut MultibodyJointSet,
|
||||
origin: Point<f32>,
|
||||
num: usize,
|
||||
use_articulations: bool,
|
||||
) {
|
||||
let rad = 0.4;
|
||||
let shift = 1.0;
|
||||
|
||||
let mut body_handles = Vec::new();
|
||||
|
||||
for i in 0..num {
|
||||
for k 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::Static
|
||||
} else {
|
||||
RigidBodyType::Dynamic
|
||||
};
|
||||
|
||||
let rigid_body = RigidBodyBuilder::new(status)
|
||||
.translation(vector![
|
||||
origin.x + fk * shift,
|
||||
origin.y,
|
||||
origin.z + fi * shift
|
||||
])
|
||||
.build();
|
||||
let child_handle = bodies.insert(rigid_body);
|
||||
let collider = ColliderBuilder::ball(rad).build();
|
||||
colliders.insert_with_parent(collider, child_handle, bodies);
|
||||
|
||||
// Vertical joint.
|
||||
if i > 0 {
|
||||
let parent_index = body_handles.len() - num;
|
||||
let parent_handle = body_handles[parent_index];
|
||||
let joint = FixedJoint::new().local_anchor2(point![0.0, 0.0, -shift]);
|
||||
|
||||
if use_articulations {
|
||||
multibody_joints.insert(parent_handle, child_handle, joint);
|
||||
} else {
|
||||
impulse_joints.insert(parent_handle, child_handle, joint);
|
||||
}
|
||||
}
|
||||
|
||||
// Horizontal joint.
|
||||
if k > 0 {
|
||||
let parent_index = body_handles.len() - 1;
|
||||
let parent_handle = body_handles[parent_index];
|
||||
let joint = FixedJoint::new().local_anchor2(point![-shift, 0.0, 0.0]);
|
||||
impulse_joints.insert(parent_handle, child_handle, joint);
|
||||
}
|
||||
|
||||
body_handles.push(child_handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn create_spherical_joints(
|
||||
bodies: &mut RigidBodySet,
|
||||
colliders: &mut ColliderSet,
|
||||
impulse_joints: &mut ImpulseJointSet,
|
||||
multibody_joints: &mut MultibodyJointSet,
|
||||
num: usize,
|
||||
use_articulations: bool,
|
||||
) {
|
||||
let rad = 0.4;
|
||||
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::Static
|
||||
} else {
|
||||
RigidBodyType::Dynamic
|
||||
};
|
||||
|
||||
let rigid_body = RigidBodyBuilder::new(status)
|
||||
.translation(vector![fk * shift, 0.0, fi * shift * 2.0])
|
||||
.build();
|
||||
let child_handle = bodies.insert(rigid_body);
|
||||
let collider = ColliderBuilder::capsule_z(rad * 1.25, rad).build();
|
||||
colliders.insert_with_parent(collider, child_handle, bodies);
|
||||
|
||||
// Vertical joint.
|
||||
if i > 0 {
|
||||
let parent_handle = *body_handles.last().unwrap();
|
||||
let joint = SphericalJoint::new().local_anchor2(point![0.0, 0.0, -shift * 2.0]);
|
||||
|
||||
if use_articulations {
|
||||
multibody_joints.insert(parent_handle, child_handle, joint);
|
||||
} else {
|
||||
impulse_joints.insert(parent_handle, child_handle, joint);
|
||||
}
|
||||
}
|
||||
|
||||
// Horizontal joint.
|
||||
if k > 0 {
|
||||
let parent_index = body_handles.len() - num;
|
||||
let parent_handle = body_handles[parent_index];
|
||||
let joint = SphericalJoint::new().local_anchor2(point![-shift, 0.0, 0.0]);
|
||||
impulse_joints.insert(parent_handle, child_handle, joint);
|
||||
}
|
||||
|
||||
body_handles.push(child_handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn create_spherical_joints_with_limits(
|
||||
bodies: &mut RigidBodySet,
|
||||
colliders: &mut ColliderSet,
|
||||
impulse_joints: &mut ImpulseJointSet,
|
||||
multibody_joints: &mut MultibodyJointSet,
|
||||
origin: Point<f32>,
|
||||
use_articulations: bool,
|
||||
) {
|
||||
let shift = vector![0.0, 0.0, 3.0];
|
||||
|
||||
let ground = bodies.insert(
|
||||
RigidBodyBuilder::new_static()
|
||||
.translation(origin.coords)
|
||||
.build(),
|
||||
);
|
||||
|
||||
let ball1 = bodies.insert(
|
||||
RigidBodyBuilder::new_dynamic()
|
||||
.translation(origin.coords + shift)
|
||||
.linvel(vector![20.0, 20.0, 0.0])
|
||||
.build(),
|
||||
);
|
||||
colliders.insert_with_parent(
|
||||
ColliderBuilder::cuboid(1.0, 1.0, 1.0).build(),
|
||||
ball1,
|
||||
bodies,
|
||||
);
|
||||
|
||||
let ball2 = bodies.insert(
|
||||
RigidBodyBuilder::new_dynamic()
|
||||
.translation(origin.coords + shift * 2.0)
|
||||
.build(),
|
||||
);
|
||||
colliders.insert_with_parent(
|
||||
ColliderBuilder::cuboid(1.0, 1.0, 1.0).build(),
|
||||
ball2,
|
||||
bodies,
|
||||
);
|
||||
|
||||
let joint1 = SphericalJoint::new()
|
||||
.local_anchor2(Point::from(-shift))
|
||||
.limit_axis(JointAxis::X, [-0.2, 0.2])
|
||||
.limit_axis(JointAxis::Y, [-0.2, 0.2]);
|
||||
|
||||
let joint2 = SphericalJoint::new()
|
||||
.local_anchor2(Point::from(-shift))
|
||||
.limit_axis(JointAxis::X, [-0.3, 0.3])
|
||||
.limit_axis(JointAxis::Y, [-0.3, 0.3]);
|
||||
|
||||
if use_articulations {
|
||||
multibody_joints.insert(ground, ball1, joint1);
|
||||
multibody_joints.insert(ball1, ball2, joint2);
|
||||
} else {
|
||||
impulse_joints.insert(ground, ball1, joint1);
|
||||
impulse_joints.insert(ball1, ball2, joint2);
|
||||
}
|
||||
}
|
||||
|
||||
fn create_actuated_revolute_joints(
|
||||
bodies: &mut RigidBodySet,
|
||||
colliders: &mut ColliderSet,
|
||||
impulse_joints: &mut ImpulseJointSet,
|
||||
multibody_joints: &mut MultibodyJointSet,
|
||||
origin: Point<f32>,
|
||||
num: usize,
|
||||
use_articulations: bool,
|
||||
) {
|
||||
let rad = 0.4;
|
||||
let shift = 2.0;
|
||||
|
||||
// We will reuse this base configuration for all the impulse_joints here.
|
||||
let z = Vector::z_axis();
|
||||
let joint_template = RevoluteJoint::new(z).local_anchor2(point![0.0, 0.0, -shift]);
|
||||
|
||||
let mut parent_handle = RigidBodyHandle::invalid();
|
||||
|
||||
for i in 0..num {
|
||||
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 {
|
||||
RigidBodyType::Static
|
||||
} else {
|
||||
RigidBodyType::Dynamic
|
||||
};
|
||||
|
||||
let shifty = (i >= 1) as u32 as f32 * -2.0;
|
||||
|
||||
let rigid_body = RigidBodyBuilder::new(status)
|
||||
.translation(vector![origin.x, origin.y + shifty, origin.z + fi * shift])
|
||||
// .rotation(Vector3::new(0.0, fi * 1.1, 0.0))
|
||||
.build();
|
||||
|
||||
let child_handle = bodies.insert(rigid_body);
|
||||
let collider = ColliderBuilder::cuboid(rad * 2.0, rad * 6.0 / (fi + 1.0), rad).build();
|
||||
colliders.insert_with_parent(collider, child_handle, bodies);
|
||||
|
||||
if i > 0 {
|
||||
let mut joint = joint_template.clone();
|
||||
|
||||
if i % 3 == 1 {
|
||||
joint = joint.motor_velocity(-20.0, 0.1);
|
||||
} else if i == num - 1 {
|
||||
let stiffness = 0.2;
|
||||
let damping = 1.0;
|
||||
joint = joint.motor_position(3.14 / 2.0, stiffness, damping);
|
||||
}
|
||||
|
||||
if i == 1 {
|
||||
joint = joint
|
||||
.local_anchor2(point![0.0, 2.0, -shift])
|
||||
.motor_velocity(-2.0, 0.1);
|
||||
}
|
||||
|
||||
if use_articulations {
|
||||
multibody_joints.insert(parent_handle, child_handle, joint);
|
||||
} else {
|
||||
impulse_joints.insert(parent_handle, child_handle, joint);
|
||||
}
|
||||
}
|
||||
|
||||
parent_handle = child_handle;
|
||||
}
|
||||
}
|
||||
|
||||
fn create_actuated_spherical_joints(
|
||||
bodies: &mut RigidBodySet,
|
||||
colliders: &mut ColliderSet,
|
||||
impulse_joints: &mut ImpulseJointSet,
|
||||
multibody_joints: &mut MultibodyJointSet,
|
||||
origin: Point<f32>,
|
||||
num: usize,
|
||||
use_articulations: bool,
|
||||
) {
|
||||
let rad = 0.4;
|
||||
let shift = 2.0;
|
||||
|
||||
// We will reuse this base configuration for all the impulse_joints here.
|
||||
let joint_template = SphericalJoint::new().local_anchor1(point![0.0, 0.0, shift]);
|
||||
|
||||
let mut parent_handle = RigidBodyHandle::invalid();
|
||||
|
||||
for i in 0..num {
|
||||
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 {
|
||||
RigidBodyType::Static
|
||||
} else {
|
||||
RigidBodyType::Dynamic
|
||||
};
|
||||
|
||||
let rigid_body = RigidBodyBuilder::new(status)
|
||||
.translation(vector![origin.x, origin.y, origin.z + fi * shift])
|
||||
// .rotation(Vector3::new(0.0, fi * 1.1, 0.0))
|
||||
.build();
|
||||
|
||||
let child_handle = bodies.insert(rigid_body);
|
||||
let collider = ColliderBuilder::capsule_y(rad * 2.0 / (fi + 1.0), rad).build();
|
||||
colliders.insert_with_parent(collider, child_handle, bodies);
|
||||
|
||||
if i > 0 {
|
||||
let mut joint = joint_template.clone();
|
||||
|
||||
if i == 1 {
|
||||
joint = joint
|
||||
.motor_velocity(JointAxis::AngX, 0.0, 0.1)
|
||||
.motor_velocity(JointAxis::AngY, 0.5, 0.1)
|
||||
.motor_velocity(JointAxis::AngZ, -2.0, 0.1);
|
||||
} else if i == num - 1 {
|
||||
let stiffness = 0.2;
|
||||
let damping = 1.0;
|
||||
joint = joint
|
||||
.motor_position(JointAxis::AngX, 0.0, stiffness, damping)
|
||||
.motor_position(JointAxis::AngY, 1.0, stiffness, damping)
|
||||
.motor_position(JointAxis::AngZ, 3.14 / 2.0, stiffness, damping);
|
||||
}
|
||||
|
||||
if use_articulations {
|
||||
multibody_joints.insert(parent_handle, child_handle, joint);
|
||||
} else {
|
||||
impulse_joints.insert(parent_handle, child_handle, joint);
|
||||
}
|
||||
}
|
||||
|
||||
parent_handle = child_handle;
|
||||
}
|
||||
}
|
||||
|
||||
fn do_init_world(testbed: &mut Testbed, use_articulations: bool) {
|
||||
/*
|
||||
* World
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let mut impulse_joints = ImpulseJointSet::new();
|
||||
let mut multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
create_prismatic_joints(
|
||||
&mut bodies,
|
||||
&mut colliders,
|
||||
&mut impulse_joints,
|
||||
&mut multibody_joints,
|
||||
point![20.0, 5.0, 0.0],
|
||||
4,
|
||||
use_articulations,
|
||||
);
|
||||
create_actuated_prismatic_joints(
|
||||
&mut bodies,
|
||||
&mut colliders,
|
||||
&mut impulse_joints,
|
||||
&mut multibody_joints,
|
||||
point![25.0, 5.0, 0.0],
|
||||
4,
|
||||
use_articulations,
|
||||
);
|
||||
create_revolute_joints(
|
||||
&mut bodies,
|
||||
&mut colliders,
|
||||
&mut impulse_joints,
|
||||
&mut multibody_joints,
|
||||
point![20.0, 0.0, 0.0],
|
||||
3,
|
||||
use_articulations,
|
||||
);
|
||||
create_revolute_joints_with_limits(
|
||||
&mut bodies,
|
||||
&mut colliders,
|
||||
&mut impulse_joints,
|
||||
&mut multibody_joints,
|
||||
point![34.0, 0.0, 0.0],
|
||||
use_articulations,
|
||||
);
|
||||
create_fixed_joints(
|
||||
&mut bodies,
|
||||
&mut colliders,
|
||||
&mut impulse_joints,
|
||||
&mut multibody_joints,
|
||||
point![0.0, 10.0, 0.0],
|
||||
10,
|
||||
use_articulations,
|
||||
);
|
||||
create_actuated_revolute_joints(
|
||||
&mut bodies,
|
||||
&mut colliders,
|
||||
&mut impulse_joints,
|
||||
&mut multibody_joints,
|
||||
point![20.0, 10.0, 0.0],
|
||||
6,
|
||||
use_articulations,
|
||||
);
|
||||
create_actuated_spherical_joints(
|
||||
&mut bodies,
|
||||
&mut colliders,
|
||||
&mut impulse_joints,
|
||||
&mut multibody_joints,
|
||||
point![13.0, 10.0, 0.0],
|
||||
3,
|
||||
use_articulations,
|
||||
);
|
||||
create_spherical_joints(
|
||||
&mut bodies,
|
||||
&mut colliders,
|
||||
&mut impulse_joints,
|
||||
&mut multibody_joints,
|
||||
15,
|
||||
use_articulations,
|
||||
);
|
||||
create_spherical_joints_with_limits(
|
||||
&mut bodies,
|
||||
&mut colliders,
|
||||
&mut impulse_joints,
|
||||
&mut multibody_joints,
|
||||
point![-5.0, 0.0, 0.0],
|
||||
use_articulations,
|
||||
);
|
||||
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![15.0, 5.0, 42.0], point![13.0, 1.0, 1.0]);
|
||||
}
|
||||
|
||||
pub fn init_world_with_joints(testbed: &mut Testbed) {
|
||||
do_init_world(testbed, false)
|
||||
}
|
||||
|
||||
pub fn init_world_with_articulations(testbed: &mut Testbed) {
|
||||
do_init_world(testbed, true)
|
||||
}
|
||||
@@ -44,7 +44,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
@@ -153,6 +154,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![100.0, 100.0, 100.0], Point::origin());
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
@@ -93,6 +94,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point!(10.0, 10.0, 10.0), Point::origin());
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
@@ -90,6 +91,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![100.0, 100.0, 100.0], Point::origin());
|
||||
}
|
||||
|
||||
@@ -15,7 +15,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
@@ -52,7 +53,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
.iter()
|
||||
.map(|v| point![v.0, v.1, v.2])
|
||||
.collect();
|
||||
use std::iter::FromIterator;
|
||||
let indices: Vec<_> = model
|
||||
.polygons
|
||||
.into_iter()
|
||||
@@ -104,7 +104,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![100.0, 100.0, 100.0], Point::origin());
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
@@ -68,6 +69,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![30.0, 30.0, 30.0], Point::origin());
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Create the cubes
|
||||
@@ -38,6 +39,13 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world_with_params(bodies, colliders, joints, Vector::zeros(), ());
|
||||
testbed.set_world_with_params(
|
||||
bodies,
|
||||
colliders,
|
||||
impulse_joints,
|
||||
multibody_joints,
|
||||
Vector::zeros(),
|
||||
(),
|
||||
);
|
||||
testbed.look_at(point![2.0, 2.5, 20.0], point![2.0, 2.5, 0.0]);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,9 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground.
|
||||
*/
|
||||
@@ -54,6 +56,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![10.0, 10.0, 10.0], Point::origin());
|
||||
}
|
||||
|
||||
98
examples3d/debug_articulations3.rs
Normal file
98
examples3d/debug_articulations3.rs
Normal file
@@ -0,0 +1,98 @@
|
||||
use rapier3d::prelude::*;
|
||||
use rapier_testbed3d::Testbed;
|
||||
|
||||
fn create_ball_articulations(
|
||||
bodies: &mut RigidBodySet,
|
||||
colliders: &mut ColliderSet,
|
||||
impulse_joints: &mut ImpulseJointSet,
|
||||
multibody_joints: &mut MultibodyJointSet,
|
||||
num: usize,
|
||||
) {
|
||||
let rad = 0.4;
|
||||
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::Static
|
||||
} else {
|
||||
RigidBodyType::Dynamic
|
||||
};
|
||||
|
||||
let rigid_body = RigidBodyBuilder::new(status)
|
||||
.translation(vector![fk * shift, 0.0, fi * shift * 2.0])
|
||||
.build();
|
||||
let child_handle = bodies.insert(rigid_body);
|
||||
let collider = ColliderBuilder::capsule_z(rad * 1.25, rad).build();
|
||||
colliders.insert_with_parent(collider, child_handle, bodies);
|
||||
|
||||
// Vertical multibody_joint.
|
||||
if i > 0 {
|
||||
let parent_handle = *body_handles.last().unwrap();
|
||||
let joint = SphericalJoint::new().local_anchor2(point![0.0, 0.0, -shift * 2.0]);
|
||||
multibody_joints.insert(parent_handle, child_handle, joint);
|
||||
}
|
||||
|
||||
// Horizontal multibody_joint.
|
||||
if k > 0 && i > 0 {
|
||||
let parent_index = body_handles.len() - num;
|
||||
let parent_handle = body_handles[parent_index];
|
||||
let joint = SphericalJoint::new().local_anchor2(point![-shift, 0.0, 0.0]);
|
||||
// let joint =
|
||||
// PrismaticJoint::new(Vector::y_axis()).local_anchor2(point![-shift, 0.0, 0.0]);
|
||||
// let joint = FixedJoint::new().local_anchor2(point![-shift, 0.0, 0.0]);
|
||||
// let joint =
|
||||
// RevoluteJoint::new(Vector::x_axis()).local_anchor2(point![-shift, 0.0, 0.0]);
|
||||
impulse_joints.insert(parent_handle, child_handle, joint);
|
||||
}
|
||||
|
||||
body_handles.push(child_handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 mut multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
let rigid_body = RigidBodyBuilder::new_dynamic().build();
|
||||
let collider = ColliderBuilder::cuboid(30.0, 0.01, 30.0) // Vector::y_axis())
|
||||
.translation(vector![0.0, -3.0, 0.0])
|
||||
.rotation(vector![0.1, 0.0, 0.1])
|
||||
.build();
|
||||
let handle = bodies.insert(rigid_body);
|
||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||
|
||||
let rigid_body = RigidBodyBuilder::new_static().build();
|
||||
let collider = ColliderBuilder::cuboid(30.0, 0.01, 30.0) // Vector::y_axis())
|
||||
.translation(vector![0.0, -3.02, 0.0])
|
||||
.rotation(vector![0.1, 0.0, 0.1])
|
||||
.build();
|
||||
let handle = bodies.insert(rigid_body);
|
||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||
|
||||
create_ball_articulations(
|
||||
&mut bodies,
|
||||
&mut colliders,
|
||||
&mut impulse_joints,
|
||||
&mut multibody_joints,
|
||||
15,
|
||||
);
|
||||
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![15.0, 5.0, 42.0], point![13.0, 1.0, 1.0]);
|
||||
}
|
||||
@@ -7,7 +7,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
@@ -38,6 +39,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![10.0, 10.0, 10.0], Point::origin());
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
@@ -25,10 +26,10 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
}
|
||||
|
||||
// Build the dynamic box rigid body.
|
||||
for _ in 0..6 {
|
||||
for _ in 0..2 {
|
||||
let rigid_body = RigidBodyBuilder::new_dynamic()
|
||||
.translation(vector![1.1, 0.0, 0.0])
|
||||
.rotation(vector![0.8, 0.2, 0.1])
|
||||
// .rotation(vector![0.8, 0.2, 0.1])
|
||||
.can_sleep(false)
|
||||
.build();
|
||||
let handle = bodies.insert(rigid_body);
|
||||
@@ -39,6 +40,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![10.0, 10.0, 10.0], Point::origin());
|
||||
}
|
||||
|
||||
@@ -10,7 +10,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
@@ -55,6 +56,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![100.0, 100.0, 100.0], Point::origin());
|
||||
}
|
||||
|
||||
@@ -7,7 +7,9 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground.
|
||||
*/
|
||||
@@ -114,6 +116,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![10.0, 10.0, 10.0], Point::origin());
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
@@ -38,6 +39,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![100.0, 100.0, 100.0], Point::origin());
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
@@ -44,5 +45,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.look_at(point![100.0, -10.0, 100.0], Point::origin());
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ use rapier_testbed3d::Testbed;
|
||||
fn prismatic_repro(
|
||||
bodies: &mut RigidBodySet,
|
||||
colliders: &mut ColliderSet,
|
||||
joints: &mut JointSet,
|
||||
impulse_joints: &mut ImpulseJointSet,
|
||||
box_center: Point<f32>,
|
||||
) {
|
||||
let box_rb = bodies.insert(
|
||||
@@ -39,19 +39,12 @@ fn prismatic_repro(
|
||||
);
|
||||
colliders.insert_with_parent(ColliderBuilder::ball(0.5).build(), wheel_rb, bodies);
|
||||
|
||||
let mut prismatic = rapier3d::dynamics::PrismaticJoint::new(
|
||||
point![pos.x, pos.y, pos.z],
|
||||
Vector::y_axis(),
|
||||
Vector::zeros(),
|
||||
Point::origin(),
|
||||
Vector::y_axis(),
|
||||
Vector::default(),
|
||||
);
|
||||
prismatic.configure_motor_model(rapier3d::dynamics::SpringModel::VelocityBased);
|
||||
let (stiffness, damping) = (0.05, 0.2);
|
||||
prismatic.configure_motor_position(0.0, stiffness, damping);
|
||||
|
||||
joints.insert(box_rb, wheel_rb, prismatic);
|
||||
let prismatic = PrismaticJoint::new(Vector::y_axis())
|
||||
.local_anchor1(point![pos.x, pos.y, pos.z])
|
||||
.motor_position(0.0, stiffness, damping);
|
||||
impulse_joints.insert(box_rb, wheel_rb, prismatic);
|
||||
}
|
||||
|
||||
// put a small box under one of the wheels
|
||||
@@ -73,7 +66,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let mut joints = JointSet::new();
|
||||
let mut impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
@@ -91,13 +85,13 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
prismatic_repro(
|
||||
&mut bodies,
|
||||
&mut colliders,
|
||||
&mut joints,
|
||||
&mut impulse_joints,
|
||||
point![0.0, 5.0, 0.0],
|
||||
);
|
||||
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![10.0, 10.0, 10.0], Point::origin());
|
||||
}
|
||||
|
||||
@@ -7,7 +7,9 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground.
|
||||
*/
|
||||
@@ -65,6 +67,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![10.0, 10.0, 10.0], Point::origin());
|
||||
}
|
||||
|
||||
@@ -7,7 +7,9 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground.
|
||||
*/
|
||||
@@ -113,6 +115,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![10.0, 10.0, 10.0], Point::origin());
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
// Triangle ground.
|
||||
let vtx = [
|
||||
@@ -36,6 +37,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![10.0, 10.0, 10.0], Point::origin());
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
// Triangle ground.
|
||||
let width = 0.5;
|
||||
@@ -57,6 +58,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![10.0, 10.0, 10.0], Point::origin());
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
@@ -73,6 +74,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![100.0, 100.0, 100.0], Point::origin());
|
||||
}
|
||||
|
||||
@@ -6,7 +6,9 @@ const MAX_NUMBER_OF_BODIES: usize = 400;
|
||||
pub fn init_world(testbed: &mut Testbed) {
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
let rad = 0.5;
|
||||
|
||||
/*
|
||||
@@ -63,7 +65,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*handle,
|
||||
&mut physics.islands,
|
||||
&mut physics.colliders,
|
||||
&mut physics.joints,
|
||||
&mut physics.impulse_joints,
|
||||
&mut physics.multibody_joints,
|
||||
);
|
||||
|
||||
if let Some(graphics) = &mut graphics {
|
||||
@@ -76,10 +79,10 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
// testbed
|
||||
// .physics_state_mut()
|
||||
// .integration_parameters
|
||||
// .velocity_based_erp = 0.2;
|
||||
// .erp = 0.2;
|
||||
testbed.look_at(point![-30.0, 4.0, -30.0], point![0.0, 1.0, 0.0]);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ pub fn init_world(harness: &mut Harness) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
@@ -59,7 +60,7 @@ pub fn init_world(harness: &mut Harness) {
|
||||
/*
|
||||
* Set up the harness.
|
||||
*/
|
||||
harness.set_world(bodies, colliders, joints);
|
||||
harness.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
||||
@@ -8,7 +8,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
@@ -95,6 +96,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![100.0, 100.0, 100.0], Point::origin());
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ use rapier_testbed3d::Testbed;
|
||||
fn create_prismatic_joints(
|
||||
bodies: &mut RigidBodySet,
|
||||
colliders: &mut ColliderSet,
|
||||
joints: &mut JointSet,
|
||||
impulse_joints: &mut ImpulseJointSet,
|
||||
origin: Point<f32>,
|
||||
num: usize,
|
||||
) {
|
||||
@@ -28,25 +28,17 @@ fn create_prismatic_joints(
|
||||
colliders.insert_with_parent(collider, curr_child, bodies);
|
||||
|
||||
let axis = if i % 2 == 0 {
|
||||
UnitVector::new_normalize(vector![1.0, 1.0, 0.0])
|
||||
UnitVector::new_normalize(vector![1.0f32, 1.0, 0.0])
|
||||
} else {
|
||||
UnitVector::new_normalize(vector![-1.0, 1.0, 0.0])
|
||||
UnitVector::new_normalize(vector![-1.0f32, 1.0, 0.0])
|
||||
};
|
||||
|
||||
let z = Vector::z();
|
||||
let mut prism = PrismaticJoint::new(
|
||||
point![0.0, 0.0, 0.0],
|
||||
axis,
|
||||
z,
|
||||
point![0.0, 0.0, -shift],
|
||||
axis,
|
||||
z,
|
||||
);
|
||||
prism.limits_enabled = true;
|
||||
prism.limits[0] = -2.0;
|
||||
prism.limits[1] = 2.0;
|
||||
let mut prism = JointData::prismatic(axis)
|
||||
.local_anchor1(point![0.0, 0.0, shift])
|
||||
.local_anchor2(point![0.0, 0.0, 0.0])
|
||||
.limit_axis(JointAxis::X, [-2.0, 2.0]);
|
||||
|
||||
joints.insert(curr_parent, curr_child, prism);
|
||||
impulse_joints.insert(curr_parent, curr_child, prism);
|
||||
|
||||
curr_parent = curr_child;
|
||||
}
|
||||
@@ -55,7 +47,7 @@ fn create_prismatic_joints(
|
||||
fn create_actuated_prismatic_joints(
|
||||
bodies: &mut RigidBodySet,
|
||||
colliders: &mut ColliderSet,
|
||||
joints: &mut JointSet,
|
||||
impulse_joints: &mut ImpulseJointSet,
|
||||
origin: Point<f32>,
|
||||
num: usize,
|
||||
) {
|
||||
@@ -84,36 +76,29 @@ fn create_actuated_prismatic_joints(
|
||||
UnitVector::new_normalize(vector![-1.0, 1.0, 0.0])
|
||||
};
|
||||
|
||||
let z = Vector::z();
|
||||
let mut prism = PrismaticJoint::new(
|
||||
point![0.0, 0.0, 0.0],
|
||||
axis,
|
||||
z,
|
||||
point![0.0, 0.0, -shift],
|
||||
axis,
|
||||
z,
|
||||
);
|
||||
let mut prism = JointData::prismatic(axis)
|
||||
.local_anchor1(point![0.0, 0.0, 0.0])
|
||||
.local_anchor2(point![0.0, 0.0, -shift]);
|
||||
|
||||
if i == 1 {
|
||||
prism.configure_motor_velocity(1.0, 1.0);
|
||||
prism.limits_enabled = true;
|
||||
prism.limits[1] = 5.0;
|
||||
// We set a max impulse so that the motor doesn't fight
|
||||
// the limits with large forces.
|
||||
prism.motor_max_impulse = 1.0;
|
||||
prism = prism
|
||||
.limit_axis(JointAxis::X, [-Real::MAX, 5.0])
|
||||
.motor_velocity(JointAxis::X, 1.0, 1.0)
|
||||
// We set a max impulse so that the motor doesn't fight
|
||||
// the limits with large forces.
|
||||
.motor_max_impulse(JointAxis::X, 1.0);
|
||||
} else if i > 1 {
|
||||
prism.configure_motor_position(2.0, 0.01, 1.0);
|
||||
prism = prism.motor_position(JointAxis::X, 2.0, 0.01, 1.0);
|
||||
} else {
|
||||
prism.configure_motor_velocity(1.0, 1.0);
|
||||
// We set a max impulse so that the motor doesn't fight
|
||||
// the limits with large forces.
|
||||
prism.motor_max_impulse = 0.7;
|
||||
prism.limits_enabled = true;
|
||||
prism.limits[0] = -2.0;
|
||||
prism.limits[1] = 5.0;
|
||||
prism = prism
|
||||
.motor_velocity(JointAxis::X, 1.0, 1.0)
|
||||
// We set a max impulse so that the motor doesn't fight
|
||||
// the limits with large forces.
|
||||
.motor_max_impulse(JointAxis::X, 0.7)
|
||||
.limit_axis(JointAxis::X, [-2.0, 5.0]);
|
||||
}
|
||||
|
||||
joints.insert(curr_parent, curr_child, prism);
|
||||
impulse_joints.insert(curr_parent, curr_child, prism);
|
||||
|
||||
curr_parent = curr_child;
|
||||
}
|
||||
@@ -122,7 +107,7 @@ fn create_actuated_prismatic_joints(
|
||||
fn create_revolute_joints(
|
||||
bodies: &mut RigidBodySet,
|
||||
colliders: &mut ColliderSet,
|
||||
joints: &mut JointSet,
|
||||
impulse_joints: &mut ImpulseJointSet,
|
||||
origin: Point<f32>,
|
||||
num: usize,
|
||||
) {
|
||||
@@ -156,22 +141,20 @@ fn create_revolute_joints(
|
||||
colliders.insert_with_parent(collider, handles[k], bodies);
|
||||
}
|
||||
|
||||
// Setup four joints.
|
||||
let o = Point::origin();
|
||||
// Setup four impulse_joints.
|
||||
let x = Vector::x_axis();
|
||||
let z = Vector::z_axis();
|
||||
|
||||
let revs = [
|
||||
RevoluteJoint::new(o, z, point![0.0, 0.0, -shift], z),
|
||||
RevoluteJoint::new(o, x, point![-shift, 0.0, 0.0], x),
|
||||
RevoluteJoint::new(o, z, point![0.0, 0.0, -shift], z),
|
||||
RevoluteJoint::new(o, x, point![shift, 0.0, 0.0], x),
|
||||
RevoluteJoint::new(x).local_anchor2(point![0.0, 0.0, -shift]),
|
||||
RevoluteJoint::new(z).local_anchor2(point![-shift, 0.0, 0.0]),
|
||||
RevoluteJoint::new(x).local_anchor2(point![0.0, 0.0, -shift]),
|
||||
RevoluteJoint::new(z).local_anchor2(point![shift, 0.0, 0.0]),
|
||||
];
|
||||
|
||||
joints.insert(curr_parent, handles[0], revs[0]);
|
||||
joints.insert(handles[0], handles[1], revs[1]);
|
||||
joints.insert(handles[1], handles[2], revs[2]);
|
||||
joints.insert(handles[2], handles[3], revs[3]);
|
||||
impulse_joints.insert(curr_parent, handles[0], revs[0]);
|
||||
impulse_joints.insert(handles[0], handles[1], revs[1]);
|
||||
impulse_joints.insert(handles[1], handles[2], revs[2]);
|
||||
impulse_joints.insert(handles[2], handles[3], revs[3]);
|
||||
|
||||
curr_parent = handles[3];
|
||||
}
|
||||
@@ -180,7 +163,7 @@ fn create_revolute_joints(
|
||||
fn create_revolute_joints_with_limits(
|
||||
bodies: &mut RigidBodySet,
|
||||
colliders: &mut ColliderSet,
|
||||
joints: &mut JointSet,
|
||||
impulse_joints: &mut ImpulseJointSet,
|
||||
origin: Point<f32>,
|
||||
) {
|
||||
let ground = bodies.insert(
|
||||
@@ -212,25 +195,14 @@ fn create_revolute_joints_with_limits(
|
||||
bodies,
|
||||
);
|
||||
|
||||
let mut joint1 = RevoluteJoint::new(
|
||||
Point::origin(),
|
||||
Vector::z_axis(),
|
||||
Point::origin(),
|
||||
Vector::z_axis(),
|
||||
);
|
||||
joint1.limits_enabled = true;
|
||||
joint1.limits = [-0.2, 0.2];
|
||||
joints.insert(ground, platform1, joint1);
|
||||
let z = Vector::z_axis();
|
||||
let mut joint1 = RevoluteJoint::new(z).limit_axis(JointAxis::X, [-0.2, 0.2]);
|
||||
impulse_joints.insert(ground, platform1, joint1);
|
||||
|
||||
let mut joint2 = RevoluteJoint::new(
|
||||
Point::origin(),
|
||||
Vector::z_axis(),
|
||||
Point::from(-shift),
|
||||
Vector::z_axis(),
|
||||
);
|
||||
joint2.limits_enabled = true;
|
||||
joint2.limits = [-0.3, 0.3];
|
||||
joints.insert(platform1, platform2, joint2);
|
||||
let mut joint2 = RevoluteJoint::new(z)
|
||||
.local_anchor2(shift.into())
|
||||
.limit_axis(JointAxis::Z, [-0.2, 0.2]);
|
||||
impulse_joints.insert(platform1, platform2, joint2);
|
||||
|
||||
// Let’s add a couple of cuboids that will fall on the platforms, triggering the joint limits.
|
||||
let cuboid_body1 = bodies.insert(
|
||||
@@ -259,7 +231,7 @@ fn create_revolute_joints_with_limits(
|
||||
fn create_fixed_joints(
|
||||
bodies: &mut RigidBodySet,
|
||||
colliders: &mut ColliderSet,
|
||||
joints: &mut JointSet,
|
||||
impulse_joints: &mut ImpulseJointSet,
|
||||
origin: Point<f32>,
|
||||
num: usize,
|
||||
) {
|
||||
@@ -268,8 +240,8 @@ fn create_fixed_joints(
|
||||
|
||||
let mut body_handles = Vec::new();
|
||||
|
||||
for k in 0..num {
|
||||
for i in 0..num {
|
||||
for i in 0..num {
|
||||
for k in 0..num {
|
||||
let fk = k as f32;
|
||||
let fi = i as f32;
|
||||
|
||||
@@ -295,23 +267,18 @@ fn create_fixed_joints(
|
||||
|
||||
// Vertical joint.
|
||||
if i > 0 {
|
||||
let parent_handle = *body_handles.last().unwrap();
|
||||
let joint = FixedJoint::new(
|
||||
Isometry::identity(),
|
||||
Isometry::translation(0.0, 0.0, -shift),
|
||||
);
|
||||
joints.insert(parent_handle, child_handle, joint);
|
||||
let parent_index = body_handles.len() - num;
|
||||
let parent_handle = body_handles[parent_index];
|
||||
let joint = JointData::fixed().local_anchor2(point![0.0, 0.0, -shift]);
|
||||
impulse_joints.insert(parent_handle, child_handle, joint);
|
||||
}
|
||||
|
||||
// Horizontal joint.
|
||||
if k > 0 {
|
||||
let parent_index = body_handles.len() - num;
|
||||
let parent_index = body_handles.len() - 1;
|
||||
let parent_handle = body_handles[parent_index];
|
||||
let joint = FixedJoint::new(
|
||||
Isometry::identity(),
|
||||
Isometry::translation(-shift, 0.0, 0.0),
|
||||
);
|
||||
joints.insert(parent_handle, child_handle, joint);
|
||||
let joint = JointData::fixed().local_anchor2(point![-shift, 0.0, 0.0]);
|
||||
impulse_joints.insert(parent_handle, child_handle, joint);
|
||||
}
|
||||
|
||||
body_handles.push(child_handle);
|
||||
@@ -322,7 +289,7 @@ fn create_fixed_joints(
|
||||
fn create_ball_joints(
|
||||
bodies: &mut RigidBodySet,
|
||||
colliders: &mut ColliderSet,
|
||||
joints: &mut JointSet,
|
||||
impulse_joints: &mut ImpulseJointSet,
|
||||
num: usize,
|
||||
) {
|
||||
let rad = 0.4;
|
||||
@@ -351,16 +318,16 @@ fn create_ball_joints(
|
||||
// Vertical joint.
|
||||
if i > 0 {
|
||||
let parent_handle = *body_handles.last().unwrap();
|
||||
let joint = BallJoint::new(Point::origin(), point![0.0, 0.0, -shift * 2.0]);
|
||||
joints.insert(parent_handle, child_handle, joint);
|
||||
let joint = JointData::ball().local_anchor2(point![0.0, 0.0, -shift * 2.0]);
|
||||
impulse_joints.insert(parent_handle, child_handle, joint);
|
||||
}
|
||||
|
||||
// Horizontal joint.
|
||||
if k > 0 {
|
||||
let parent_index = body_handles.len() - num;
|
||||
let parent_handle = body_handles[parent_index];
|
||||
let joint = BallJoint::new(Point::origin(), point![-shift, 0.0, 0.0]);
|
||||
joints.insert(parent_handle, child_handle, joint);
|
||||
let joint = JointData::ball().local_anchor2(point![-shift, 0.0, 0.0]);
|
||||
impulse_joints.insert(parent_handle, child_handle, joint);
|
||||
}
|
||||
|
||||
body_handles.push(child_handle);
|
||||
@@ -371,7 +338,7 @@ fn create_ball_joints(
|
||||
fn create_ball_joints_with_limits(
|
||||
bodies: &mut RigidBodySet,
|
||||
colliders: &mut ColliderSet,
|
||||
joints: &mut JointSet,
|
||||
impulse_joints: &mut ImpulseJointSet,
|
||||
origin: Point<f32>,
|
||||
) {
|
||||
let shift = vector![0.0, 0.0, 3.0];
|
||||
@@ -405,38 +372,32 @@ fn create_ball_joints_with_limits(
|
||||
bodies,
|
||||
);
|
||||
|
||||
let mut joint1 = BallJoint::new(Point::origin(), Point::from(-shift));
|
||||
joint1.limits_enabled = true;
|
||||
joint1.limits_local_axis1 = Vector::z_axis();
|
||||
joint1.limits_local_axis2 = Vector::z_axis();
|
||||
joint1.limits_angle = 0.2;
|
||||
joints.insert(ground, ball1, joint1);
|
||||
let mut joint1 = JointData::ball()
|
||||
.local_anchor2(Point::from(-shift))
|
||||
.limit_axis(JointAxis::X, [-0.2, 0.2])
|
||||
.limit_axis(JointAxis::Y, [-0.2, 0.2]);
|
||||
impulse_joints.insert(ground, ball1, joint1);
|
||||
|
||||
let mut joint2 = BallJoint::new(Point::origin(), Point::from(-shift));
|
||||
joint2.limits_enabled = true;
|
||||
joint2.limits_local_axis1 = Vector::z_axis();
|
||||
joint2.limits_local_axis2 = Vector::z_axis();
|
||||
joint2.limits_angle = 0.3;
|
||||
joints.insert(ball1, ball2, joint2);
|
||||
let mut joint2 = JointData::ball()
|
||||
.local_anchor2(Point::from(-shift))
|
||||
.limit_axis(JointAxis::X, [-0.3, 0.3])
|
||||
.limit_axis(JointAxis::Y, [-0.3, 0.3]);
|
||||
impulse_joints.insert(ball1, ball2, joint2);
|
||||
}
|
||||
|
||||
fn create_actuated_revolute_joints(
|
||||
bodies: &mut RigidBodySet,
|
||||
colliders: &mut ColliderSet,
|
||||
joints: &mut JointSet,
|
||||
impulse_joints: &mut ImpulseJointSet,
|
||||
origin: Point<f32>,
|
||||
num: usize,
|
||||
) {
|
||||
let rad = 0.4;
|
||||
let shift = 2.0;
|
||||
|
||||
// We will reuse this base configuration for all the joints here.
|
||||
let joint_template = RevoluteJoint::new(
|
||||
Point::origin(),
|
||||
Vector::z_axis(),
|
||||
point![0.0, 0.0, -shift],
|
||||
Vector::z_axis(),
|
||||
);
|
||||
// We will reuse this base configuration for all the impulse_joints here.
|
||||
let z = Vector::z_axis();
|
||||
let joint_template = RevoluteJoint::new(z).local_anchor2(point![0.0, 0.0, -shift]);
|
||||
|
||||
let mut parent_handle = RigidBodyHandle::invalid();
|
||||
|
||||
@@ -467,19 +428,19 @@ fn create_actuated_revolute_joints(
|
||||
let mut joint = joint_template.clone();
|
||||
|
||||
if i % 3 == 1 {
|
||||
joint.configure_motor_velocity(-20.0, 0.1);
|
||||
joint = joint.motor_velocity(JointAxis::AngX, -20.0, 0.1);
|
||||
} else if i == num - 1 {
|
||||
let stiffness = 0.2;
|
||||
let damping = 1.0;
|
||||
joint.configure_motor_position(3.14 / 2.0, stiffness, damping);
|
||||
joint = joint.motor_position(JointAxis::AngX, 3.14 / 2.0, stiffness, damping);
|
||||
}
|
||||
|
||||
if i == 1 {
|
||||
joint.local_anchor2.y = 2.0;
|
||||
joint.configure_motor_velocity(-2.0, 0.1);
|
||||
joint.local_frame2.translation.vector.y = 2.0;
|
||||
joint = joint.motor_velocity(JointAxis::AngX, -2.0, 0.1);
|
||||
}
|
||||
|
||||
joints.insert(parent_handle, child_handle, joint);
|
||||
impulse_joints.insert(parent_handle, child_handle, joint);
|
||||
}
|
||||
|
||||
parent_handle = child_handle;
|
||||
@@ -489,15 +450,15 @@ fn create_actuated_revolute_joints(
|
||||
fn create_actuated_ball_joints(
|
||||
bodies: &mut RigidBodySet,
|
||||
colliders: &mut ColliderSet,
|
||||
joints: &mut JointSet,
|
||||
impulse_joints: &mut ImpulseJointSet,
|
||||
origin: Point<f32>,
|
||||
num: usize,
|
||||
) {
|
||||
let rad = 0.4;
|
||||
let shift = 2.0;
|
||||
|
||||
// We will reuse this base configuration for all the joints here.
|
||||
let joint_template = BallJoint::new(point![0.0, 0.0, shift], Point::origin());
|
||||
// We will reuse this base configuration for all the impulse_joints here.
|
||||
let joint_template = JointData::ball().local_anchor1(point![0.0, 0.0, shift]);
|
||||
|
||||
let mut parent_handle = RigidBodyHandle::invalid();
|
||||
|
||||
@@ -526,18 +487,20 @@ fn create_actuated_ball_joints(
|
||||
let mut joint = joint_template.clone();
|
||||
|
||||
if i == 1 {
|
||||
joint.configure_motor_velocity(vector![0.0, 0.5, -2.0], 0.1);
|
||||
joint = joint
|
||||
.motor_velocity(JointAxis::AngX, 0.0, 0.1)
|
||||
.motor_velocity(JointAxis::AngY, 0.5, 0.1)
|
||||
.motor_velocity(JointAxis::AngZ, -2.0, 0.1);
|
||||
} else if i == num - 1 {
|
||||
let stiffness = 0.2;
|
||||
let damping = 1.0;
|
||||
joint.configure_motor_position(
|
||||
Rotation::new(vector![0.0, 1.0, 3.14 / 2.0]),
|
||||
stiffness,
|
||||
damping,
|
||||
);
|
||||
joint = joint
|
||||
.motor_position(JointAxis::AngX, 0.0, stiffness, damping)
|
||||
.motor_position(JointAxis::AngY, 1.0, stiffness, damping)
|
||||
.motor_position(JointAxis::AngZ, 3.14 / 2.0, stiffness, damping);
|
||||
}
|
||||
|
||||
joints.insert(parent_handle, child_handle, joint);
|
||||
impulse_joints.insert(parent_handle, child_handle, joint);
|
||||
}
|
||||
|
||||
parent_handle = child_handle;
|
||||
@@ -550,67 +513,68 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let mut joints = JointSet::new();
|
||||
let mut impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
create_prismatic_joints(
|
||||
&mut bodies,
|
||||
&mut colliders,
|
||||
&mut joints,
|
||||
&mut impulse_joints,
|
||||
point![20.0, 5.0, 0.0],
|
||||
4,
|
||||
);
|
||||
create_actuated_prismatic_joints(
|
||||
&mut bodies,
|
||||
&mut colliders,
|
||||
&mut joints,
|
||||
&mut impulse_joints,
|
||||
point![25.0, 5.0, 0.0],
|
||||
4,
|
||||
);
|
||||
create_revolute_joints(
|
||||
&mut bodies,
|
||||
&mut colliders,
|
||||
&mut joints,
|
||||
&mut impulse_joints,
|
||||
point![20.0, 0.0, 0.0],
|
||||
3,
|
||||
);
|
||||
create_revolute_joints_with_limits(
|
||||
&mut bodies,
|
||||
&mut colliders,
|
||||
&mut joints,
|
||||
&mut impulse_joints,
|
||||
point![34.0, 0.0, 0.0],
|
||||
);
|
||||
create_fixed_joints(
|
||||
&mut bodies,
|
||||
&mut colliders,
|
||||
&mut joints,
|
||||
&mut impulse_joints,
|
||||
point![0.0, 10.0, 0.0],
|
||||
10,
|
||||
);
|
||||
create_actuated_revolute_joints(
|
||||
&mut bodies,
|
||||
&mut colliders,
|
||||
&mut joints,
|
||||
&mut impulse_joints,
|
||||
point![20.0, 10.0, 0.0],
|
||||
6,
|
||||
);
|
||||
create_actuated_ball_joints(
|
||||
&mut bodies,
|
||||
&mut colliders,
|
||||
&mut joints,
|
||||
&mut impulse_joints,
|
||||
point![13.0, 10.0, 0.0],
|
||||
3,
|
||||
);
|
||||
create_ball_joints(&mut bodies, &mut colliders, &mut joints, 15);
|
||||
create_ball_joints(&mut bodies, &mut colliders, &mut impulse_joints, 15);
|
||||
create_ball_joints_with_limits(
|
||||
&mut bodies,
|
||||
&mut colliders,
|
||||
&mut joints,
|
||||
&mut impulse_joints,
|
||||
point![-5.0, 0.0, 0.0],
|
||||
);
|
||||
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![15.0, 5.0, 42.0], point![13.0, 1.0, 1.0]);
|
||||
}
|
||||
|
||||
@@ -83,7 +83,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
@@ -132,6 +133,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![100.0, 100.0, 100.0], Point::origin());
|
||||
}
|
||||
|
||||
@@ -10,7 +10,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* The ground
|
||||
@@ -54,6 +55,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![10.0, 3.0, 0.0], point![0.0, 3.0, 0.0]);
|
||||
}
|
||||
|
||||
@@ -62,7 +62,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
@@ -126,7 +127,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
testbed.set_world_with_params(
|
||||
bodies,
|
||||
colliders,
|
||||
joints,
|
||||
impulse_joints,
|
||||
multibody_joints,
|
||||
vector![0.0, -9.81, 0.0],
|
||||
physics_hooks,
|
||||
);
|
||||
|
||||
@@ -7,7 +7,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground.
|
||||
@@ -103,6 +104,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Run the simulation.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![-10.0, 5.0, -10.0], Point::origin());
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
@@ -51,13 +52,13 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
let handle = bodies.insert(rigid_body);
|
||||
|
||||
let collider = match j % 5 {
|
||||
0 => ColliderBuilder::cuboid(rad, rad, rad).build(),
|
||||
1 => ColliderBuilder::ball(rad).build(),
|
||||
// Rounded cylinders are much more efficient that cylinder, even if the
|
||||
// rounding margin is small.
|
||||
2 => ColliderBuilder::round_cylinder(rad, rad, rad / 10.0).build(),
|
||||
3 => ColliderBuilder::cone(rad, rad).build(),
|
||||
_ => ColliderBuilder::capsule_y(rad, rad).build(),
|
||||
_ => ColliderBuilder::cuboid(rad, rad, rad).build(),
|
||||
// 1 => ColliderBuilder::ball(rad).build(),
|
||||
// // Rounded cylinders are much more efficient that cylinder, even if the
|
||||
// // rounding margin is small.
|
||||
// 2 => ColliderBuilder::round_cylinder(rad, rad, rad / 10.0).build(),
|
||||
// 3 => ColliderBuilder::cone(rad, rad).build(),
|
||||
// _ => ColliderBuilder::capsule_y(rad, rad).build(),
|
||||
};
|
||||
|
||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||
@@ -70,6 +71,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![100.0, 100.0, 100.0], Point::origin());
|
||||
}
|
||||
|
||||
BIN
examples3d/rapier.data
Normal file
BIN
examples3d/rapier.data
Normal file
Binary file not shown.
@@ -7,7 +7,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
@@ -44,6 +45,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![0.0, 3.0, 30.0], point![0.0, 3.0, 0.0]);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground.
|
||||
@@ -102,6 +103,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![-6.0, 4.0, -6.0], point![0.0, 1.0, 0.0]);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
*/
|
||||
let mut bodies = RigidBodySet::new();
|
||||
let mut colliders = ColliderSet::new();
|
||||
let joints = JointSet::new();
|
||||
let impulse_joints = ImpulseJointSet::new();
|
||||
let multibody_joints = MultibodyJointSet::new();
|
||||
|
||||
/*
|
||||
* Ground
|
||||
@@ -100,6 +101,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_world(bodies, colliders, joints);
|
||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||
testbed.look_at(point![100.0, 100.0, 100.0], Point::origin());
|
||||
}
|
||||
|
||||
@@ -6,20 +6,20 @@ echo "$tmp"
|
||||
|
||||
cp -r src "$tmp"/.
|
||||
cp -r src_testbed "$tmp"/.
|
||||
cp -r build "$tmp"/.
|
||||
cp -r crates "$tmp"/.
|
||||
cp -r LICENSE README.md "$tmp"/.
|
||||
|
||||
### Publish the 2D version.
|
||||
sed 's#\.\./\.\./src#src#g' build/rapier_testbed2d/Cargo.toml > "$tmp"/Cargo.toml
|
||||
sed -i 's#\.\./rapier#./build/rapier#g' "$tmp"/Cargo.toml
|
||||
sed 's#\.\./\.\./src#src#g' crates/rapier_testbed2d/Cargo.toml > "$tmp"/Cargo.toml
|
||||
sed -i 's#\.\./rapier#./crates/rapier#g' "$tmp"/Cargo.toml
|
||||
currdir=$(pwd)
|
||||
cd "$tmp" && cargo publish
|
||||
cd "$currdir" || exit
|
||||
|
||||
|
||||
### Publish the 3D version.
|
||||
sed 's#\.\./\.\./src#src#g' build/rapier_testbed3d/Cargo.toml > "$tmp"/Cargo.toml
|
||||
sed -i 's#\.\./rapier#./build/rapier#g' "$tmp"/Cargo.toml
|
||||
sed 's#\.\./\.\./src#src#g' crates/rapier_testbed3d/Cargo.toml > "$tmp"/Cargo.toml
|
||||
sed -i 's#\.\./rapier#./crates/rapier#g' "$tmp"/Cargo.toml
|
||||
cp -r LICENSE README.md "$tmp"/.
|
||||
cd "$tmp" && cargo publish
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ mod solver_counters;
|
||||
mod stages_counters;
|
||||
mod timer;
|
||||
|
||||
/// Aggregation of all the performances counters tracked by nphysics.
|
||||
/// Aggregation of all the performances counters tracked by rapier.
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Counters {
|
||||
/// Whether thi counter is enabled or not.
|
||||
@@ -34,7 +34,7 @@ pub struct Counters {
|
||||
}
|
||||
|
||||
impl Counters {
|
||||
/// Create a new set of counters initialized to wero.
|
||||
/// Create a new set of counters initialized to zero.
|
||||
pub fn new(enabled: bool) -> Self {
|
||||
Counters {
|
||||
enabled,
|
||||
|
||||
@@ -13,6 +13,14 @@ impl<T> Coarena<T> {
|
||||
Self { data: Vec::new() }
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> impl Iterator<Item = (Index, &T)> {
|
||||
self.data
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|(_, elt)| elt.0 != u32::MAX)
|
||||
.map(|(i, elt)| (Index::from_raw_parts(i as u32, elt.0), &elt.1))
|
||||
}
|
||||
|
||||
/// Gets a specific element from the coarena without specifying its generation number.
|
||||
///
|
||||
/// It is strongly encouraged to use `Coarena::get` instead of this method because this method
|
||||
@@ -23,12 +31,12 @@ impl<T> Coarena<T> {
|
||||
|
||||
/// Deletes an element for the coarena and returns its value.
|
||||
///
|
||||
/// We can't really remove an element from the coarena. So instead of actually removing
|
||||
/// it, this method will reset the value to the given `removed_value`.
|
||||
/// This method will reset the value to the given `removed_value`.
|
||||
pub fn remove(&mut self, index: Index, removed_value: T) -> Option<T> {
|
||||
let (i, g) = index.into_raw_parts();
|
||||
let data = self.data.get_mut(i as usize)?;
|
||||
if g == data.0 {
|
||||
data.0 = u32::MAX; // invalidate the generation number.
|
||||
Some(std::mem::replace(&mut data.1, removed_value))
|
||||
} else {
|
||||
None
|
||||
|
||||
@@ -644,19 +644,24 @@ impl<'a, E> Iterator for Edges<'a, E> {
|
||||
|
||||
// For iterate_over, "both" is represented as None.
|
||||
// For reverse, "no" is represented as None.
|
||||
let (iterate_over, reverse) = (None, Some(self.direction.opposite()));
|
||||
let (iterate_over, _reverse) = (None, Some(self.direction.opposite()));
|
||||
|
||||
if iterate_over.unwrap_or(Direction::Outgoing) == Direction::Outgoing {
|
||||
let i = self.next[0].index();
|
||||
if let Some(Edge { node, weight, next }) = self.edges.get(i) {
|
||||
if let Some(Edge {
|
||||
node: _node,
|
||||
weight,
|
||||
next,
|
||||
}) = self.edges.get(i)
|
||||
{
|
||||
self.next[0] = next[0];
|
||||
return Some(EdgeReference {
|
||||
index: EdgeIndex(i as u32),
|
||||
node: if reverse == Some(Direction::Outgoing) {
|
||||
swap_pair(*node)
|
||||
} else {
|
||||
*node
|
||||
},
|
||||
// node: if reverse == Some(Direction::Outgoing) {
|
||||
// swap_pair(*node)
|
||||
// } else {
|
||||
// *node
|
||||
// },
|
||||
weight,
|
||||
});
|
||||
}
|
||||
@@ -674,11 +679,11 @@ impl<'a, E> Iterator for Edges<'a, E> {
|
||||
|
||||
return Some(EdgeReference {
|
||||
index: edge_index,
|
||||
node: if reverse == Some(Direction::Incoming) {
|
||||
swap_pair(*node)
|
||||
} else {
|
||||
*node
|
||||
},
|
||||
// node: if reverse == Some(Direction::Incoming) {
|
||||
// swap_pair(*node)
|
||||
// } else {
|
||||
// *node
|
||||
// },
|
||||
weight,
|
||||
});
|
||||
}
|
||||
@@ -688,10 +693,10 @@ impl<'a, E> Iterator for Edges<'a, E> {
|
||||
}
|
||||
}
|
||||
|
||||
fn swap_pair<T>(mut x: [T; 2]) -> [T; 2] {
|
||||
x.swap(0, 1);
|
||||
x
|
||||
}
|
||||
// fn swap_pair<T>(mut x: [T; 2]) -> [T; 2] {
|
||||
// x.swap(0, 1);
|
||||
// x
|
||||
// }
|
||||
|
||||
impl<'a, E> Clone for Edges<'a, E> {
|
||||
fn clone(&self) -> Self {
|
||||
@@ -742,24 +747,11 @@ impl<N, E> IndexMut<EdgeIndex> for Graph<N, E> {
|
||||
}
|
||||
}
|
||||
|
||||
/// A “walker” object that can be used to step through the edge list of a node.
|
||||
///
|
||||
/// Created with [`.detach()`](struct.Neighbors.html#method.detach).
|
||||
///
|
||||
/// The walker does not borrow from the graph, so it lets you step through
|
||||
/// neighbors or incident edges while also mutating graph weights, as
|
||||
/// in the following example:
|
||||
#[derive(Clone)]
|
||||
pub struct WalkNeighbors {
|
||||
skip_start: NodeIndex,
|
||||
next: [EdgeIndex; 2],
|
||||
}
|
||||
|
||||
/// Reference to a `Graph` edge.
|
||||
#[derive(Debug)]
|
||||
pub struct EdgeReference<'a, E: 'a> {
|
||||
index: EdgeIndex,
|
||||
node: [NodeIndex; 2],
|
||||
// node: [NodeIndex; 2],
|
||||
weight: &'a E,
|
||||
}
|
||||
|
||||
|
||||
@@ -18,18 +18,6 @@ pub struct IntegrationParameters {
|
||||
/// to numerical instabilities.
|
||||
pub min_ccd_dt: Real,
|
||||
|
||||
/// The Error Reduction Parameter in `[0, 1]` is the proportion of
|
||||
/// the positional error to be corrected at each time step (default: `0.2`).
|
||||
pub erp: Real,
|
||||
/// The Error Reduction Parameter for joints in `[0, 1]` is the proportion of
|
||||
/// the positional error to be corrected at each time step (default: `0.2`).
|
||||
pub joint_erp: Real,
|
||||
/// Each cached impulse are multiplied by this coefficient in `[0, 1]`
|
||||
/// when they are re-used to initialize the solver (default `1.0`).
|
||||
pub warmstart_coeff: Real,
|
||||
/// Correction factor to avoid large warmstart impulse after a strong impact (default `10.0`).
|
||||
pub warmstart_correction_slope: Real,
|
||||
|
||||
/// 0-1: how much of the velocity to dampen out in the constraint solver?
|
||||
/// (default `1.0`).
|
||||
pub velocity_solve_fraction: Real,
|
||||
@@ -40,23 +28,21 @@ pub struct IntegrationParameters {
|
||||
/// If non-zero, you do not need the positional solver.
|
||||
/// A good non-zero value is around `0.2`.
|
||||
/// (default `0.0`).
|
||||
pub velocity_based_erp: Real,
|
||||
pub erp: Real,
|
||||
|
||||
/// Amount of penetration the engine wont attempt to correct (default: `0.005m`).
|
||||
/// Amount of penetration the engine wont attempt to correct (default: `0.001m`).
|
||||
pub allowed_linear_error: Real,
|
||||
/// The maximal distance separating two objects that will generate predictive contacts (default: `0.002`).
|
||||
pub prediction_distance: Real,
|
||||
/// Amount of angular drift of joint limits the engine wont
|
||||
/// attempt to correct (default: `0.001rad`).
|
||||
pub allowed_angular_error: Real,
|
||||
/// Maximum linear correction during one step of the non-linear position solver (default: `0.2`).
|
||||
pub max_linear_correction: Real,
|
||||
/// Maximum angular correction during one step of the non-linear position solver (default: `0.2`).
|
||||
pub max_angular_correction: Real,
|
||||
/// Maximum number of iterations performed by the velocity constraints solver (default: `4`).
|
||||
/// Maximum number of iterations performed to solve non-penetration and joint constraints (default: `4`).
|
||||
pub max_velocity_iterations: usize,
|
||||
/// Maximum number of iterations performed by the position-based constraints solver (default: `1`).
|
||||
pub max_position_iterations: usize,
|
||||
/// Maximum number of iterations performed to solve friction constraints (default: `8`).
|
||||
pub max_velocity_friction_iterations: usize,
|
||||
/// Maximum number of iterations performed to remove the energy introduced by penetration corrections (default: `1`).
|
||||
pub max_stabilization_iterations: usize,
|
||||
/// If `false`, friction and non-penetration constraints will be solved in the same loop. Otherwise,
|
||||
/// non-penetration constraints are solved first, and friction constraints are solved after (default: `true`).
|
||||
pub interleave_restitution_and_friction_resolution: bool,
|
||||
/// Minimum number of dynamic bodies in each active island (default: `128`).
|
||||
pub min_island_size: usize,
|
||||
/// Maximum number of substeps performed by the solver (default: `1`).
|
||||
@@ -64,46 +50,6 @@ pub struct IntegrationParameters {
|
||||
}
|
||||
|
||||
impl IntegrationParameters {
|
||||
/// Creates a set of integration parameters with the given values.
|
||||
#[deprecated = "Use `IntegrationParameters { dt: 60.0, ..Default::default() }` instead"]
|
||||
pub fn new(
|
||||
dt: Real,
|
||||
erp: Real,
|
||||
joint_erp: Real,
|
||||
warmstart_coeff: Real,
|
||||
allowed_linear_error: Real,
|
||||
allowed_angular_error: Real,
|
||||
max_linear_correction: Real,
|
||||
max_angular_correction: Real,
|
||||
prediction_distance: Real,
|
||||
max_velocity_iterations: usize,
|
||||
max_position_iterations: usize,
|
||||
max_ccd_substeps: usize,
|
||||
) -> Self {
|
||||
IntegrationParameters {
|
||||
dt,
|
||||
erp,
|
||||
joint_erp,
|
||||
warmstart_coeff,
|
||||
allowed_linear_error,
|
||||
allowed_angular_error,
|
||||
max_linear_correction,
|
||||
max_angular_correction,
|
||||
prediction_distance,
|
||||
max_velocity_iterations,
|
||||
max_position_iterations,
|
||||
max_ccd_substeps,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
/// The current time-stepping length.
|
||||
#[inline(always)]
|
||||
#[deprecated = "You can just read the `IntegrationParams::dt` value directly"]
|
||||
pub fn dt(&self) -> Real {
|
||||
self.dt
|
||||
}
|
||||
|
||||
/// The inverse of the time-stepping length, i.e. the steps per seconds (Hz).
|
||||
///
|
||||
/// This is zero if `self.dt` is zero.
|
||||
@@ -136,10 +82,10 @@ impl IntegrationParameters {
|
||||
}
|
||||
}
|
||||
|
||||
/// Convenience: `velocity_based_erp / dt`
|
||||
/// Convenience: `erp / dt`
|
||||
#[inline]
|
||||
pub(crate) fn velocity_based_erp_inv_dt(&self) -> Real {
|
||||
self.velocity_based_erp * self.inv_dt()
|
||||
pub(crate) fn erp_inv_dt(&self) -> Real {
|
||||
self.erp * self.inv_dt()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,20 +94,14 @@ impl Default for IntegrationParameters {
|
||||
Self {
|
||||
dt: 1.0 / 60.0,
|
||||
min_ccd_dt: 1.0 / 60.0 / 100.0,
|
||||
// multithreading_enabled: true,
|
||||
erp: 0.2,
|
||||
joint_erp: 0.2,
|
||||
velocity_solve_fraction: 1.0,
|
||||
velocity_based_erp: 0.0,
|
||||
warmstart_coeff: 1.0,
|
||||
warmstart_correction_slope: 10.0,
|
||||
allowed_linear_error: 0.005,
|
||||
erp: 0.8,
|
||||
allowed_linear_error: 0.001, // 0.005
|
||||
prediction_distance: 0.002,
|
||||
allowed_angular_error: 0.001,
|
||||
max_linear_correction: 0.2,
|
||||
max_angular_correction: 0.2,
|
||||
max_velocity_iterations: 4,
|
||||
max_position_iterations: 1,
|
||||
max_velocity_friction_iterations: 8,
|
||||
max_stabilization_iterations: 1,
|
||||
interleave_restitution_and_friction_resolution: true, // Enabling this makes a big difference for 2D stability.
|
||||
// FIXME: what is the optimal value for min_island_size?
|
||||
// It should not be too big so that we don't end up with
|
||||
// huge islands that don't fit in cache.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::data::{BundleSet, ComponentSet, ComponentSetMut, ComponentSetOption};
|
||||
use crate::dynamics::{
|
||||
JointSet, RigidBodyActivation, RigidBodyColliders, RigidBodyHandle, RigidBodyIds,
|
||||
RigidBodyType, RigidBodyVelocity,
|
||||
ImpulseJointSet, MultibodyJointSet, RigidBodyActivation, RigidBodyColliders, RigidBodyHandle,
|
||||
RigidBodyIds, RigidBodyType, RigidBodyVelocity,
|
||||
};
|
||||
use crate::geometry::{ColliderParent, NarrowPhase};
|
||||
use crate::math::Real;
|
||||
@@ -175,7 +175,8 @@ impl IslandManager {
|
||||
bodies: &mut Bodies,
|
||||
colliders: &Colliders,
|
||||
narrow_phase: &NarrowPhase,
|
||||
joints: &JointSet,
|
||||
impulse_joints: &ImpulseJointSet,
|
||||
multibody_joints: &MultibodyJointSet,
|
||||
min_island_size: usize,
|
||||
) where
|
||||
Bodies: ComponentSetMut<RigidBodyIds>
|
||||
@@ -302,11 +303,15 @@ impl IslandManager {
|
||||
// in contact or joined with this collider.
|
||||
push_contacting_bodies(rb_colliders, colliders, narrow_phase, &mut self.stack);
|
||||
|
||||
for inter in joints.joints_with(handle) {
|
||||
for inter in impulse_joints.joints_with(handle) {
|
||||
let other = crate::utils::select_other((inter.0, inter.1), handle);
|
||||
self.stack.push(other);
|
||||
}
|
||||
|
||||
for other in multibody_joints.attached_bodies(handle) {
|
||||
self.stack.push(other);
|
||||
}
|
||||
|
||||
bodies.map_mut_internal(handle.0, |activation: &mut RigidBodyActivation| {
|
||||
activation.wake_up(false);
|
||||
});
|
||||
|
||||
@@ -1,148 +0,0 @@
|
||||
use crate::dynamics::SpringModel;
|
||||
use crate::math::{Point, Real, Rotation, UnitVector, Vector};
|
||||
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
||||
/// A joint that removes all relative linear motion between a pair of points on two bodies.
|
||||
pub struct BallJoint {
|
||||
/// Where the ball joint is attached on the first body, expressed in the first body local frame.
|
||||
pub local_anchor1: Point<Real>,
|
||||
/// Where the ball joint is attached on the second body, expressed in the second body local frame.
|
||||
pub local_anchor2: Point<Real>,
|
||||
/// The impulse applied by this joint on the first body.
|
||||
///
|
||||
/// The impulse applied to the second body is given by `-impulse`.
|
||||
pub impulse: Vector<Real>,
|
||||
|
||||
/// The target relative angular velocity the motor will attempt to reach.
|
||||
#[cfg(feature = "dim2")]
|
||||
pub motor_target_vel: Real,
|
||||
/// The target relative angular velocity the motor will attempt to reach.
|
||||
#[cfg(feature = "dim3")]
|
||||
pub motor_target_vel: Vector<Real>,
|
||||
/// The target angular position of this joint, expressed as an axis-angle.
|
||||
pub motor_target_pos: Rotation<Real>,
|
||||
/// The motor's stiffness.
|
||||
/// See the documentation of `SpringModel` for more information on this parameter.
|
||||
pub motor_stiffness: Real,
|
||||
/// The motor's damping.
|
||||
/// See the documentation of `SpringModel` for more information on this parameter.
|
||||
pub motor_damping: Real,
|
||||
/// The maximal impulse the motor is able to deliver.
|
||||
pub motor_max_impulse: Real,
|
||||
/// The angular impulse applied by the motor.
|
||||
#[cfg(feature = "dim2")]
|
||||
pub motor_impulse: Real,
|
||||
/// The angular impulse applied by the motor.
|
||||
#[cfg(feature = "dim3")]
|
||||
pub motor_impulse: Vector<Real>,
|
||||
/// The spring-like model used by the motor to reach the target velocity and .
|
||||
pub motor_model: SpringModel,
|
||||
|
||||
/// Are the limits enabled for this joint?
|
||||
pub limits_enabled: bool,
|
||||
/// The axis of the limit cone for this joint, if the local-space of the first body.
|
||||
pub limits_local_axis1: UnitVector<Real>,
|
||||
/// The axis of the limit cone for this joint, if the local-space of the first body.
|
||||
pub limits_local_axis2: UnitVector<Real>,
|
||||
/// The maximum angle allowed between the two limit axes in world-space.
|
||||
pub limits_angle: Real,
|
||||
/// The impulse applied to enforce joint limits.
|
||||
pub limits_impulse: Real,
|
||||
}
|
||||
|
||||
impl BallJoint {
|
||||
/// Creates a new Ball joint from two anchors given on the local spaces of the respective bodies.
|
||||
pub fn new(local_anchor1: Point<Real>, local_anchor2: Point<Real>) -> Self {
|
||||
Self::with_impulse(local_anchor1, local_anchor2, Vector::zeros())
|
||||
}
|
||||
|
||||
pub(crate) fn with_impulse(
|
||||
local_anchor1: Point<Real>,
|
||||
local_anchor2: Point<Real>,
|
||||
impulse: Vector<Real>,
|
||||
) -> Self {
|
||||
Self {
|
||||
local_anchor1,
|
||||
local_anchor2,
|
||||
impulse,
|
||||
motor_target_vel: na::zero(),
|
||||
motor_target_pos: Rotation::identity(),
|
||||
motor_stiffness: 0.0,
|
||||
motor_damping: 0.0,
|
||||
motor_impulse: na::zero(),
|
||||
motor_max_impulse: Real::MAX,
|
||||
motor_model: SpringModel::default(),
|
||||
limits_enabled: false,
|
||||
limits_local_axis1: Vector::x_axis(),
|
||||
limits_local_axis2: Vector::x_axis(),
|
||||
limits_angle: Real::MAX,
|
||||
limits_impulse: 0.0,
|
||||
}
|
||||
}
|
||||
|
||||
/// Can a SIMD constraint be used for resolving this joint?
|
||||
pub fn supports_simd_constraints(&self) -> bool {
|
||||
// SIMD ball constraints don't support motors and limits right now.
|
||||
!self.limits_enabled
|
||||
&& (self.motor_max_impulse == 0.0
|
||||
|| (self.motor_stiffness == 0.0 && self.motor_damping == 0.0))
|
||||
}
|
||||
|
||||
/// Set the spring-like model used by the motor to reach the desired target velocity and position.
|
||||
pub fn configure_motor_model(&mut self, model: SpringModel) {
|
||||
self.motor_model = model;
|
||||
}
|
||||
|
||||
/// Sets the target velocity and velocity correction factor this motor.
|
||||
#[cfg(feature = "dim2")]
|
||||
pub fn configure_motor_velocity(&mut self, target_vel: Real, factor: Real) {
|
||||
self.configure_motor(self.motor_target_pos, target_vel, 0.0, factor)
|
||||
}
|
||||
|
||||
/// Sets the target velocity and velocity correction factor this motor.
|
||||
#[cfg(feature = "dim3")]
|
||||
pub fn configure_motor_velocity(&mut self, target_vel: Vector<Real>, factor: Real) {
|
||||
self.configure_motor(self.motor_target_pos, target_vel, 0.0, factor)
|
||||
}
|
||||
|
||||
/// Sets the target orientation this motor needs to reach.
|
||||
pub fn configure_motor_position(
|
||||
&mut self,
|
||||
target_pos: Rotation<Real>,
|
||||
stiffness: Real,
|
||||
damping: Real,
|
||||
) {
|
||||
self.configure_motor(target_pos, na::zero(), stiffness, damping)
|
||||
}
|
||||
|
||||
/// Sets the target orientation this motor needs to reach.
|
||||
#[cfg(feature = "dim2")]
|
||||
pub fn configure_motor(
|
||||
&mut self,
|
||||
target_pos: Rotation<Real>,
|
||||
target_vel: Real,
|
||||
stiffness: Real,
|
||||
damping: Real,
|
||||
) {
|
||||
self.motor_target_vel = target_vel;
|
||||
self.motor_target_pos = target_pos;
|
||||
self.motor_stiffness = stiffness;
|
||||
self.motor_damping = damping;
|
||||
}
|
||||
|
||||
/// Configure both the target orientation and target velocity of the motor.
|
||||
#[cfg(feature = "dim3")]
|
||||
pub fn configure_motor(
|
||||
&mut self,
|
||||
target_pos: Rotation<Real>,
|
||||
target_vel: Vector<Real>,
|
||||
stiffness: Real,
|
||||
damping: Real,
|
||||
) {
|
||||
self.motor_target_vel = target_vel;
|
||||
self.motor_target_pos = target_pos;
|
||||
self.motor_stiffness = stiffness;
|
||||
self.motor_damping = damping;
|
||||
}
|
||||
}
|
||||
@@ -1,38 +1,55 @@
|
||||
use crate::math::{Isometry, Real, SpacialVector};
|
||||
use crate::dynamics::{JointAxesMask, JointData};
|
||||
use crate::math::{Isometry, Point, Real};
|
||||
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
||||
/// A joint that prevents all relative movement between two bodies.
|
||||
///
|
||||
/// Given two frames of references, this joint aims to ensure these frame always coincide in world-space.
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub struct FixedJoint {
|
||||
/// The frame of reference for the first body affected by this joint, expressed in the local frame
|
||||
/// of the first body.
|
||||
pub local_frame1: Isometry<Real>,
|
||||
/// The frame of reference for the second body affected by this joint, expressed in the local frame
|
||||
/// of the first body.
|
||||
pub local_frame2: Isometry<Real>,
|
||||
/// The impulse applied to the first body affected by this joint.
|
||||
///
|
||||
/// The impulse applied to the second body affected by this joint is given by `-impulse`.
|
||||
/// This combines both linear and angular impulses:
|
||||
/// - In 2D, `impulse.xy()` gives the linear impulse, and `impulse.z` the angular impulse.
|
||||
/// - In 3D, `impulse.xyz()` gives the linear impulse, and `(impulse[3], impulse[4], impulse[5])` the angular impulse.
|
||||
pub impulse: SpacialVector<Real>,
|
||||
data: JointData,
|
||||
}
|
||||
|
||||
impl FixedJoint {
|
||||
/// Creates a new fixed joint from the frames of reference of both bodies.
|
||||
pub fn new(local_frame1: Isometry<Real>, local_frame2: Isometry<Real>) -> Self {
|
||||
Self {
|
||||
local_frame1,
|
||||
local_frame2,
|
||||
impulse: SpacialVector::zeros(),
|
||||
}
|
||||
pub fn new() -> Self {
|
||||
#[cfg(feature = "dim2")]
|
||||
let mask = JointAxesMask::X | JointAxesMask::Y | JointAxesMask::ANG_X;
|
||||
#[cfg(feature = "dim3")]
|
||||
let mask = JointAxesMask::X
|
||||
| JointAxesMask::Y
|
||||
| JointAxesMask::Z
|
||||
| JointAxesMask::ANG_X
|
||||
| JointAxesMask::ANG_Y
|
||||
| JointAxesMask::ANG_Z;
|
||||
|
||||
let data = JointData::default().lock_axes(mask);
|
||||
Self { data }
|
||||
}
|
||||
|
||||
/// Can a SIMD constraint be used for resolving this joint?
|
||||
pub fn supports_simd_constraints(&self) -> bool {
|
||||
true
|
||||
#[must_use]
|
||||
pub fn local_frame1(mut self, local_frame: Isometry<Real>) -> Self {
|
||||
self.data = self.data.local_frame1(local_frame);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn local_frame2(mut self, local_frame: Isometry<Real>) -> Self {
|
||||
self.data = self.data.local_frame2(local_frame);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn local_anchor1(mut self, anchor1: Point<Real>) -> Self {
|
||||
self.data = self.data.local_anchor1(anchor1);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn local_anchor2(mut self, anchor2: Point<Real>) -> Self {
|
||||
self.data = self.data.local_anchor2(anchor2);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<JointData> for FixedJoint {
|
||||
fn into(self) -> JointData {
|
||||
self.data
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,144 +0,0 @@
|
||||
use crate::dynamics::{BallJoint, FixedJoint, PrismaticJoint, RevoluteJoint};
|
||||
use crate::math::{Isometry, Real, SpacialVector};
|
||||
use crate::na::{Rotation3, UnitQuaternion};
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
||||
/// A joint that prevents all relative movement between two bodies.
|
||||
///
|
||||
/// Given two frames of references, this joint aims to ensure these frame always coincide in world-space.
|
||||
pub struct GenericJoint {
|
||||
/// The frame of reference for the first body affected by this joint, expressed in the local frame
|
||||
/// of the first body.
|
||||
pub local_anchor1: Isometry<Real>,
|
||||
/// The frame of reference for the second body affected by this joint, expressed in the local frame
|
||||
/// of the first body.
|
||||
pub local_anchor2: Isometry<Real>,
|
||||
/// The impulse applied to the first body affected by this joint.
|
||||
///
|
||||
/// The impulse applied to the second body affected by this joint is given by `-impulse`.
|
||||
/// This combines both linear and angular impulses:
|
||||
/// - In 2D, `impulse.xy()` gives the linear impulse, and `impulse.z` the angular impulse.
|
||||
/// - In 3D, `impulse.xyz()` gives the linear impulse, and `(impulse[3], impulse[4], impulse[5])` the angular impulse.
|
||||
pub impulse: SpacialVector<Real>,
|
||||
|
||||
pub min_position: SpacialVector<Real>,
|
||||
pub max_position: SpacialVector<Real>,
|
||||
pub min_velocity: SpacialVector<Real>,
|
||||
pub max_velocity: SpacialVector<Real>,
|
||||
/// The minimum negative impulse the joint can apply on each DoF. Must be <= 0.0
|
||||
pub min_impulse: SpacialVector<Real>,
|
||||
/// The maximum positive impulse the joint can apply on each DoF. Must be >= 0.0
|
||||
pub max_impulse: SpacialVector<Real>,
|
||||
/// The minimum negative position impulse the joint can apply on each DoF. Must be <= 0.0
|
||||
pub min_pos_impulse: SpacialVector<Real>,
|
||||
/// The maximum positive position impulse the joint can apply on each DoF. Must be >= 0.0
|
||||
pub max_pos_impulse: SpacialVector<Real>,
|
||||
}
|
||||
|
||||
impl GenericJoint {
|
||||
/// Creates a new fixed joint from the frames of reference of both bodies.
|
||||
pub fn new(local_anchor1: Isometry<Real>, local_anchor2: Isometry<Real>) -> Self {
|
||||
Self {
|
||||
local_anchor1,
|
||||
local_anchor2,
|
||||
impulse: SpacialVector::zeros(),
|
||||
min_position: SpacialVector::zeros(),
|
||||
max_position: SpacialVector::zeros(),
|
||||
min_velocity: SpacialVector::zeros(),
|
||||
max_velocity: SpacialVector::zeros(),
|
||||
min_impulse: SpacialVector::repeat(-Real::MAX),
|
||||
max_impulse: SpacialVector::repeat(Real::MAX),
|
||||
min_pos_impulse: SpacialVector::repeat(-Real::MAX),
|
||||
max_pos_impulse: SpacialVector::repeat(Real::MAX),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_dof_vel(&mut self, dof: u8, target_vel: Real, max_force: Real) {
|
||||
self.min_velocity[dof as usize] = target_vel;
|
||||
self.max_velocity[dof as usize] = target_vel;
|
||||
self.min_impulse[dof as usize] = -max_force;
|
||||
self.max_impulse[dof as usize] = max_force;
|
||||
}
|
||||
|
||||
pub fn free_dof(&mut self, dof: u8) {
|
||||
self.min_position[dof as usize] = -Real::MAX;
|
||||
self.max_position[dof as usize] = Real::MAX;
|
||||
self.min_velocity[dof as usize] = -Real::MAX;
|
||||
self.max_velocity[dof as usize] = Real::MAX;
|
||||
self.min_impulse[dof as usize] = 0.0;
|
||||
self.max_impulse[dof as usize] = 0.0;
|
||||
self.min_pos_impulse[dof as usize] = 0.0;
|
||||
self.max_pos_impulse[dof as usize] = 0.0;
|
||||
}
|
||||
|
||||
pub fn set_dof_limits(&mut self, dof: u8, min: Real, max: Real) {
|
||||
self.min_position[dof as usize] = min;
|
||||
self.max_position[dof as usize] = max;
|
||||
}
|
||||
}
|
||||
|
||||
impl From<RevoluteJoint> for GenericJoint {
|
||||
fn from(joint: RevoluteJoint) -> Self {
|
||||
let basis1 = [*joint.local_axis1, joint.basis1[0], joint.basis1[1]];
|
||||
let basis2 = [*joint.local_axis2, joint.basis2[0], joint.basis2[1]];
|
||||
let quat1 = UnitQuaternion::from_basis_unchecked(&basis1);
|
||||
let quat2 = UnitQuaternion::from_basis_unchecked(&basis2);
|
||||
let local_anchor1 = Isometry::from_parts(joint.local_anchor1.coords.into(), quat1);
|
||||
let local_anchor2 = Isometry::from_parts(joint.local_anchor2.coords.into(), quat2);
|
||||
|
||||
let mut result = Self::new(local_anchor1, local_anchor2);
|
||||
result.free_dof(3);
|
||||
|
||||
if joint.motor_damping != 0.0 {
|
||||
result.set_dof_vel(3, joint.motor_target_vel, joint.motor_max_impulse);
|
||||
}
|
||||
|
||||
result.impulse[0] = joint.impulse[0];
|
||||
result.impulse[1] = joint.impulse[1];
|
||||
result.impulse[2] = joint.impulse[2];
|
||||
result.impulse[3] = joint.motor_impulse;
|
||||
result.impulse[4] = joint.impulse[3];
|
||||
result.impulse[5] = joint.impulse[4];
|
||||
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BallJoint> for GenericJoint {
|
||||
fn from(joint: BallJoint) -> Self {
|
||||
let local_anchor1 = Isometry::new(joint.local_anchor1.coords, na::zero());
|
||||
let local_anchor2 = Isometry::new(joint.local_anchor2.coords, na::zero());
|
||||
|
||||
let mut result = Self::new(local_anchor1, local_anchor2);
|
||||
result.impulse[0] = joint.impulse[0];
|
||||
result.impulse[1] = joint.impulse[1];
|
||||
result.impulse[2] = joint.impulse[2];
|
||||
result.free_dof(3);
|
||||
result.free_dof(4);
|
||||
result.free_dof(5);
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PrismaticJoint> for GenericJoint {
|
||||
fn from(joint: PrismaticJoint) -> Self {
|
||||
let basis1 = [*joint.local_axis1, joint.basis1[0], joint.basis1[1]];
|
||||
let basis2 = [*joint.local_axis2, joint.basis2[0], joint.basis2[1]];
|
||||
let quat1 = UnitQuaternion::from_basis_unchecked(&basis1);
|
||||
let quat2 = UnitQuaternion::from_basis_unchecked(&basis2);
|
||||
let local_anchor1 = Isometry::from_parts(joint.local_anchor1.coords.into(), quat1);
|
||||
let local_anchor2 = Isometry::from_parts(joint.local_anchor2.coords.into(), quat2);
|
||||
|
||||
let mut result = Self::new(local_anchor1, local_anchor2);
|
||||
result.free_dof(0);
|
||||
result.set_dof_limits(0, joint.limits[0], joint.limits[1]);
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
impl From<FixedJoint> for GenericJoint {
|
||||
fn from(joint: FixedJoint) -> Self {
|
||||
Self::new(joint.local_anchor1, joint.local_anchor2)
|
||||
}
|
||||
}
|
||||
20
src/dynamics/joint/impulse_joint/impulse_joint.rs
Normal file
20
src/dynamics/joint/impulse_joint/impulse_joint.rs
Normal file
@@ -0,0 +1,20 @@
|
||||
use crate::dynamics::{JointData, JointHandle, RigidBodyHandle};
|
||||
use crate::math::{Real, SpacialVector};
|
||||
|
||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
/// A joint attached to two bodies.
|
||||
pub struct ImpulseJoint {
|
||||
/// Handle to the first body attached to this joint.
|
||||
pub body1: RigidBodyHandle,
|
||||
/// Handle to the second body attached to this joint.
|
||||
pub body2: RigidBodyHandle,
|
||||
|
||||
pub data: JointData,
|
||||
pub impulses: SpacialVector<Real>,
|
||||
|
||||
// A joint needs to know its handle to simplify its removal.
|
||||
pub(crate) handle: JointHandle,
|
||||
#[cfg(feature = "parallel")]
|
||||
pub(crate) constraint_index: usize,
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
use super::Joint;
|
||||
use super::ImpulseJoint;
|
||||
use crate::geometry::{InteractionGraph, RigidBodyGraphIndex, TemporaryInteractionIndex};
|
||||
|
||||
use crate::data::arena::Arena;
|
||||
use crate::data::{BundleSet, Coarena, ComponentSet, ComponentSetMut};
|
||||
use crate::dynamics::{IslandManager, RigidBodyActivation, RigidBodyIds, RigidBodyType};
|
||||
use crate::dynamics::{JointParams, RigidBodyHandle};
|
||||
use crate::dynamics::{JointData, RigidBodyHandle};
|
||||
|
||||
/// The unique identifier of a joint added to the joint set.
|
||||
/// The unique identifier of a collider added to a collider set.
|
||||
@@ -34,19 +34,19 @@ impl JointHandle {
|
||||
}
|
||||
|
||||
pub(crate) type JointIndex = usize;
|
||||
pub(crate) type JointGraphEdge = crate::data::graph::Edge<Joint>;
|
||||
pub(crate) type JointGraphEdge = crate::data::graph::Edge<ImpulseJoint>;
|
||||
|
||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
||||
#[derive(Clone, Default)]
|
||||
/// A set of joints that can be handled by a physics `World`.
|
||||
pub struct JointSet {
|
||||
/// A set of impulse_joints that can be handled by a physics `World`.
|
||||
pub struct ImpulseJointSet {
|
||||
rb_graph_ids: Coarena<RigidBodyGraphIndex>,
|
||||
joint_ids: Arena<TemporaryInteractionIndex>, // Map joint handles to edge ids on the graph.
|
||||
joint_graph: InteractionGraph<RigidBodyHandle, Joint>,
|
||||
joint_graph: InteractionGraph<RigidBodyHandle, ImpulseJoint>,
|
||||
}
|
||||
|
||||
impl JointSet {
|
||||
/// Creates a new empty set of joints.
|
||||
impl ImpulseJointSet {
|
||||
/// Creates a new empty set of impulse_joints.
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
rb_graph_ids: Coarena::new(),
|
||||
@@ -55,26 +55,26 @@ impl JointSet {
|
||||
}
|
||||
}
|
||||
|
||||
/// The number of joints on this set.
|
||||
/// The number of impulse_joints on this set.
|
||||
pub fn len(&self) -> usize {
|
||||
self.joint_graph.graph.edges.len()
|
||||
}
|
||||
|
||||
/// `true` if there are no joints in this set.
|
||||
/// `true` if there are no impulse_joints in this set.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.joint_graph.graph.edges.is_empty()
|
||||
}
|
||||
|
||||
/// Retrieve the joint graph where edges are joints and nodes are rigid body handles.
|
||||
pub fn joint_graph(&self) -> &InteractionGraph<RigidBodyHandle, Joint> {
|
||||
/// Retrieve the joint graph where edges are impulse_joints and nodes are rigid body handles.
|
||||
pub fn joint_graph(&self) -> &InteractionGraph<RigidBodyHandle, ImpulseJoint> {
|
||||
&self.joint_graph
|
||||
}
|
||||
|
||||
/// Iterates through all the joitns attached to the given rigid-body.
|
||||
/// Iterates through all the impulse_joints attached to the given rigid-body.
|
||||
pub fn joints_with<'a>(
|
||||
&'a self,
|
||||
body: RigidBodyHandle,
|
||||
) -> impl Iterator<Item = (RigidBodyHandle, RigidBodyHandle, &'a Joint)> {
|
||||
) -> impl Iterator<Item = (RigidBodyHandle, RigidBodyHandle, &'a ImpulseJoint)> {
|
||||
self.rb_graph_ids
|
||||
.get(body.0)
|
||||
.into_iter()
|
||||
@@ -87,13 +87,13 @@ impl JointSet {
|
||||
}
|
||||
|
||||
/// Gets the joint with the given handle.
|
||||
pub fn get(&self, handle: JointHandle) -> Option<&Joint> {
|
||||
pub fn get(&self, handle: JointHandle) -> Option<&ImpulseJoint> {
|
||||
let id = self.joint_ids.get(handle.0)?;
|
||||
self.joint_graph.graph.edge_weight(*id)
|
||||
}
|
||||
|
||||
/// Gets a mutable reference to the joint with the given handle.
|
||||
pub fn get_mut(&mut self, handle: JointHandle) -> Option<&mut Joint> {
|
||||
pub fn get_mut(&mut self, handle: JointHandle) -> Option<&mut ImpulseJoint> {
|
||||
let id = self.joint_ids.get(handle.0)?;
|
||||
self.joint_graph.graph.edge_weight_mut(*id)
|
||||
}
|
||||
@@ -107,7 +107,7 @@ impl JointSet {
|
||||
///
|
||||
/// Using this is discouraged in favor of `self.get(handle)` which does not
|
||||
/// suffer form the ABA problem.
|
||||
pub fn get_unknown_gen(&self, i: u32) -> Option<(&Joint, JointHandle)> {
|
||||
pub fn get_unknown_gen(&self, i: u32) -> Option<(&ImpulseJoint, JointHandle)> {
|
||||
let (id, handle) = self.joint_ids.get_unknown_gen(i)?;
|
||||
Some((
|
||||
self.joint_graph.graph.edge_weight(*id)?,
|
||||
@@ -124,7 +124,7 @@ impl JointSet {
|
||||
///
|
||||
/// Using this is discouraged in favor of `self.get_mut(handle)` which does not
|
||||
/// suffer form the ABA problem.
|
||||
pub fn get_unknown_gen_mut(&mut self, i: u32) -> Option<(&mut Joint, JointHandle)> {
|
||||
pub fn get_unknown_gen_mut(&mut self, i: u32) -> Option<(&mut ImpulseJoint, JointHandle)> {
|
||||
let (id, handle) = self.joint_ids.get_unknown_gen(i)?;
|
||||
Some((
|
||||
self.joint_graph.graph.edge_weight_mut(*id)?,
|
||||
@@ -133,7 +133,7 @@ impl JointSet {
|
||||
}
|
||||
|
||||
/// Iterates through all the joint on this set.
|
||||
pub fn iter(&self) -> impl Iterator<Item = (JointHandle, &Joint)> {
|
||||
pub fn iter(&self) -> impl Iterator<Item = (JointHandle, &ImpulseJoint)> {
|
||||
self.joint_graph
|
||||
.graph
|
||||
.edges
|
||||
@@ -142,7 +142,7 @@ impl JointSet {
|
||||
}
|
||||
|
||||
/// Iterates mutably through all the joint on this set.
|
||||
pub fn iter_mut(&mut self) -> impl Iterator<Item = (JointHandle, &mut Joint)> {
|
||||
pub fn iter_mut(&mut self) -> impl Iterator<Item = (JointHandle, &mut ImpulseJoint)> {
|
||||
self.joint_graph
|
||||
.graph
|
||||
.edges
|
||||
@@ -150,8 +150,8 @@ impl JointSet {
|
||||
.map(|e| (e.weight.handle, &mut e.weight))
|
||||
}
|
||||
|
||||
// /// The set of joints as an array.
|
||||
// pub(crate) fn joints(&self) -> &[JointGraphEdge] {
|
||||
// /// The set of impulse_joints as an array.
|
||||
// pub(crate) fn impulse_joints(&self) -> &[JointGraphEdge] {
|
||||
// // self.joint_graph
|
||||
// // .graph
|
||||
// // .edges
|
||||
@@ -170,25 +170,22 @@ impl JointSet {
|
||||
}
|
||||
|
||||
/// Inserts a new joint into this set and retrieve its handle.
|
||||
pub fn insert<J>(
|
||||
pub fn insert(
|
||||
&mut self,
|
||||
body1: RigidBodyHandle,
|
||||
body2: RigidBodyHandle,
|
||||
joint_params: J,
|
||||
) -> JointHandle
|
||||
where
|
||||
J: Into<JointParams>,
|
||||
{
|
||||
data: impl Into<JointData>,
|
||||
) -> JointHandle {
|
||||
let data = data.into();
|
||||
let handle = self.joint_ids.insert(0.into());
|
||||
let joint = Joint {
|
||||
let joint = ImpulseJoint {
|
||||
body1,
|
||||
body2,
|
||||
data,
|
||||
impulses: na::zero(),
|
||||
handle: JointHandle(handle),
|
||||
#[cfg(feature = "parallel")]
|
||||
constraint_index: 0,
|
||||
#[cfg(feature = "parallel")]
|
||||
position_constraint_index: 0,
|
||||
params: joint_params.into(),
|
||||
};
|
||||
|
||||
let default_id = InteractionGraph::<(), ()>::invalid_graph_index();
|
||||
@@ -201,12 +198,12 @@ impl JointSet {
|
||||
|
||||
// NOTE: the body won't have a graph index if it does not
|
||||
// have any joint attached.
|
||||
if !InteractionGraph::<RigidBodyHandle, Joint>::is_graph_index_valid(graph_index1) {
|
||||
if !InteractionGraph::<RigidBodyHandle, ImpulseJoint>::is_graph_index_valid(graph_index1) {
|
||||
graph_index1 = self.joint_graph.graph.add_node(joint.body1);
|
||||
self.rb_graph_ids.insert(joint.body1.0, graph_index1);
|
||||
}
|
||||
|
||||
if !InteractionGraph::<RigidBodyHandle, Joint>::is_graph_index_valid(graph_index2) {
|
||||
if !InteractionGraph::<RigidBodyHandle, ImpulseJoint>::is_graph_index_valid(graph_index2) {
|
||||
graph_index2 = self.joint_graph.graph.add_node(joint.body2);
|
||||
self.rb_graph_ids.insert(joint.body2.0, graph_index2);
|
||||
}
|
||||
@@ -215,7 +212,7 @@ impl JointSet {
|
||||
JointHandle(handle)
|
||||
}
|
||||
|
||||
/// Retrieve all the joints happening between two active bodies.
|
||||
/// Retrieve all the impulse_joints happening between two active bodies.
|
||||
// NOTE: this is very similar to the code from NarrowPhase::select_active_interactions.
|
||||
pub(crate) fn select_active_interactions<Bodies>(
|
||||
&self,
|
||||
@@ -271,7 +268,7 @@ impl JointSet {
|
||||
islands: &mut IslandManager,
|
||||
bodies: &mut Bodies,
|
||||
wake_up: bool,
|
||||
) -> Option<Joint>
|
||||
) -> Option<ImpulseJoint>
|
||||
where
|
||||
Bodies: ComponentSetMut<RigidBodyActivation>
|
||||
+ ComponentSet<RigidBodyType>
|
||||
@@ -299,11 +296,11 @@ impl JointSet {
|
||||
removed_joint
|
||||
}
|
||||
|
||||
/// Deletes all the joints attached to the given rigid-body.
|
||||
/// Deletes all the impulse_joints attached to the given rigid-body.
|
||||
///
|
||||
/// The provided rigid-body handle is not required to identify a rigid-body that
|
||||
/// is still contained by the `bodies` component set.
|
||||
/// Returns the (now invalid) handles of the removed joints.
|
||||
/// Returns the (now invalid) handles of the removed impulse_joints.
|
||||
pub fn remove_joints_attached_to_rigid_body<Bodies>(
|
||||
&mut self,
|
||||
handle: RigidBodyHandle,
|
||||
6
src/dynamics/joint/impulse_joint/mod.rs
Normal file
6
src/dynamics/joint/impulse_joint/mod.rs
Normal file
@@ -0,0 +1,6 @@
|
||||
pub use self::impulse_joint::ImpulseJoint;
|
||||
pub use self::impulse_joint_set::{ImpulseJointSet, JointHandle};
|
||||
pub(crate) use self::impulse_joint_set::{JointGraphEdge, JointIndex};
|
||||
|
||||
mod impulse_joint;
|
||||
mod impulse_joint_set;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user