Split rigid-bodies and colliders into multiple components
This commit is contained in:
@@ -38,7 +38,12 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
// Remove then re-add the ground collider.
|
||||
let coll = physics
|
||||
.colliders
|
||||
.remove(ground_collider_handle, &mut physics.bodies, true)
|
||||
.remove(
|
||||
ground_collider_handle,
|
||||
&mut physics.islands,
|
||||
&mut physics.bodies,
|
||||
true,
|
||||
)
|
||||
.unwrap();
|
||||
ground_collider_handle = physics
|
||||
.colliders
|
||||
|
||||
@@ -79,7 +79,9 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
step = snapped_frame;
|
||||
|
||||
for handle in &extra_colliders {
|
||||
physics.colliders.remove(*handle, &mut physics.bodies, true);
|
||||
physics
|
||||
.colliders
|
||||
.remove(*handle, &mut physics.islands, &mut physics.bodies, true);
|
||||
}
|
||||
|
||||
extra_colliders.clear();
|
||||
|
||||
@@ -61,9 +61,12 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
|
||||
let num_to_remove = to_remove.len() - MAX_NUMBER_OF_BODIES;
|
||||
for (handle, _) in &to_remove[..num_to_remove] {
|
||||
physics
|
||||
.bodies
|
||||
.remove(*handle, &mut physics.colliders, &mut physics.joints);
|
||||
physics.bodies.remove(
|
||||
*handle,
|
||||
&mut physics.islands,
|
||||
&mut physics.colliders,
|
||||
&mut physics.joints,
|
||||
);
|
||||
|
||||
if let (Some(graphics), Some(window)) = (&mut graphics, &mut window) {
|
||||
graphics.remove_body_nodes(window, *handle);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use na::{Isometry3, Point3, Unit, UnitQuaternion, Vector3};
|
||||
use rapier3d::dynamics::{
|
||||
BallJoint, BodyStatus, FixedJoint, JointSet, PrismaticJoint, RevoluteJoint, RigidBodyBuilder,
|
||||
RigidBodyHandle, RigidBodySet,
|
||||
BallJoint, FixedJoint, JointSet, PrismaticJoint, RevoluteJoint, RigidBodyBuilder,
|
||||
RigidBodyHandle, RigidBodySet, RigidBodyType,
|
||||
};
|
||||
use rapier3d::geometry::{ColliderBuilder, ColliderSet};
|
||||
use rapier_testbed3d::Testbed;
|
||||
@@ -203,9 +203,9 @@ fn create_fixed_joints(
|
||||
// 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) {
|
||||
BodyStatus::Static
|
||||
RigidBodyType::Static
|
||||
} else {
|
||||
BodyStatus::Dynamic
|
||||
RigidBodyType::Dynamic
|
||||
};
|
||||
|
||||
let rigid_body = RigidBodyBuilder::new(status)
|
||||
@@ -258,9 +258,9 @@ fn create_ball_joints(
|
||||
let fi = i as f32;
|
||||
|
||||
let status = if i == 0 && (k % 4 == 0 || k == num - 1) {
|
||||
BodyStatus::Static
|
||||
RigidBodyType::Static
|
||||
} else {
|
||||
BodyStatus::Dynamic
|
||||
RigidBodyType::Dynamic
|
||||
};
|
||||
|
||||
let rigid_body = RigidBodyBuilder::new(status)
|
||||
@@ -317,9 +317,9 @@ fn create_actuated_revolute_joints(
|
||||
// fixed bodies. Because physx will crash if we add
|
||||
// a joint between these.
|
||||
let status = if i == 0 {
|
||||
BodyStatus::Static
|
||||
RigidBodyType::Static
|
||||
} else {
|
||||
BodyStatus::Dynamic
|
||||
RigidBodyType::Dynamic
|
||||
};
|
||||
|
||||
let shifty = (i >= 1) as u32 as f32 * -2.0;
|
||||
@@ -378,9 +378,9 @@ fn create_actuated_ball_joints(
|
||||
// fixed bodies. Because physx will crash if we add
|
||||
// a joint between these.
|
||||
let status = if i == 0 {
|
||||
BodyStatus::Static
|
||||
RigidBodyType::Static
|
||||
} else {
|
||||
BodyStatus::Dynamic
|
||||
RigidBodyType::Dynamic
|
||||
};
|
||||
|
||||
let rigid_body = RigidBodyBuilder::new(status)
|
||||
|
||||
@@ -9,36 +9,39 @@ struct OneWayPlatformHook {
|
||||
platform2: ColliderHandle,
|
||||
}
|
||||
|
||||
impl PhysicsHooks for OneWayPlatformHook {
|
||||
impl PhysicsHooks<RigidBodySet, ColliderSet> for OneWayPlatformHook {
|
||||
fn active_hooks(&self) -> PhysicsHooksFlags {
|
||||
PhysicsHooksFlags::MODIFY_SOLVER_CONTACTS
|
||||
}
|
||||
|
||||
fn modify_solver_contacts(&self, context: &mut ContactModificationContext) {
|
||||
fn modify_solver_contacts(
|
||||
&self,
|
||||
context: &mut ContactModificationContext<RigidBodySet, ColliderSet>,
|
||||
) {
|
||||
// The allowed normal for the first platform is its local +y axis, and the
|
||||
// allowed normal for the second platform is its local -y axis.
|
||||
//
|
||||
// Now we have to be careful because the `manifold.local_n1` normal points
|
||||
// toward the outside of the shape of `context.co1`. So we need to flip the
|
||||
// allowed normal direction if the platform is in `context.collider_handle2`.
|
||||
// allowed normal direction if the platform is in `context.collider2`.
|
||||
//
|
||||
// Therefore:
|
||||
// - If context.collider_handle1 == self.platform1 then the allowed normal is +y.
|
||||
// - If context.collider_handle2 == self.platform1 then the allowed normal is -y.
|
||||
// - If context.collider_handle1 == self.platform2 then its allowed normal +y needs to be flipped to -y.
|
||||
// - If context.collider_handle2 == self.platform2 then the allowed normal -y needs to be flipped to +y.
|
||||
// - If context.collider1 == self.platform1 then the allowed normal is +y.
|
||||
// - If context.collider2 == self.platform1 then the allowed normal is -y.
|
||||
// - If context.collider1 == self.platform2 then its allowed normal +y needs to be flipped to -y.
|
||||
// - If context.collider2 == self.platform2 then the allowed normal -y needs to be flipped to +y.
|
||||
let mut allowed_local_n1 = Vector3::zeros();
|
||||
|
||||
if context.collider_handle1 == self.platform1 {
|
||||
if context.collider1 == self.platform1 {
|
||||
allowed_local_n1 = Vector3::y();
|
||||
} else if context.collider_handle2 == self.platform1 {
|
||||
} else if context.collider2 == self.platform1 {
|
||||
// Flip the allowed direction.
|
||||
allowed_local_n1 = -Vector3::y();
|
||||
}
|
||||
|
||||
if context.collider_handle1 == self.platform2 {
|
||||
if context.collider1 == self.platform2 {
|
||||
allowed_local_n1 = -Vector3::y();
|
||||
} else if context.collider_handle2 == self.platform2 {
|
||||
} else if context.collider2 == self.platform2 {
|
||||
// Flip the allowed direction.
|
||||
allowed_local_n1 = Vector3::y();
|
||||
}
|
||||
@@ -47,13 +50,12 @@ impl PhysicsHooks for OneWayPlatformHook {
|
||||
context.update_as_oneway_platform(&allowed_local_n1, 0.1);
|
||||
|
||||
// Set the surface velocity of the accepted contacts.
|
||||
let tangent_velocity = if context.collider_handle1 == self.platform1
|
||||
|| context.collider_handle2 == self.platform2
|
||||
{
|
||||
-12.0
|
||||
} else {
|
||||
12.0
|
||||
};
|
||||
let tangent_velocity =
|
||||
if context.collider1 == self.platform1 || context.collider2 == self.platform2 {
|
||||
-12.0
|
||||
} else {
|
||||
12.0
|
||||
};
|
||||
|
||||
for contact in context.solver_contacts.iter_mut() {
|
||||
contact.tangent_velocity.z = tangent_velocity;
|
||||
@@ -115,13 +117,14 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
}
|
||||
}
|
||||
|
||||
physics.bodies.foreach_active_dynamic_body_mut(|_, body| {
|
||||
for handle in physics.islands.active_dynamic_bodies() {
|
||||
let body = physics.bodies.get_mut(*handle).unwrap();
|
||||
if body.position().translation.y > 1.0 {
|
||||
body.set_gravity_scale(1.0, false);
|
||||
} else if body.position().translation.y < -1.0 {
|
||||
body.set_gravity_scale(-1.0, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use na::Point3;
|
||||
use na::{Isometry3, Point3, UnitQuaternion, Vector3};
|
||||
use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet};
|
||||
use rapier3d::geometry::{ColliderBuilder, ColliderSet};
|
||||
use rapier_testbed3d::Testbed;
|
||||
@@ -14,7 +14,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Ground.
|
||||
*/
|
||||
let ground_size = 10.0;
|
||||
let ground_size = 20.0;
|
||||
let ground_height = 0.1;
|
||||
|
||||
let rigid_body = RigidBodyBuilder::new_static()
|
||||
@@ -27,25 +27,28 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
/*
|
||||
* Create the boxes
|
||||
*/
|
||||
let num = 6;
|
||||
let num = 1;
|
||||
let rad = 0.2;
|
||||
|
||||
let shift = rad * 2.0;
|
||||
let centerx = shift * num as f32 / 2.0;
|
||||
let centery = shift / 2.0 + 3.04;
|
||||
let centery = shift / 2.0;
|
||||
let centerz = shift * num as f32 / 2.0;
|
||||
|
||||
for i in 0usize..num {
|
||||
for i in 0usize..20 {
|
||||
for j in 0usize..num {
|
||||
for k in 0usize..num {
|
||||
let x = i as f32 * shift - centerx;
|
||||
let x = i as f32 * (shift + rad / 4.0) - centerx;
|
||||
let y = j as f32 * shift + centery;
|
||||
let z = k as f32 * shift - centerz;
|
||||
|
||||
// Build the rigid body.
|
||||
let rigid_body = RigidBodyBuilder::new_dynamic().translation(x, y, z).build();
|
||||
let rigid_body = RigidBodyBuilder::new_dynamic()
|
||||
.translation(x, y + rad, z)
|
||||
.ccd_enabled(true)
|
||||
.build();
|
||||
let handle = bodies.insert(rigid_body);
|
||||
let collider = ColliderBuilder::cuboid(rad, rad, rad).build();
|
||||
let collider = ColliderBuilder::cuboid(rad, rad * 2.0, rad).build();
|
||||
colliders.insert(collider, handle, &mut bodies);
|
||||
}
|
||||
}
|
||||
@@ -55,11 +58,16 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
* Setup a kinematic rigid body.
|
||||
*/
|
||||
let platform_body = RigidBodyBuilder::new_kinematic()
|
||||
.translation(0.0, 1.5 + 0.8, -10.0 * rad)
|
||||
.translation(0.2, 0.4, -40.0 * rad)
|
||||
.build();
|
||||
let platform_handle = bodies.insert(platform_body);
|
||||
let collider = ColliderBuilder::cuboid(rad * 10.0, rad, rad * 10.0).build();
|
||||
colliders.insert(collider, platform_handle, &mut bodies);
|
||||
let collider1 = ColliderBuilder::cuboid(rad * 5.0, rad * 2.0, rad * 10.0).build();
|
||||
let collider2 = ColliderBuilder::cuboid(rad * 5.0, rad * 2.0, rad * 10.0)
|
||||
.position_wrt_parent(Isometry3::translation(0.0, rad * 2.1, 0.0))
|
||||
.build();
|
||||
colliders.insert(collider1, platform_handle, &mut bodies);
|
||||
colliders.insert(collider2, platform_handle, &mut bodies);
|
||||
testbed.set_body_color(platform_handle, Point3::new(1.0, 1.0, 0.0));
|
||||
|
||||
/*
|
||||
* Setup a callback to control the platform.
|
||||
@@ -67,23 +75,27 @@ pub fn init_world(testbed: &mut Testbed) {
|
||||
let mut count = 0;
|
||||
testbed.add_callback(move |_, _, physics, _, run_state| {
|
||||
count += 1;
|
||||
if count % 100 > 50 {
|
||||
return;
|
||||
}
|
||||
// if count % 100 > 50 {
|
||||
// return;
|
||||
// }
|
||||
|
||||
if let Some(platform) = physics.bodies.get_mut(platform_handle) {
|
||||
let mut next_pos = *platform.position();
|
||||
|
||||
let dt = 0.016;
|
||||
next_pos.translation.vector.y += (run_state.time * 5.0).sin() * dt;
|
||||
next_pos.translation.vector.z += run_state.time.sin() * 5.0 * dt;
|
||||
// next_pos.translation.vector.y += (run_state.time * 5.0).sin() * dt;
|
||||
// next_pos.translation.vector.z += run_state.time.sin() * 5.0 * dt;
|
||||
|
||||
if next_pos.translation.vector.z >= rad * 10.0 {
|
||||
next_pos.translation.vector.z -= dt;
|
||||
}
|
||||
if next_pos.translation.vector.z <= -rad * 10.0 {
|
||||
next_pos.translation.vector.z += dt;
|
||||
}
|
||||
let drot = UnitQuaternion::new(Vector3::y() * 0.01);
|
||||
next_pos.rotation = drot * next_pos.rotation;
|
||||
next_pos.translation.vector += next_pos.rotation * Vector3::z() * 0.1;
|
||||
|
||||
// if next_pos.translation.vector.z >= rad * 10.0 {
|
||||
// next_pos.translation.vector.z -= dt;
|
||||
// }
|
||||
// if next_pos.translation.vector.z <= -rad * 10.0 {
|
||||
// next_pos.translation.vector.z += dt;
|
||||
// }
|
||||
|
||||
platform.set_next_kinematic_position(next_pos);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user