aboutsummaryrefslogtreecommitdiff
path: root/src_testbed
diff options
context:
space:
mode:
authorRobert Hrusecky <robert.hrusecky@utexas.edu>2020-10-29 18:09:41 -0500
committerRobert Hrusecky <robert.hrusecky@utexas.edu>2020-10-29 18:09:41 -0500
commitbcec54ef31d987cf20b493628a20777183a95f65 (patch)
treecee40c0467c04f1f02861342e20ce8223ca6d99b /src_testbed
parentdd8e25bc4756b8bd01d283b5d7e7c5daa9a1af3f (diff)
parent4b8242b9c267a9412c88793575db37f79c544ca2 (diff)
downloadrapier-bcec54ef31d987cf20b493628a20777183a95f65.tar.gz
rapier-bcec54ef31d987cf20b493628a20777183a95f65.tar.bz2
rapier-bcec54ef31d987cf20b493628a20777183a95f65.zip
Merge branch 'master' into infinite_fall_memory
Fix merge conflict resulting from "axii" spelling correction
Diffstat (limited to 'src_testbed')
-rw-r--r--src_testbed/box2d_backend.rs76
-rw-r--r--src_testbed/engine.rs95
-rw-r--r--src_testbed/nphysics_backend.rs51
-rw-r--r--src_testbed/objects/cone.rs74
-rw-r--r--src_testbed/objects/cylinder.rs74
-rw-r--r--src_testbed/objects/mod.rs2
-rw-r--r--src_testbed/objects/node.rs18
-rw-r--r--src_testbed/physx_backend.rs45
-rw-r--r--src_testbed/testbed.rs27
9 files changed, 352 insertions, 110 deletions
diff --git a/src_testbed/box2d_backend.rs b/src_testbed/box2d_backend.rs
index c25ff1f..769b12d 100644
--- a/src_testbed/box2d_backend.rs
+++ b/src_testbed/box2d_backend.rs
@@ -5,7 +5,7 @@ use rapier::counters::Counters;
use rapier::dynamics::{
IntegrationParameters, JointParams, JointSet, RigidBodyHandle, RigidBodySet,
};
-use rapier::geometry::{Collider, ColliderSet, Shape};
+use rapier::geometry::{Collider, ColliderSet};
use std::f32;
use wrapped2d::b2;
@@ -167,44 +167,42 @@ impl Box2dWorld {
fixture_def.is_sensor = collider.is_sensor();
fixture_def.filter = b2::Filter::new();
- match collider.shape() {
- Shape::Ball(b) => {
- let mut b2_shape = b2::CircleShape::new();
- b2_shape.set_radius(b.radius);
- b2_shape.set_position(center);
- body.create_fixture(&b2_shape, &mut fixture_def);
- }
- Shape::Cuboid(c) => {
- let b2_shape = b2::PolygonShape::new_box(c.half_extents.x, c.half_extents.y);
- body.create_fixture(&b2_shape, &mut fixture_def);
- }
- Shape::Polygon(poly) => {
- let points: Vec<_> = poly
- .vertices()
- .iter()
- .map(|p| collider.position_wrt_parent() * p)
- .map(|p| na_vec_to_b2_vec(p.coords))
- .collect();
- let b2_shape = b2::PolygonShape::new_with(&points);
- body.create_fixture(&b2_shape, &mut fixture_def);
- }
- Shape::HeightField(heightfield) => {
- let mut segments = heightfield.segments();
- let seg1 = segments.next().unwrap();
- let mut vertices = vec![
- na_vec_to_b2_vec(seg1.a.coords),
- na_vec_to_b2_vec(seg1.b.coords),
- ];
-
- // TODO: this will not handle holes properly.
- segments.for_each(|seg| {
- vertices.push(na_vec_to_b2_vec(seg.b.coords));
- });
-
- let b2_shape = b2::ChainShape::new_chain(&vertices);
- body.create_fixture(&b2_shape, &mut fixture_def);
- }
- _ => eprintln!("Creating a shape unknown to the Box2d backend."),
+ let shape = collider.shape();
+
+ if let Some(b) = shape.as_ball() {
+ let mut b2_shape = b2::CircleShape::new();
+ b2_shape.set_radius(b.radius);
+ b2_shape.set_position(center);
+ body.create_fixture(&b2_shape, &mut fixture_def);
+ } else if let Some(c) = shape.as_cuboid() {
+ let b2_shape = b2::PolygonShape::new_box(c.half_extents.x, c.half_extents.y);
+ body.create_fixture(&b2_shape, &mut fixture_def);
+ // } else if let Some(polygon) = shape.as_polygon() {
+ // let points: Vec<_> = poly
+ // .vertices()
+ // .iter()
+ // .map(|p| collider.position_wrt_parent() * p)
+ // .map(|p| na_vec_to_b2_vec(p.coords))
+ // .collect();
+ // let b2_shape = b2::PolygonShape::new_with(&points);
+ // body.create_fixture(&b2_shape, &mut fixture_def);
+ } else if let Some(heightfield) = shape.as_heightfield() {
+ let mut segments = heightfield.segments();
+ let seg1 = segments.next().unwrap();
+ let mut vertices = vec![
+ na_vec_to_b2_vec(seg1.a.coords),
+ na_vec_to_b2_vec(seg1.b.coords),
+ ];
+
+ // TODO: this will not handle holes properly.
+ segments.for_each(|seg| {
+ vertices.push(na_vec_to_b2_vec(seg.b.coords));
+ });
+
+ let b2_shape = b2::ChainShape::new_chain(&vertices);
+ body.create_fixture(&b2_shape, &mut fixture_def);
+ } else {
+ eprintln!("Creating a shape unknown to the Box2d backend.");
}
}
diff --git a/src_testbed/engine.rs b/src_testbed/engine.rs
index 217da48..1bafdb6 100644
--- a/src_testbed/engine.rs
+++ b/src_testbed/engine.rs
@@ -9,11 +9,10 @@ use na::Point3;
use crate::math::Point;
use crate::objects::ball::Ball;
use crate::objects::box_node::Box as BoxNode;
-use crate::objects::convex::Convex;
use crate::objects::heightfield::HeightField;
use crate::objects::node::{GraphicsNode, Node};
use rapier::dynamics::{RigidBodyHandle, RigidBodySet};
-use rapier::geometry::{Collider, ColliderHandle, ColliderSet, Shape};
+use rapier::geometry::{Collider, ColliderHandle, ColliderSet};
//use crate::objects::capsule::Capsule;
//use crate::objects::convex::Convex;
//#[cfg(feature = "fluids")]
@@ -26,6 +25,10 @@ use rapier::geometry::{Collider, ColliderHandle, ColliderSet, Shape};
//#[cfg(feature = "fluids")]
//use crate::objects::FluidRenderingMode;
use crate::objects::capsule::Capsule;
+#[cfg(feature = "dim3")]
+use crate::objects::cone::Cone;
+#[cfg(feature = "dim3")]
+use crate::objects::cylinder::Cylinder;
use crate::objects::mesh::Mesh;
use rand::{Rng, SeedableRng};
use rand_pcg::Pcg32;
@@ -60,6 +63,7 @@ pub struct GraphicsManager {
#[cfg(feature = "fluids")]
boundary2sn: HashMap<BoundaryHandle, FluidNode>,
b2color: HashMap<RigidBodyHandle, Point3<f32>>,
+ c2color: HashMap<ColliderHandle, Point3<f32>>,
b2wireframe: HashMap<RigidBodyHandle, bool>,
#[cfg(feature = "fluids")]
f2color: HashMap<FluidHandle, Point3<f32>>,
@@ -97,6 +101,7 @@ impl GraphicsManager {
#[cfg(feature = "fluids")]
boundary2sn: HashMap::new(),
b2color: HashMap::new(),
+ c2color: HashMap::new(),
#[cfg(feature = "fluids")]
f2color: HashMap::new(),
ground_color: Point3::new(0.5, 0.5, 0.5),
@@ -183,6 +188,10 @@ impl GraphicsManager {
}
}
+ pub fn set_collider_initial_color(&mut self, c: ColliderHandle, color: Point3<f32>) {
+ self.c2color.insert(c, color);
+ }
+
pub fn set_body_wireframe(&mut self, b: RigidBodyHandle, enabled: bool) {
self.b2wireframe.insert(b, enabled);
@@ -321,6 +330,7 @@ impl GraphicsManager {
let mut new_nodes = Vec::new();
for collider_handle in bodies[handle].colliders() {
+ let color = self.c2color.get(collider_handle).copied().unwrap_or(color);
let collider = &colliders[*collider_handle];
self.add_collider(window, *collider_handle, collider, color, &mut new_nodes);
}
@@ -349,33 +359,44 @@ impl GraphicsManager {
color: Point3<f32>,
out: &mut Vec<Node>,
) {
- match collider.shape() {
- Shape::Ball(ball) => {
- out.push(Node::Ball(Ball::new(handle, ball.radius, color, window)))
- }
- Shape::Polygon(poly) => out.push(Node::Convex(Convex::new(
- handle,
- poly.vertices().to_vec(),
- color,
- window,
- ))),
- Shape::Cuboid(cuboid) => out.push(Node::Box(BoxNode::new(
+ let shape = collider.shape();
+
+ if let Some(ball) = shape.as_ball() {
+ out.push(Node::Ball(Ball::new(handle, ball.radius, color, window)))
+ }
+
+ // Shape::Polygon(poly) => out.push(Node::Convex(Convex::new(
+ // handle,
+ // poly.vertices().to_vec(),
+ // color,
+ // window,
+ // ))),
+
+ if let Some(cuboid) = shape.as_cuboid() {
+ out.push(Node::Box(BoxNode::new(
handle,
cuboid.half_extents,
color,
window,
- ))),
- Shape::Capsule(capsule) => {
- out.push(Node::Capsule(Capsule::new(handle, capsule, color, window)))
- }
- Shape::Triangle(triangle) => out.push(Node::Mesh(Mesh::new(
+ )))
+ }
+
+ if let Some(capsule) = shape.as_capsule() {
+ out.push(Node::Capsule(Capsule::new(handle, capsule, color, window)))
+ }
+
+ if let Some(triangle) = shape.as_triangle() {
+ out.push(Node::Mesh(Mesh::new(
handle,
vec![triangle.a, triangle.b, triangle.c],
vec![Point3::new(0, 1, 2)],
color,
window,
- ))),
- Shape::Trimesh(trimesh) => out.push(Node::Mesh(Mesh::new(
+ )))
+ }
+
+ if let Some(trimesh) = shape.as_trimesh() {
+ out.push(Node::Mesh(Mesh::new(
handle,
trimesh.vertices().to_vec(),
trimesh
@@ -385,13 +406,41 @@ impl GraphicsManager {
.collect(),
color,
window,
- ))),
- Shape::HeightField(heightfield) => out.push(Node::HeightField(HeightField::new(
+ )))
+ }
+
+ if let Some(heightfield) = shape.as_heightfield() {
+ out.push(Node::HeightField(HeightField::new(
handle,
heightfield,
color,
window,
- ))),
+ )))
+ }
+
+ #[cfg(feature = "dim3")]
+ if let Some(cylinder) = shape
+ .as_cylinder()
+ .or(shape.as_round_cylinder().map(|r| &r.cylinder))
+ {
+ out.push(Node::Cylinder(Cylinder::new(
+ handle,
+ cylinder.half_height,
+ cylinder.radius,
+ color,
+ window,
+ )))
+ }
+
+ #[cfg(feature = "dim3")]
+ if let Some(cone) = shape.as_cone() {
+ out.push(Node::Cone(Cone::new(
+ handle,
+ cone.half_height,
+ cone.radius,
+ color,
+ window,
+ )))
}
}
diff --git a/src_testbed/nphysics_backend.rs b/src_testbed/nphysics_backend.rs
index c2a7fb1..3a0e487 100644
--- a/src_testbed/nphysics_backend.rs
+++ b/src_testbed/nphysics_backend.rs
@@ -12,7 +12,7 @@ use rapier::counters::Counters;
use rapier::dynamics::{
IntegrationParameters, JointParams, JointSet, RigidBodyHandle, RigidBodySet,
};
-use rapier::geometry::{Collider, ColliderSet, Shape};
+use rapier::geometry::{Collider, ColliderSet};
use rapier::math::Vector;
use std::collections::HashMap;
#[cfg(feature = "dim3")]
@@ -177,28 +177,37 @@ fn nphysics_collider_from_rapier_collider(
) -> Option<ColliderDesc<f32>> {
let margin = ColliderDesc::<f32>::default_margin();
let mut pos = *collider.position_wrt_parent();
-
- let shape = match collider.shape() {
- Shape::Cuboid(cuboid) => {
- ShapeHandle::new(Cuboid::new(cuboid.half_extents.map(|e| e - margin)))
+ let shape = collider.shape();
+
+ let shape = if let Some(cuboid) = shape.as_cuboid() {
+ ShapeHandle::new(Cuboid::new(cuboid.half_extents.map(|e| e - margin)))
+ } else if let Some(ball) = shape.as_ball() {
+ ShapeHandle::new(Ball::new(ball.radius - margin))
+ } else if let Some(capsule) = shape.as_capsule() {
+ pos *= capsule.transform_wrt_y();
+ ShapeHandle::new(Capsule::new(capsule.half_height(), capsule.radius))
+ } else if let Some(heightfield) = shape.as_heightfield() {
+ ShapeHandle::new(heightfield.clone())
+ } else {
+ #[cfg(feature = "dim3")]
+ if let Some(trimesh) = shape.as_trimesh() {
+ ShapeHandle::new(TriMesh::new(
+ trimesh.vertices().to_vec(),
+ trimesh
+ .indices()
+ .iter()
+ .map(|idx| na::convert(*idx))
+ .collect(),
+ None,
+ ))
+ } else {
+ return None;
}
- Shape::Ball(ball) => ShapeHandle::new(Ball::new(ball.radius - margin)),
- Shape::Capsule(capsule) => {
- pos *= capsule.transform_wrt_y();
- ShapeHandle::new(Capsule::new(capsule.half_height(), capsule.radius))
+
+ #[cfg(feature = "dim2")]
+ {
+ return None;
}
- Shape::HeightField(heightfield) => ShapeHandle::new(heightfield.clone()),
- #[cfg(feature = "dim3")]
- Shape::Trimesh(trimesh) => ShapeHandle::new(TriMesh::new(
- trimesh.vertices().to_vec(),
- trimesh
- .indices()
- .iter()
- .map(|idx| na::convert(*idx))
- .collect(),
- None,
- )),
- _ => return None,
};
let density = if is_dynamic { collider.density() } else { 0.0 };
diff --git a/src_testbed/objects/cone.rs b/src_testbed/objects/cone.rs
new file mode 100644
index 0000000..58b014f
--- /dev/null
+++ b/src_testbed/objects/cone.rs
@@ -0,0 +1,74 @@
+use crate::objects::node::{self, GraphicsNode};
+use kiss3d::window::Window;
+use na::Point3;
+use rapier::geometry::{ColliderHandle, ColliderSet};
+use rapier::math::Isometry;
+
+pub struct Cone {
+ color: Point3<f32>,
+ base_color: Point3<f32>,
+ gfx: GraphicsNode,
+ collider: ColliderHandle,
+}
+
+impl Cone {
+ pub fn new(
+ collider: ColliderHandle,
+ half_height: f32,
+ radius: f32,
+ color: Point3<f32>,
+ window: &mut Window,
+ ) -> Cone {
+ #[cfg(feature = "dim2")]
+ let node = window.add_rectangle(radius, half_height);
+ #[cfg(feature = "dim3")]
+ let node = window.add_cone(radius, half_height * 2.0);
+
+ let mut res = Cone {
+ color,
+ base_color: color,
+ gfx: node,
+ collider,
+ };
+
+ // res.gfx.set_texture_from_file(&Path::new("media/kitten.png"), "kitten");
+ res.gfx.set_color(color.x, color.y, color.z);
+ res
+ }
+
+ pub fn select(&mut self) {
+ self.color = Point3::new(1.0, 0.0, 0.0);
+ }
+
+ pub fn unselect(&mut self) {
+ self.color = self.base_color;
+ }
+
+ pub fn set_color(&mut self, color: Point3<f32>) {
+ self.gfx.set_color(color.x, color.y, color.z);
+ self.color = color;
+ self.base_color = color;
+ }
+
+ pub fn update(&mut self, colliders: &ColliderSet) {
+ node::update_scene_node(
+ &mut self.gfx,
+ colliders,
+ self.collider,
+ &self.color,
+ &Isometry::identity(),
+ );
+ }
+
+ pub fn scene_node(&self) -> &GraphicsNode {
+ &self.gfx
+ }
+
+ pub fn scene_node_mut(&mut self) -> &mut GraphicsNode {
+ &mut self.gfx
+ }
+
+ pub fn object(&self) -> ColliderHandle {
+ self.collider
+ }
+}
diff --git a/src_testbed/objects/cylinder.rs b/src_testbed/objects/cylinder.rs
new file mode 100644
index 0000000..01a6737
--- /dev/null
+++ b/src_testbed/objects/cylinder.rs
@@ -0,0 +1,74 @@
+use crate::objects::node::{self, GraphicsNode};
+use kiss3d::window::Window;
+use na::Point3;
+use rapier::geometry::{ColliderHandle, ColliderSet};
+use rapier::math::Isometry;
+
+pub struct Cylinder {
+ color: Point3<f32>,
+ base_color: Point3<f32>,
+ gfx: GraphicsNode,
+ collider: ColliderHandle,
+}
+
+impl Cylinder {
+ pub fn new(
+ collider: ColliderHandle,
+ half_height: f32,
+ radius: f32,
+ color: Point3<f32>,
+ window: &mut Window,
+ ) -> Cylinder {
+ #[cfg(feature = "dim2")]
+ let node = window.add_rectangle(radius, half_height);
+ #[cfg(feature = "dim3")]
+ let node = window.add_cylinder(radius, half_height * 2.0);
+
+ let mut res = Cylinder {
+ color,
+ base_color: color,
+ gfx: node,
+ collider,
+ };
+
+ // res.gfx.set_texture_from_file(&Path::new("media/kitten.png"), "kitten");
+ res.gfx.set_color(color.x, color.y, color.z);
+ res
+ }
+
+ pub fn select(&mut self) {
+ self.color = Point3::new(1.0, 0.0, 0.0);
+ }
+
+ pub fn unselect(&mut self) {
+ self.color = self.base_color;
+ }
+
+ pub fn set_color(&mut self, color: Point3<f32>) {
+ self.gfx.set_color(color.x, color.y, color.z);
+ self.color = color;
+ self.base_color = color;
+ }
+
+ pub fn update(&mut self, colliders: &ColliderSet) {
+ node::update_scene_node(
+ &mut self.gfx,
+ colliders,
+ self.collider,
+ &self.color,
+ &Isometry::identity(),
+ );
+ }
+
+ pub fn scene_node(&self) -> &GraphicsNode {
+ &self.gfx
+ }
+
+ pub fn scene_node_mut(&mut self) -> &mut GraphicsNode {
+ &mut self.gfx
+ }
+
+ pub fn object(&self) -> ColliderHandle {
+ self.collider
+ }
+}
diff --git a/src_testbed/objects/mod.rs b/src_testbed/objects/mod.rs
index 82895b3..e4d7bc4 100644
--- a/src_testbed/objects/mod.rs
+++ b/src_testbed/objects/mod.rs
@@ -1,7 +1,9 @@
pub mod ball;
pub mod box_node;
pub mod capsule;
+pub mod cone;
pub mod convex;
+pub mod cylinder;
pub mod heightfield;
pub mod mesh;
pub mod node;
diff --git a/src_testbed/objects/node.rs b/src_testbed/objects/node.rs
index 93b5eac..d1de799 100644
--- a/src_testbed/objects/node.rs
+++ b/src_testbed/objects/node.rs
@@ -10,6 +10,8 @@ use crate::objects::mesh::Mesh;
use kiss3d::window::Window;
use na::Point3;
+use crate::objects::cone::Cone;
+use crate::objects::cylinder::Cylinder;
use rapier::geometry::{ColliderHandle, ColliderSet};
use rapier::math::Isometry;
@@ -28,6 +30,8 @@ pub enum Node {
// Polyline(Polyline),
Mesh(Mesh),
Convex(Convex),
+ Cylinder(Cylinder),
+ Cone(Cone),
}
impl Node {
@@ -42,6 +46,8 @@ impl Node {
// Node::Polyline(ref mut n) => n.select(),
Node::Mesh(ref mut n) => n.select(),
Node::Convex(ref mut n) => n.select(),
+ Node::Cylinder(ref mut n) => n.select(),
+ Node::Cone(ref mut n) => n.select(),
}
}
@@ -56,6 +62,8 @@ impl Node {
// Node::Polyline(ref mut n) => n.unselect(),
Node::Mesh(ref mut n) => n.unselect(),
Node::Convex(ref mut n) => n.unselect(),
+ Node::Cylinder(ref mut n) => n.unselect(),
+ Node::Cone(ref mut n) => n.unselect(),
}
}
@@ -70,6 +78,8 @@ impl Node {
// Node::Polyline(ref mut n) => n.update(colliders),
Node::Mesh(ref mut n) => n.update(colliders),
Node::Convex(ref mut n) => n.update(colliders),
+ Node::Cylinder(ref mut n) => n.update(colliders),
+ Node::Cone(ref mut n) => n.update(colliders),
}
}
@@ -97,6 +107,8 @@ impl Node {
Node::HeightField(ref n) => Some(n.scene_node()),
Node::Mesh(ref n) => Some(n.scene_node()),
Node::Convex(ref n) => Some(n.scene_node()),
+ Node::Cylinder(ref n) => Some(n.scene_node()),
+ Node::Cone(ref n) => Some(n.scene_node()),
#[cfg(feature = "dim2")]
_ => None,
}
@@ -113,6 +125,8 @@ impl Node {
Node::HeightField(ref mut n) => Some(n.scene_node_mut()),
Node::Mesh(ref mut n) => Some(n.scene_node_mut()),
Node::Convex(ref mut n) => Some(n.scene_node_mut()),
+ Node::Cylinder(ref mut n) => Some(n.scene_node_mut()),
+ Node::Cone(ref mut n) => Some(n.scene_node_mut()),
#[cfg(feature = "dim2")]
_ => None,
}
@@ -129,6 +143,8 @@ impl Node {
// Node::Polyline(ref n) => n.object(),
Node::Mesh(ref n) => n.object(),
Node::Convex(ref n) => n.object(),
+ Node::Cylinder(ref n) => n.object(),
+ Node::Cone(ref n) => n.object(),
}
}
@@ -143,6 +159,8 @@ impl Node {
// Node::Polyline(ref mut n) => n.set_color(color),
Node::Mesh(ref mut n) => n.set_color(color),
Node::Convex(ref mut n) => n.set_color(color),
+ Node::Cylinder(ref mut n) => n.set_color(color),
+ Node::Cone(ref mut n) => n.set_color(color),
}
}
}
diff --git a/src_testbed/physx_backend.rs b/src_testbed/physx_backend.rs
index ec2e2bf..74d6af2 100644
--- a/src_testbed/physx_backend.rs
+++ b/src_testbed/physx_backend.rs
@@ -6,7 +6,7 @@ use rapier::counters::Counters;
use rapier::dynamics::{
IntegrationParameters, JointParams, JointSet, RigidBodyHandle, RigidBodySet,
};
-use rapier::geometry::{Collider, ColliderSet, Shape};
+use rapier::geometry::{Collider, ColliderSet};
use rapier::utils::WBasis;
use std::collections::HashMap;
@@ -422,27 +422,29 @@ fn physx_collider_from_rapier_collider(
collider: &Collider,
) -> Option<(ColliderDesc, Isometry3<f32>)> {
let mut local_pose = *collider.position_wrt_parent();
- let desc = match collider.shape() {
- Shape::Cuboid(cuboid) => ColliderDesc::Box(
+ let shape = collider.shape();
+
+ let desc = if let Some(cuboid) = shape.as_cuboid() {
+ ColliderDesc::Box(
cuboid.half_extents.x,
cuboid.half_extents.y,
cuboid.half_extents.z,
- ),
- Shape::Ball(ball) => ColliderDesc::Sphere(ball.radius),
- Shape::Capsule(capsule) => {
- let center = capsule.center();
- let mut dir = capsule.b - capsule.a;
-
- if dir.x < 0.0 {
- dir = -dir;
- }
-
- let rot = UnitQuaternion::rotation_between(&Vector3::x(), &dir);
- local_pose *=
- Translation3::from(center.coords) * rot.unwrap_or(UnitQuaternion::identity());
- ColliderDesc::Capsule(capsule.radius, capsule.height())
+ )
+ } else if let Some(ball) = shape.as_ball() {
+ ColliderDesc::Sphere(ball.radius)
+ } else if let Some(capsule) = shape.as_capsule() {
+ let center = capsule.center();
+ let mut dir = capsule.segment.b - capsule.segment.a;
+
+ if dir.x < 0.0 {
+ dir = -dir;
}
- Shape::Trimesh(trimesh) => ColliderDesc::TriMesh {
+
+ let rot = UnitQuaternion::rotation_between(&Vector3::x(), &dir);
+ local_pose *= Translation3::from(center.coords) * rot.unwrap_or(UnitQuaternion::identity());
+ ColliderDesc::Capsule(capsule.radius, capsule.height())
+ } else if let Some(trimesh) = shape.as_trimesh() {
+ ColliderDesc::TriMesh {
vertices: trimesh
.vertices()
.iter()
@@ -450,11 +452,10 @@ fn physx_collider_from_rapier_collider(
.collect(),
indices: trimesh.flat_indices().to_vec(),
mesh_scale: Vector3::repeat(1.0).into_glam(),
- },
- _ => {
- eprintln!("Creating a shape unknown to the PhysX backend.");
- return None;
}
+ } else {
+ eprintln!("Creating a shape unknown to the PhysX backend.");
+ return None;
};
Some((desc, local_pose))
diff --git a/src_testbed/testbed.rs b/src_testbed/testbed.rs
index 3d7fd7d..3bf720a 100644
--- a/src_testbed/testbed.rs
+++ b/src_testbed/testbed.rs
@@ -21,7 +21,12 @@ use na::{self, Point2, Point3, Vector3};
use rapier::dynamics::{
ActivationStatus, IntegrationParameters, JointSet, RigidBodyHandle, RigidBodySet,
};
-use rapier::geometry::{BroadPhase, ColliderSet, ContactEvent, NarrowPhase, ProximityEvent, Ray};
+#[cfg(feature = "dim3")]
+use rapier::geometry::Ray;
+use rapier::geometry::{
+ BroadPhase, ColliderHandle, ColliderSet, ContactEvent, InteractionGroups, NarrowPhase,
+ ProximityEvent,
+};
use rapier::math::Vector;
use rapier::pipeline::{ChannelEventCollector, PhysicsPipeline, QueryPipeline};
#[cfg(feature = "fluids")]
@@ -495,6 +500,10 @@ impl Testbed {
self.graphics.set_body_color(body, color);
}
+ pub fn set_collider_initial_color(&mut self, collider: ColliderHandle, color: Point3<f32>) {
+ self.graphics.set_collider_initial_color(collider, color);
+ }
+
#[cfg(feature = "fluids")]
pub fn set_fluid_color(&mut self, fluid: FluidHandle, color: Point3<f32>) {
self.graphics.set_fluid_color(fluid, color);
@@ -672,6 +681,8 @@ impl Testbed {
&mut self.physics.bodies,
&mut self.physics.colliders,
&mut self.physics.joints,
+ None,
+ None,
&self.event_handler,
);
@@ -1180,10 +1191,12 @@ impl Testbed {
.camera()
.unproject(&self.cursor_pos, &na::convert(size));
let ray = Ray::new(pos, dir);
- let hit = self
- .physics
- .query_pipeline
- .cast_ray(&self.physics.colliders, &ray, f32::MAX);
+ let hit = self.physics.query_pipeline.cast_ray(
+ &self.physics.colliders,
+ &ray,
+ f32::MAX,
+ InteractionGroups::all(),
+ );
if let Some((_, collider, _)) = hit {
if self.physics.bodies[collider.parent()].is_dynamic() {
@@ -1446,6 +1459,8 @@ impl State for Testbed {
&mut physics.bodies,
&mut physics.colliders,
&mut physics.joints,
+ None,
+ None,
event_handler,
);
});
@@ -1460,6 +1475,8 @@ impl State for Testbed {
&mut self.physics.bodies,
&mut self.physics.colliders,
&mut self.physics.joints,
+ None,
+ None,
&self.event_handler,
);