DanielChappuis / reactphysics3d

Open source C++ physics engine library in 3D
http://www.reactphysics3d.com
zlib License
1.54k stars 223 forks source link

Convex vs Capsule normal assert failed #279

Closed caxapexac closed 8 months ago

caxapexac commented 2 years ago

What could possibly lead to this issue?

Assertion failed: contactNormal.length() > 0.8f , at: reactphysics3d/collision/narrowphase/NarrowPhaseInfoBatch.h,168,addContactPoint

  | $reactphysics3d::SATAlgorithm::computeCapsulePolyhedronFaceContactPoints(unsigned int, float, reactphysics3d::ConvexPolyhedronShape const*, float, reactphysics3d::Transform const&, reactphysics3d::Vector3&, reactphysics3d::Vector3 const&, reactphysics3d::Vector3 const&, reactphysics3d::Vector3 const&, reactphysics3d::NarrowPhaseInfoBatch&, unsigned int, bool) const | @ | first-person-shooter.wasm:0x724b04
  | $reactphysics3d::CapsuleVsConvexPolyhedronAlgorithm::testCollision(reactphysics3d::NarrowPhaseInfoBatch&, unsigned int, unsigned int, bool, reactphysics3d::MemoryAllocator&) | @ | first-person-shooter.wasm:0x743bb0
  | $reactphysics3d::CollisionDetectionSystem::testNarrowPhaseCollision(reactphysics3d::NarrowPhaseInput&, bool, reactphysics3d::MemoryAllocator&) | @ | first-person-shooter.wasm:0x750c66
  | $reactphysics3d::CollisionDetectionSystem::computeNarrowPhase() | @ | first-person-shooter.wasm:0x74a1b9
  | $reactphysics3d::CollisionDetectionSystem::computeCollisionDetection()
DanielChappuis commented 2 years ago

This assert is there to make sure the length of the contact normal is not to small (the contact normal should be of unity length). What is the length of the contact normal in your case? Can you try to find in the code where this contact normal is generated?

caxapexac commented 2 years ago

Okay wait for several minutes

caxapexac commented 2 years ago

contactNormal: xyz: -0.000000 -0.000000 -0.000000 len: 0.000000

Crashes when I contact ground after jump (just walking works well, jumping also works but this assert hapens after 1~15 jumps, not consistent)

caxapexac commented 2 years ago

@DanielChappuis Convex colliders contain triangles (not polygons) for now, could it be related to the problem?

DanielChappuis commented 2 years ago

Triangles are valid polygons and therefore it should not be an issue as long as you have created your ConvexMeshShape correctly using triangles polygons.

DanielChappuis commented 2 years ago

contactNormal: xyz: -0.000000 -0.000000 -0.000000 len: 0.000000

Crashes when I contact ground after jump (just walking works well, jumping also works but this assert hapens after 1~15 jumps, not consistent)

Ok it is a contact normal with zero length and therefore seems to be a bug. Can I ask you to try to understand where exactly this contact normal is generated in the library code? It would help a lot. It is probably in the collision detection code in the following two files:

Look at where the addContactPoint() method is called. The second parameter of this method is the contact normal. Try to see when this function is called (in those two files) with a zero length contact normal.

caxapexac commented 2 years ago

@DanielChappuis stacktrace shows SATA https://github.com/DanielChappuis/reactphysics3d/issues/279#issue-1377776992

DanielChappuis commented 2 years ago

OK the computeCapsulePolyhedronFaceContactPoints() methods takes a 'contactNormal' parameter. Can you find where this contact normal has been computed originally?

caxapexac commented 2 years ago

Polyhedron face normal == 0

CapsuleVsConvexPolyhedronAlgorithm::109 faceNormal 0.000000 0.000000 0.000000 len: 0.000000

CapsuleVsConvexPolyhedronAlgorithm::110 polyhedronToWorld.getOrientation() 0.000000 0.000000 0.000000 1.000000

CapsuleVsConvexPolyhedronAlgorithm::110 faceNormalWorld 0.000000 0.000000 0.000000 len: 0.000000

computeCapsulePolyhedronFaceContactPoints CapsuleVsConvexPolyhedronAlgorithm::146

faceNormalWorld -0.000000 -0.000000 -0.000000 len: 0.000000
DanielChappuis commented 2 years ago

So the face normal returned by the method polyhedron->getFaceNormal(f) is (0, 0, 0)? In this case, you might need to check the vertices of the given face of your convex mesh. Maybe this face is degenerated (zero area for instance).

caxapexac commented 2 years ago

PolyhedronMesh::computeFacesNormals

const Vector3 vec1 = getVertex(face.faceVertices[1]) - getVertex(face.faceVertices[0]);
        const Vector3 vec2 = getVertex(face.faceVertices[2]) - getVertex(face.faceVertices[0]);
        mFacesNormals[f] = vec1.cross(vec2);
        mFacesNormals[f].normalize();

        if (mFacesNormals[f].length() < 0.8f)
        {
            auto v0 = getVertex(face.faceVertices[0]);
            auto v1 = getVertex(face.faceVertices[1]);
            auto v2 = getVertex(face.faceVertices[2]);

            LOG_WARNING("mFacesNormals[f].length() < 0.8f: %f", mFacesNormals[f].length());
            LOG_WARNING("vertex0: %f %f %f", v0.x, v0.y, v0.z);
            LOG_WARNING("vertex1: %f %f %f", v1.x, v1.y, v1.z);
            LOG_WARNING("vertex2: %f %f %f", v2.x, v2.y, v2.z);
            LOG_WARNING("vec1: %f %f %f", vec1.x, vec1.y, vec1.z);
            LOG_WARNING("vec2: %f %f %f", vec2.x, vec2.y, vec2.z);
        }

vertex0: -1.345502 1.466758 -0.043059 vertex1: -1.345502 -1.192211 -0.043059 vertex2: -1.345502 -0.873077 -0.043059 vec1: 0.000000 -2.658969 0.000000 vec2: 0.000000 -2.339835 0.000000

So yeah, seems like area is 0

At least this should be checked inside the convex mesh generation algorithm cuz Ive built convex meshes using Blender convex hull operator and expecting this to be valid

DanielChappuis commented 2 years ago

Yes I totally agree with you. I will add checks for this inside the code that creates the convex mesh.

caxapexac commented 2 years ago

@DanielChappuis btw which algorithm/application/library are you using for convex colliders?

DanielChappuis commented 2 years ago

@DanielChappuis btw which algorithm/application/library are you using for convex colliders?

What do you mean exactly by 'for convex colliders'? Do you mean collision detection between convex colliders? For collision detection, I use the SAT algorithm and GJK Algorithm.

caxapexac commented 2 years ago

No I mean external tool for creating/building/generating convex colliders that your library supports (as Ive said previously - Blender makes shitty ones). E.g. quickhull.h or something. Would be really appreciated to get to know somthing like this

DanielChappuis commented 2 years ago

I am also using Blender most of the time.

Note that I am currently working on implementing a quickhull algorithm inside the ReactPhysics3D library as you can see in this branch here. This way, it will be possible to create a ConvexMeshShape with simply an array of 3D points. This will be released in the next version of the library.

kewldan commented 1 year ago

Same problem (Capsule and concave). Occurs in my experience when a capsule collides with a small face. And to minimize the chance of this error, you should remove all duplicate vertices in the mesh. And also transfer the normals yourself when creating the TriangleVertexArray. I will also try to analyze now my normals, which I pass to the constructor

DanielChappuis commented 1 year ago

Yes, the mesh used for collision detection must not have duplicated vertices or zero area faces. In the next version of the library, there will be code to check this kind of errors at the mesh creation.

kewldan commented 1 year ago

Yes, the mesh used for collision detection must not have duplicated vertices or zero area faces. In the next version of the library, there will be code to check this kind of errors at the mesh creation.

Guide for blender:

  1. Triangulate the model
  2. Select all faces
  3. Press M -> By distance (Merge dublicated vertices)
  4. Shift + N (Recalculate normals)
  5. Export (I use export as obj and Assimp loader)

Try all these steps to minimize the chance of this error. U should also give normals from the model to ReactPhysics if you use Concave Mesh. It helps me.

By the way, can you tell me when the next version will be released? Will there be a check for zero-area faces and a controller for the player's actions?

In any case, I think that your library is the easiest to understand and has the most intuitive interface for interacting with it. And you should add more functionality (like a player controller). Thank you for your hard work!

DanielChappuis commented 8 months ago

In the last version of the library (v0.10.0) there are checks when creating ConvexMesh, TriangleMesh and HeightField. When creating those shapes, the library will report errors in this case. Thanks a lot for reporting the issue.