aboutsummaryrefslogtreecommitdiff
path: root/src_testbed
diff options
context:
space:
mode:
Diffstat (limited to 'src_testbed')
-rw-r--r--src_testbed/box2d_backend.rs8
-rw-r--r--src_testbed/engine.rs106
-rw-r--r--src_testbed/harness/mod.rs2
-rw-r--r--src_testbed/lib.rs4
-rw-r--r--src_testbed/nphysics_backend.rs27
-rw-r--r--src_testbed/objects/ball.rs5
-rw-r--r--src_testbed/objects/box_node.rs5
-rw-r--r--src_testbed/objects/capsule.rs5
-rw-r--r--src_testbed/objects/cone.rs5
-rw-r--r--src_testbed/objects/convex.rs23
-rw-r--r--src_testbed/objects/cylinder.rs5
-rw-r--r--src_testbed/objects/heightfield.rs28
-rw-r--r--src_testbed/objects/mesh.rs7
-rw-r--r--src_testbed/objects/polyline.rs2
-rw-r--r--src_testbed/physics/mod.rs6
-rw-r--r--src_testbed/physx_backend.rs758
-rw-r--r--src_testbed/testbed.rs25
17 files changed, 601 insertions, 420 deletions
diff --git a/src_testbed/box2d_backend.rs b/src_testbed/box2d_backend.rs
index 941c6d5..29fd4fa 100644
--- a/src_testbed/box2d_backend.rs
+++ b/src_testbed/box2d_backend.rs
@@ -174,6 +174,14 @@ impl Box2dWorld {
b2_shape.set_radius(b.radius);
b2_shape.set_position(center);
body.create_fixture(&b2_shape, &mut fixture_def);
+ } else if let Some(p) = shape.as_convex_polygon() {
+ let vertices: Vec<_> = p
+ .points()
+ .iter()
+ .map(|p| na_vec_to_b2_vec(p.coords))
+ .collect();
+ let b2_shape = b2::PolygonShape::new_with(&vertices);
+ 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);
diff --git a/src_testbed/engine.rs b/src_testbed/engine.rs
index 040c883..cef12d6 100644
--- a/src_testbed/engine.rs
+++ b/src_testbed/engine.rs
@@ -6,15 +6,15 @@ use kiss3d::window::Window;
use na::Point3;
-use crate::math::Point;
+use crate::math::{Isometry, Point};
use crate::objects::ball::Ball;
use crate::objects::box_node::Box as BoxNode;
use crate::objects::heightfield::HeightField;
use crate::objects::node::{GraphicsNode, Node};
use rapier::dynamics::{RigidBodyHandle, RigidBodySet};
-use rapier::geometry::{Collider, ColliderHandle, ColliderSet};
+use rapier::geometry::{ColliderHandle, ColliderSet, Shape};
//use crate::objects::capsule::Capsule;
-//use crate::objects::convex::Convex;
+use crate::objects::convex::Convex;
//#[cfg(feature = "dim3")]
//use crate::objects::mesh::Mesh;
//use crate::objects::plane::Plane;
@@ -237,7 +237,14 @@ impl GraphicsManager {
for collider_handle in bodies[handle].colliders() {
let color = self.c2color.get(collider_handle).copied().unwrap_or(color);
let collider = &colliders[*collider_handle];
- self.do_add_collider(window, *collider_handle, collider, color, &mut new_nodes);
+ self.do_add_shape(
+ window,
+ *collider_handle,
+ collider.shape(),
+ &Isometry::identity(),
+ color,
+ &mut new_nodes,
+ );
}
new_nodes.iter_mut().for_each(|n| n.update(colliders));
@@ -267,34 +274,49 @@ impl GraphicsManager {
let color = self.c2color.get(&handle).copied().unwrap_or(color);
let mut nodes =
std::mem::replace(self.b2sn.get_mut(&collider.parent()).unwrap(), Vec::new());
- self.do_add_collider(window, handle, collider, color, &mut nodes);
+ self.do_add_shape(
+ window,
+ handle,
+ collider.shape(),
+ &Isometry::identity(),
+ color,
+ &mut nodes,
+ );
self.b2sn.insert(collider.parent(), nodes);
}
- fn do_add_collider(
+ fn do_add_shape(
&mut self,
window: &mut Window,
handle: ColliderHandle,
- collider: &Collider,
+ shape: &dyn Shape,
+ delta: &Isometry<f32>,
color: Point3<f32>,
out: &mut Vec<Node>,
) {
- let shape = collider.shape();
+ if let Some(compound) = shape.as_compound() {
+ for (shape_pos, shape) in compound.shapes() {
+ self.do_add_shape(window, handle, &**shape, shape_pos, color, out)
+ }
+ }
if let Some(ball) = shape.as_ball() {
- out.push(Node::Ball(Ball::new(handle, ball.radius, color, window)))
+ out.push(Node::Ball(Ball::new(
+ handle,
+ *delta,
+ 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() {
+ if let Some(cuboid) = shape
+ .as_cuboid()
+ .or(shape.as_round_cuboid().map(|r| &r.base_shape))
+ {
out.push(Node::Box(BoxNode::new(
handle,
+ *delta,
cuboid.half_extents,
color,
window,
@@ -302,14 +324,19 @@ impl GraphicsManager {
}
if let Some(capsule) = shape.as_capsule() {
- out.push(Node::Capsule(Capsule::new(handle, capsule, color, window)))
+ out.push(Node::Capsule(Capsule::new(
+ handle, *delta, capsule, color, window,
+ )))
}
- if let Some(triangle) = shape.as_triangle() {
+ if let Some(triangle) = shape
+ .as_triangle()
+ .or(shape.as_round_triangle().map(|r| &r.base_shape))
+ {
out.push(Node::Mesh(Mesh::new(
handle,
vec![triangle.a, triangle.b, triangle.c],
- vec![Point3::new(0, 1, 2)],
+ vec![[0, 1, 2]],
color,
window,
)))
@@ -319,11 +346,7 @@ impl GraphicsManager {
out.push(Node::Mesh(Mesh::new(
handle,
trimesh.vertices().to_vec(),
- trimesh
- .indices()
- .iter()
- .map(|idx| na::convert(*idx))
- .collect(),
+ trimesh.indices().to_vec(),
color,
window,
)))
@@ -338,13 +361,36 @@ impl GraphicsManager {
)))
}
+ #[cfg(feature = "dim2")]
+ if let Some(convex_polygon) = shape
+ .as_convex_polygon()
+ .or(shape.as_round_convex_polygon().map(|r| &r.base_shape))
+ {
+ let vertices = convex_polygon.points().to_vec();
+ out.push(Node::Convex(Convex::new(
+ handle, *delta, vertices, color, window,
+ )))
+ }
+
+ #[cfg(feature = "dim3")]
+ if let Some(convex_polyhedron) = shape
+ .as_convex_polyhedron()
+ .or(shape.as_round_convex_polyhedron().map(|r| &r.base_shape))
+ {
+ let (vertices, indices) = convex_polyhedron.to_trimesh();
+ out.push(Node::Convex(Convex::new(
+ handle, *delta, vertices, indices, color, window,
+ )))
+ }
+
#[cfg(feature = "dim3")]
if let Some(cylinder) = shape
.as_cylinder()
- .or(shape.as_round_cylinder().map(|r| &r.cylinder))
+ .or(shape.as_round_cylinder().map(|r| &r.base_shape))
{
out.push(Node::Cylinder(Cylinder::new(
handle,
+ *delta,
cylinder.half_height,
cylinder.radius,
color,
@@ -353,9 +399,13 @@ impl GraphicsManager {
}
#[cfg(feature = "dim3")]
- if let Some(cone) = shape.as_cone() {
+ if let Some(cone) = shape
+ .as_cone()
+ .or(shape.as_round_cone().map(|r| &r.base_shape))
+ {
out.push(Node::Cone(Cone::new(
handle,
+ *delta,
cone.half_height,
cone.radius,
color,
@@ -501,7 +551,7 @@ impl GraphicsManager {
object: DefaultColliderHandle,
colliders: &DefaultColliderSet<f32>,
delta: Isometry<f32>,
- shape: &Cuboid<f32>,
+ shape: &Cuboid,
color: Point3<f32>,
out: &mut Vec<Node>,
) {
diff --git a/src_testbed/harness/mod.rs b/src_testbed/harness/mod.rs
index 2251038..413ef52 100644
--- a/src_testbed/harness/mod.rs
+++ b/src_testbed/harness/mod.rs
@@ -81,7 +81,7 @@ impl Harness {
let event_handler = ChannelEventCollector::new(proximity_channel.0, contact_channel.0);
let events = PhysicsEvents {
contact_events: contact_channel.1,
- proximity_events: proximity_channel.1,
+ intersection_events: proximity_channel.1,
};
let physics = PhysicsState::new();
let state = RunState::new();
diff --git a/src_testbed/lib.rs b/src_testbed/lib.rs
index 5358e7c..d6ea1c3 100644
--- a/src_testbed/lib.rs
+++ b/src_testbed/lib.rs
@@ -1,5 +1,9 @@
#[macro_use]
extern crate kiss3d;
+#[cfg(feature = "dim2")]
+extern crate cdl2d as cdl;
+#[cfg(feature = "dim3")]
+extern crate cdl3d as cdl;
extern crate nalgebra as na;
#[cfg(feature = "dim2")]
extern crate ncollide2d as ncollide;
diff --git a/src_testbed/nphysics_backend.rs b/src_testbed/nphysics_backend.rs
index d988904..8b88e28 100644
--- a/src_testbed/nphysics_backend.rs
+++ b/src_testbed/nphysics_backend.rs
@@ -1,4 +1,6 @@
-use ncollide::shape::{Ball, Capsule, Cuboid, ShapeHandle};
+#[cfg(feature = "dim2")]
+use ncollide::shape::ConvexPolygon;
+use ncollide::shape::{Ball, Capsule, Cuboid, HeightField, ShapeHandle};
use nphysics::force_generator::DefaultForceGeneratorSet;
use nphysics::joint::{
DefaultJointConstraintSet, FixedConstraint, PrismaticConstraint, RevoluteConstraint,
@@ -144,6 +146,7 @@ impl NPhysicsWorld {
self.mechanical_world
.integration_parameters
.set_dt(params.dt);
+ self.mechanical_world.integration_parameters.warmstart_coeff = params.warmstart_coeff;
counters.step_started();
self.mechanical_world.step(
@@ -175,19 +178,25 @@ fn nphysics_collider_from_rapier_collider(
collider: &Collider,
is_dynamic: bool,
) -> Option<ColliderDesc<f32>> {
- let margin = ColliderDesc::<f32>::default_margin();
+ let mut margin = ColliderDesc::<f32>::default_margin();
let mut pos = *collider.position_wrt_parent();
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(cuboid) = shape.as_round_cuboid() {
+ margin = cuboid.border_radius;
+ ShapeHandle::new(Cuboid::new(cuboid.base_shape.half_extents))
} 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())
+ let heights = heightfield.heights();
+ let scale = heightfield.scale();
+ let heightfield = HeightField::new(heights.clone(), *scale);
+ ShapeHandle::new(heightfield)
} else {
#[cfg(feature = "dim3")]
if let Some(trimesh) = shape.as_trimesh() {
@@ -196,7 +205,7 @@ fn nphysics_collider_from_rapier_collider(
trimesh
.indices()
.iter()
- .map(|idx| na::convert(*idx))
+ .map(|idx| na::Point3::new(idx[0] as usize, idx[1] as usize, idx[2] as usize))
.collect(),
None,
))
@@ -205,7 +214,12 @@ fn nphysics_collider_from_rapier_collider(
}
#[cfg(feature = "dim2")]
- {
+ if let Some(polygon) = shape.as_round_convex_polygon() {
+ margin = polygon.border_radius;
+ ShapeHandle::new(ConvexPolygon::try_from_points(polygon.base_shape.points()).unwrap())
+ } else if let Some(polygon) = shape.as_convex_polygon() {
+ ShapeHandle::new(ConvexPolygon::try_from_points(polygon.points()).unwrap())
+ } else {
return None;
}
};
@@ -216,6 +230,7 @@ fn nphysics_collider_from_rapier_collider(
ColliderDesc::new(shape)
.position(pos)
.density(density)
- .sensor(collider.is_sensor()),
+ .sensor(collider.is_sensor())
+ .margin(margin),
)
}
diff --git a/src_testbed/objects/ball.rs b/src_testbed/objects/ball.rs
index f72c284..df43341 100644
--- a/src_testbed/objects/ball.rs
+++ b/src_testbed/objects/ball.rs
@@ -9,11 +9,13 @@ pub struct Ball {
base_color: Point3<f32>,
gfx: GraphicsNode,
collider: ColliderHandle,
+ delta: Isometry<f32>,
}
impl Ball {
pub fn new(
collider: ColliderHandle,
+ delta: Isometry<f32>,
radius: f32,
color: Point3<f32>,
window: &mut Window,
@@ -28,6 +30,7 @@ impl Ball {
base_color: color,
gfx: node,
collider,
+ delta,
};
// res.gfx.set_texture_from_file(&Path::new("media/kitten.png"), "kitten");
@@ -55,7 +58,7 @@ impl Ball {
colliders,
self.collider,
&self.color,
- &Isometry::identity(),
+ &self.delta,
);
}
diff --git a/src_testbed/objects/box_node.rs b/src_testbed/objects/box_node.rs
index 493ffba..0586d77 100644
--- a/src_testbed/objects/box_node.rs
+++ b/src_testbed/objects/box_node.rs
@@ -9,11 +9,13 @@ pub struct Box {
base_color: Point3<f32>,
gfx: GraphicsNode,
collider: ColliderHandle,
+ delta: Isometry<f32>,
}
impl Box {
pub fn new(
collider: ColliderHandle,
+ delta: Isometry<f32>,
half_extents: Vector<f32>,
color: Point3<f32>,
window: &mut window::Window,
@@ -29,6 +31,7 @@ impl Box {
base_color: color,
gfx: node,
collider,
+ delta,
};
res.gfx.set_color(color.x, color.y, color.z);
@@ -55,7 +58,7 @@ impl Box {
colliders,
self.collider,
&self.color,
- &Isometry::identity(),
+ &self.delta,
);
}
diff --git a/src_testbed/objects/capsule.rs b/src_testbed/objects/capsule.rs
index 23160be..3d3e88f 100644
--- a/src_testbed/objects/capsule.rs
+++ b/src_testbed/objects/capsule.rs
@@ -9,11 +9,13 @@ pub struct Capsule {
base_color: Point3<f32>,
gfx: GraphicsNode,
collider: ColliderHandle,
+ delta: Isometry<f32>,
}
impl Capsule {
pub fn new(
collider: ColliderHandle,
+ delta: Isometry<f32>,
capsule: &geometry::Capsule,
color: Point3<f32>,
window: &mut window::Window,
@@ -30,6 +32,7 @@ impl Capsule {
base_color: color,
gfx: node,
collider,
+ delta: delta * capsule.transform_wrt_y(),
};
res.gfx.set_color(color.x, color.y, color.z);
@@ -50,7 +53,7 @@ impl Capsule {
colliders,
self.collider,
&self.color,
- &Isometry::identity(),
+ &self.delta,
);
}
diff --git a/src_testbed/objects/cone.rs b/src_testbed/objects/cone.rs
index 58b014f..7aa2039 100644
--- a/src_testbed/objects/cone.rs
+++ b/src_testbed/objects/cone.rs
@@ -9,11 +9,13 @@ pub struct Cone {
base_color: Point3<f32>,
gfx: GraphicsNode,
collider: ColliderHandle,
+ delta: Isometry<f32>,
}
impl Cone {
pub fn new(
collider: ColliderHandle,
+ delta: Isometry<f32>,
half_height: f32,
radius: f32,
color: Point3<f32>,
@@ -29,6 +31,7 @@ impl Cone {
base_color: color,
gfx: node,
collider,
+ delta,
};
// res.gfx.set_texture_from_file(&Path::new("media/kitten.png"), "kitten");
@@ -56,7 +59,7 @@ impl Cone {
colliders,
self.collider,
&self.color,
- &Isometry::identity(),
+ &self.delta,
);
}
diff --git a/src_testbed/objects/convex.rs b/src_testbed/objects/convex.rs
index 0347144..95ef74a 100644
--- a/src_testbed/objects/convex.rs
+++ b/src_testbed/objects/convex.rs
@@ -13,25 +13,44 @@ pub struct Convex {
base_color: Point3<f32>,
gfx: GraphicsNode,
body: ColliderHandle,
+ delta: Isometry<f32>,
}
impl Convex {
pub fn new(
body: ColliderHandle,
+ delta: Isometry<f32>,
vertices: Vec<Point<f32>>,
+ #[cfg(feature = "dim3")] indices: Vec<[u32; 3]>,
color: Point3<f32>,
window: &mut Window,
) -> Convex {
#[cfg(feature = "dim2")]
let node = window.add_convex_polygon(vertices, Vector::from_element(1.0));
#[cfg(feature = "dim3")]
- let node = unimplemented!();
+ let node = {
+ use std::cell::RefCell;
+ use std::rc::Rc;
+ let mut mesh_vertices = Vec::new();
+ let mut mesh_indices = Vec::new();
+ for idx in indices {
+ let i = mesh_vertices.len() as u16;
+ mesh_vertices.push(vertices[idx[0] as usize]);
+ mesh_vertices.push(vertices[idx[1] as usize]);
+ mesh_vertices.push(vertices[idx[2] as usize]);
+ mesh_indices.push(Point3::new(i, i + 1, i + 2));
+ }
+
+ let mesh = kiss3d::resource::Mesh::new(mesh_vertices, mesh_indices, None, None, false);
+ window.add_mesh(Rc::new(RefCell::new(mesh)), na::Vector3::from_element(1.0))
+ };
let mut res = Convex {
color,
base_color: color,
gfx: node,
body,
+ delta,
};
// res.gfx.set_texture_from_file(&Path::new("media/kitten.png"), "kitten");
@@ -59,7 +78,7 @@ impl Convex {
colliders,
self.body,
&self.color,
- &Isometry::identity(),
+ &self.delta,
);
}
diff --git a/src_testbed/objects/cylinder.rs b/src_testbed/objects/cylinder.rs
index 01a6737..ff4dc72 100644
--- a/src_testbed/objects/cylinder.rs
+++ b/src_testbed/objects/cylinder.rs
@@ -9,11 +9,13 @@ pub struct Cylinder {
base_color: Point3<f32>,
gfx: GraphicsNode,
collider: ColliderHandle,
+ delta: Isometry<f32>,
}
impl Cylinder {
pub fn new(
collider: ColliderHandle,
+ delta: Isometry<f32>,
half_height: f32,
radius: f32,
color: Point3<f32>,
@@ -29,6 +31,7 @@ impl Cylinder {
base_color: color,
gfx: node,
collider,
+ delta,
};
// res.gfx.set_texture_from_file(&Path::new("media/kitten.png"), "kitten");
@@ -56,7 +59,7 @@ impl Cylinder {
colliders,
self.collider,
&self.color,
- &Isometry::identity(),
+ &self.delta,
);
}
diff --git a/src_testbed/objects/heightfield.rs b/src_testbed/objects/heightfield.rs
index 0815592..cb5edf3 100644
--- a/src_testbed/objects/heightfield.rs
+++ b/src_testbed/objects/heightfield.rs
@@ -1,15 +1,16 @@
-#[cfg(feature = "dim3")]
-use crate::objects::node::{self, GraphicsNode};
+use cdl::shape;
use kiss3d::window::Window;
use na::{self, Point3};
-use ncollide::shape;
-#[cfg(feature = "dim3")]
-use ncollide::transformation::ToTriMesh;
use rapier::geometry::{ColliderHandle, ColliderSet};
#[cfg(feature = "dim2")]
use rapier::math::Point;
#[cfg(feature = "dim3")]
-use rapier::math::Vector;
+use {
+ crate::objects::node::{self, GraphicsNode},
+ kiss3d::resource::Mesh,
+ rapier::math::Vector,
+ std::cell::RefCell,
+};
pub struct HeightField {
color: Point3<f32>,
@@ -25,7 +26,7 @@ impl HeightField {
#[cfg(feature = "dim2")]
pub fn new(
collider: ColliderHandle,
- heightfield: &shape::HeightField<f32>,
+ heightfield: &shape::HeightField,
color: Point3<f32>,
_: &mut Window,
) -> HeightField {
@@ -47,16 +48,23 @@ impl HeightField {
#[cfg(feature = "dim3")]
pub fn new(
collider: ColliderHandle,
- heightfield: &shape::HeightField<f32>,
+ heightfield: &shape::HeightField,
color: Point3<f32>,
window: &mut Window,
) -> HeightField {
- let mesh = heightfield.to_trimesh(());
+ use std::rc::Rc;
+
+ let (vertices, indices) = heightfield.to_trimesh();
+ let indices = indices
+ .into_iter()
+ .map(|idx| Point3::new(idx[0] as u16, idx[1] as u16, idx[2] as u16))
+ .collect();
+ let mesh = Mesh::new(vertices, indices, None, None, false);
let mut res = HeightField {
color,
base_color: color,
- gfx: window.add_trimesh(mesh, Vector::repeat(1.0)),
+ gfx: window.add_mesh(Rc::new(RefCell::new(mesh)), Vector::repeat(1.0)),
collider: collider,
};
diff --git a/src_testbed/objects/mesh.rs b/src_testbed/objects/mesh.rs
index 5187a8b..5505de3 100644
--- a/src_testbed/objects/mesh.rs
+++ b/src_testbed/objects/mesh.rs
@@ -17,12 +17,15 @@ impl Mesh {
pub fn new(
collider: ColliderHandle,
vertices: Vec<Point<f32>>,
- indices: Vec<Point3<u32>>,
+ indices: Vec<[u32; 3]>,
color: Point3<f32>,
window: &mut window::Window,
) -> Mesh {
let vs = vertices;
- let is = indices.into_iter().map(na::convert).collect();
+ let is = indices
+ .into_iter()
+ .map(|idx| Point3::new(idx[0] as u16, idx[1] as u16, idx[2] as u16))
+ .collect();
let mesh;
let gfx;
diff --git a/src_testbed/objects/polyline.rs b/src_testbed/objects/polyline.rs
index 77841ae..a7422b3 100644
--- a/src_testbed/objects/polyline.rs
+++ b/src_testbed/objects/polyline.rs
@@ -1,6 +1,6 @@
+use cdl2d::shape;
use kiss3d::window::Window;
use na::{Isometry2, Point2, Point3};
-use ncollide2d::shape;
use nphysics2d::object::{ColliderAnchor, DefaultColliderHandle, DefaultColliderSet};
pub struct Polyline {
diff --git a/src_testbed/physics/mod.rs b/src_testbed/physics/mod.rs
index 4b1923f..808e9bd 100644
--- a/src_testbed/physics/mod.rs
+++ b/src_testbed/physics/mod.rs
@@ -1,6 +1,6 @@
use crossbeam::channel::Receiver;
use rapier::dynamics::{IntegrationParameters, JointSet, RigidBodySet};
-use rapier::geometry::{BroadPhase, ColliderSet, ContactEvent, NarrowPhase, ProximityEvent};
+use rapier::geometry::{BroadPhase, ColliderSet, ContactEvent, IntersectionEvent, NarrowPhase};
use rapier::math::Vector;
use rapier::pipeline::{PhysicsPipeline, QueryPipeline};
@@ -97,12 +97,12 @@ impl PhysicsState {
pub struct PhysicsEvents {
pub contact_events: Receiver<ContactEvent>,
- pub proximity_events: Receiver<ProximityEvent>,
+ pub intersection_events: Receiver<IntersectionEvent>,
}
impl PhysicsEvents {
pub fn poll_all(&self) {
while let Ok(_) = self.contact_events.try_recv() {}
- while let Ok(_) = self.proximity_events.try_recv() {}
+ while let Ok(_) = self.intersection_events.try_recv() {}
}
}
diff --git a/src_testbed/physx_backend.rs b/src_testbed/physx_backend.rs
index 6ea207a..319736c 100644
--- a/src_testbed/physx_backend.rs
+++ b/src_testbed/physx_backend.rs
@@ -1,7 +1,21 @@
#![allow(dead_code)]
-use na::{Isometry3, Matrix3, Matrix4, Point3, Rotation3, Translation3, UnitQuaternion, Vector3};
+use na::{
+ Isometry3, Matrix3, Matrix4, Point3, Quaternion, Rotation3, Translation3, Unit, UnitQuaternion,
+ Vector3,
+};
+use physx::cooking::{
+ ConvexMeshCookingResult, PxConvexMeshDesc, PxCooking, PxCookingParams, PxHeightFieldDesc,
+ PxTriangleMeshDesc, TriangleMeshCookingResult,
+};
+use physx::foundation::DefaultAllocator;
use physx::prelude::*;
+use physx::scene::FrictionType;
+use physx::traits::Class;
+use physx_sys::{
+ PxBitAndByte, PxConvexFlags, PxConvexMeshGeometryFlags, PxHeightFieldSample,
+ PxMeshGeometryFlags, PxMeshScale_new, PxRigidActor,
+};
use rapier::counters::Counters;
use rapier::dynamics::{
IntegrationParameters, JointParams, JointSet, RigidBodyHandle, RigidBodySet,
@@ -10,8 +24,6 @@ use rapier::geometry::{Collider, ColliderSet};
use rapier::utils::WBasis;
use std::collections::HashMap;
-const PX_PHYSICS_VERSION: u32 = physx::version(4, 1, 1);
-
trait IntoNa {
type Output;
fn into_na(self) -> Self::Output;
@@ -24,37 +36,53 @@ impl IntoNa for glam::Mat4 {
}
}
+impl IntoNa for PxVec3 {
+ type Output = Vector3<f32>;
+ fn into_na(self) -> Self::Output {
+ Vector3::new(self.x(), self.y(), self.z())
+ }
+}
+
+impl IntoNa for PxQuat {
+ type Output = Quaternion<f32>;
+ fn into_na(self) -> Self::Output {
+ Quaternion::new(self.w(), self.x(), self.y(), self.z())
+ }
+}
+
+impl IntoNa for PxTransform {
+ type Output = Isometry3<f32>;
+ fn into_na(self) -> Self::Output {
+ let tra = self.translation().into_na();
+ let quat = self.rotation().into_na();
+ let unit_quat = Unit::new_unchecked(quat);
+ Isometry3::from_parts(tra.into(), unit_quat)
+ }
+}
+
trait IntoPhysx {
type Output;
fn into_physx(self) -> Self::Output;
}
impl IntoPhysx for Vector3<f32> {
- type Output = physx_sys::PxVec3;
+ type Output = PxVec3;
fn into_physx(self) -> Self::Output {
- physx_sys::PxVec3 {
- x: self.x,
- y: self.y,
- z: self.z,
- }
+ PxVec3::new(self.x, self.y, self.z)
}
}
impl IntoPhysx for Point3<f32> {
- type Output = physx_sys::PxVec3;
+ type Output = PxVec3;
fn into_physx(self) -> Self::Output {
- physx_sys::PxVec3 {
- x: self.x,
- y: self.y,
- z: self.z,
- }
+ PxVec3::new(self.x, self.y, self.z)
}
}
impl IntoPhysx for Isometry3<f32> {
- type Output = physx_sys::PxTransform;
+ type Output = PxTransform;
fn into_physx(self) -> Self::Output {
- physx::transform::gl_to_px_tf(self.into_glam())
+ self.into_glam().into()
}
}
@@ -92,14 +120,23 @@ impl IntoGlam for Isometry3<f32> {
}
thread_local! {
-pub static FOUNDATION: std::cell::RefCell<Foundation> = std::cell::RefCell::new(Foundation::new(PX_PHYSICS_VERSION));
+pub static FOUNDATION: std::cell::RefCell<PxPhysicsFoundation> = std::cell::RefCell::new(PhysicsFoundation::default());
}
pub struct PhysxWorld {
- physics: Physics,
- cooking: Cooking,
- scene: Scene,
- rapier2physx: HashMap<RigidBodyHandle, BodyHandle>,
+ // physics: Physics,
+ // cooking: Cooking,
+ materials: Vec<Owner<PxMaterial>>,
+ shapes: Vec<Owner<PxShape>>,
+ scene: Option<Owner<PxScene>>,
+}
+
+impl Drop for PhysxWorld {
+ fn drop(&mut self) {
+ let scene = self.scene.take();
+ // FIXME: we get a segfault if we don't forget the scene.
+ std::mem::forget(scene);
+ }
}
impl PhysxWorld {
@@ -112,123 +149,87 @@ impl PhysxWorld {
use_two_friction_directions: bool,
num_threads: usize,
) -> Self {
- let mut rapier2physx = HashMap::new();
- let mut physics = FOUNDATION.with(|f| {
- PhysicsBuilder::default()
- .load_extensions(false)
- .build(&mut *f.borrow_mut())
- });
- let mut cooking = FOUNDATION.with(|f| unsafe {
- let sc = physx_sys::PxTolerancesScale_new();
- let params = physx_sys::PxCookingParams_new(&sc);
- Cooking::new(PX_PHYSICS_VERSION, &mut *f.borrow_mut(), params)
- });
-
- let scene_desc = MySceneBuilder::default()
- .set_gravity(gravity.into_glam())
- .set_simulation_threading(SimulationThreadType::Dedicated(num_threads as u32))
- // .set_broad_phase_type(BroadPhaseType::SweepAndPrune)
- // .set_solver_type(physx_sys::PxSolverType::eTGS)
- .build_desc(&mut physics);
-
- let raw_scene =
- unsafe { physx_sys::PxPhysics_createScene_mut(physics.get_raw_mut(), &scene_desc) };
-
- // FIXME: we do this because we are also using two
- // friction directions. We should add to rapier the option to use
- // one friction direction too, and perhaps an equivalent of physX
- // ePATCH friction type.
- if use_two_friction_directions {
- unsafe {
- physx_sys::PxScene_setFrictionType_mut(
- raw_scene,
- physx_sys::PxFrictionType::eTWO_DIRECTIONAL,
- );
- }
- }
+ FOUNDATION.with(|physics| {
+ let mut physics = physics.borrow_mut();
+ let mut shapes = Vec::new();
+ let mut materials = Vec::new();
- let mut scene = Scene::new(raw_scene);
-
- for (rapier_handle, rb) in bodies.iter() {
- use physx::rigid_dynamic::RigidDynamic;
- use physx::rigid_static::RigidStatic;
- use physx::transform;
+ let friction_type = if use_two_friction_directions {
+ FrictionType::TwoDirectional
+ } else {
+ FrictionType::Patch
+ };
- let pos = transform::gl_to_px_tf(rb.position().to_homogeneous().into_g