Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

It is no longer possible to set TriMeshFlags::FIX_INTERNAL_EDGES when using Collider::from_bevy_mesh #571

Closed
rparrett opened this issue Jul 25, 2024 · 3 comments

Comments

@rparrett
Copy link
Contributor

TriMeshFlags::FIX_INTERNAL_EDGES is no longer the default behavior, but Bevy users don't really have a good way of setting it.

The workaround is pretty annoying due to extract_mesh_vertices_indices not being pub and containing a bunch of nalgebra types.

Workaround:

let mut flags = TriMeshFlags::default();
flags.set(TriMeshFlags::FIX_INTERNAL_EDGES, true);
let (vtx, idx) =
    extract_mesh_vertices_indices(meshes.get(mesh_handle).unwrap()).unwrap();
let collider: Collider = SharedShape::trimesh_with_flags(vtx, idx, flags).into();

// ...

fn extract_mesh_vertices_indices(
    mesh: &Mesh,
) -> Option<(
    Vec<bevy_rapier3d::na::Point3<bevy_rapier3d::prelude::Real>>,
    Vec<[u32; 3]>,
)> {
    use bevy_rapier3d::math::Real;
    use bevy_rapier3d::na::Point3;

    let vertices = mesh.attribute(Mesh::ATTRIBUTE_POSITION)?;
    let indices = mesh.indices()?;

    let vtx: Vec<_> = match vertices {
        VertexAttributeValues::Float32(vtx) => Some(
            vtx.chunks(3)
                .map(|v| Point3::new(v[0] as Real, v[1] as Real, v[2] as Real))
                .collect(),
        ),
        VertexAttributeValues::Float32x3(vtx) => Some(
            vtx.iter()
                .map(|v| Point3::new(v[0] as Real, v[1] as Real, v[2] as Real))
                .collect(),
        ),
        _ => None,
    }?;

    let idx = match indices {
        Indices::U16(idx) => idx
            .chunks_exact(3)
            .map(|i| [i[0] as u32, i[1] as u32, i[2] as u32])
            .collect(),
        Indices::U32(idx) => idx.chunks_exact(3).map(|i| [i[0], i[1], i[2]]).collect(),
    };

    Some((vtx, idx))
}
@Vrixyz
Copy link
Contributor

Vrixyz commented Jul 25, 2024

I'm surprised TriMeshFlags::FIX_INTERNAL_EDGES was the default somewhere :o, if you can pinpoint how/where exactly I'm curious.

you should be able to pass within ComputedColliderShape the flags inside the TriMesh variant.

if that's not enough, we can probably consider making extract_mesh_vertices_indices public.

@rparrett
Copy link
Contributor Author

It looks like #559 should fix me up whenever it makes it into a release.

Thanks!

@rparrett
Copy link
Contributor Author

rparrett commented Jul 25, 2024

I'm surprised TriMeshFlags::FIX_INTERNAL_EDGES was the default somewhere

Sorry, bit of an assumption / misreading of this changelog entry by me.

Internal edge correction is now opt-in with the TriMeshFlags::FIX_INTERNAL_EDGES and HeightFieldFlags::FIX_INTERNAL_EDGES flags.

I read that as if the flag existed previously, but was enabled by default. Upgrading from 0.25 -> 0.27 seemed to regress trimesh collisions though, resulting in colliders bumping wildly on "smooth" edges.

So I think that the TriMeshFlags::FIX_INTERNAL_EDGES flag itself is new, but there was something making trimesh edge collisions more stable in rapier 0.18 that was happening by default. And now to get the same behavior, I have to enable that flag.

I have vague memories of this being an issue in much older versions of rapier and then not an issue in later ones, and now an issue again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants