nphysics
nphysics copied to clipboard
Isometry fields are NaN for TriMesh rigid bodies
Here is an example that reproduces the issue, based on the trimesh3 example:
fn main() {
let mut world = World::new();
let quad = ncollide3d::procedural::quad(10.0, 10.0, 10, 10);
let indices = quad
.flat_indices()
.chunks(3)
.map(|is| Point3::new(is[0] as usize, is[2] as usize, is[1] as usize))
.collect();
let vertices = quad.coords;
let geom = ShapeHandle::new(TriMesh::new(vertices, indices, None));
// Add first object
let pos = Isometry3::new(Vector3::new(1.0, 2.0, 3.0), na::zero());
let handle = world.add_rigid_body(pos, Inertia3::zero(), na::Point3::new(4.0, 5.0, 6.0));
let col_handle1 = world.add_collider(
COLLIDER_MARGIN,
geom.clone(),
handle,
Isometry3::identity(),
Material::default(),
);
// Add second object
let pos = Isometry3::new(Vector3::new(1.0, 2.0, 3.0), na::zero());
let handle = world.add_rigid_body(pos, Inertia3::zero(), na::Point3::new(4.0, 5.0, 6.0));
let col_handle2 = world.add_collider(
COLLIDER_MARGIN,
geom.clone(),
handle,
Isometry3::identity(),
Material::default(),
);
world.step();
world.step();
println!("{:?}", world.collider(col_handle1).unwrap().position());
println!("{:?}", world.collider(col_handle2).unwrap().position());
}
Output:
Isometry { rotation: Unit { value: Quaternion { coords: Matrix { data: [NaN, NaN, NaN, NaN] } } }, translation: Translation { vector: Matrix { data: [NaN, NaN, NaN] } }, _noconstruct: PhantomData }
Isometry { rotation: Unit { value: Quaternion { coords: Matrix { data: [NaN, NaN, NaN, NaN] } } }, translation: Translation { vector: Matrix { data: [NaN, NaN, NaN] } }, _noconstruct: PhantomData }
Two static rigid bodies are created using a TriMesh as their colliders. After calling world.step() twice, the translation and rotation of both the rigid body and the collider of each rigid body are filled with NaN. I would expect even static bodies such as TriMeshs to have a position and rotation, and this is indeed the case if world.step() is only called once in the above example.
There are two issues here:
- Creating a rigid body with an inertia set to zero does not make it static automatically. Instead, you end up with a dynamic rigid body with invalid inertial properties, i.e., an inverse mass equal to
1.0 / 0.0. So you should either not attach theTriMeshto any rigid body, or attach theTriMeshto a rigid body on which you callrb.set_status(BodyStatus::Static);. See this for more details on rigid body statuses. - The two triangle meshes are exactly superimposed, which seem to break collision detection or constraint generation here. I will have to investigate that.
Regarding the first issue, maybe nphysics should panic if the user runs a simulation with an invalid inertia, or maybe it should just act as if the mass was infinite (so the object becomes static) when it is set to 0 by the user.
Thanks for the reply. I guess this issue can track the second issue listed in your comment.