NVIDIAGameWorks/PhysX

Found bug in Gu::sweepCapsuleTriangles_Precise

bleston opened this issue · 0 comments

Gu::sweepCapsuleTriangles_Precise may miss initial overlap when sweep dir is parallel with triangle.

Below code show this:

void testSweepCapsuleTriangle()
{
	const PxVec3 vertices[3] = { {0.f, 0.f, 0.f}, {1.f, 0.f, 0.f }, {0.f, 0.f, -1.0f} };
	const PxU32 indices[3] = { 0, 1, 2 };

	static float radius = 0.3;
	static float halfHeight = 1.f;

	const PxVec3 startPoint{ 0.f, 0.f, 0.f };
	const PxQuat rot{ 0.f, 0.f, 0.f, 1.f };
	const PxVec3 unitDir{ -1.f, 0.f, 0.f };
	const PxReal distance{ 1.0f };

	const physx::PxTransform pose0{ startPoint, rot };
	const physx::PxTransform poseTri{ PxIdentity };

	PxHitFlags hitFlags{ physx::PxHitFlag::eDEFAULT | physx::PxHitFlag::eMESH_BOTH_SIDES };

	PxTriangleMeshDesc meshDesc;
	meshDesc.points.count = 3;
	meshDesc.points.data = vertices;
	meshDesc.points.stride = sizeof(PxVec3);
	meshDesc.triangles.count = 1;
	meshDesc.triangles.data = indices;
	meshDesc.triangles.stride = 3 * sizeof(PxU32);
	PxCookingParams params = gCooking->getParams();

	PxTriangleMesh* triMesh = NULL;
	triMesh = gCooking->createTriangleMesh(meshDesc, gPhysics->getPhysicsInsertionCallback());

	PxTriangleMeshGeometry triGeom{ triMesh };
	PxCapsuleGeometry capsuleGeom{ radius, halfHeight };

	bool isInitOverlap = PxGeometryQuery::overlap(capsuleGeom, pose0, triGeom, poseTri);
	printf("isInitOverlap = %d.\n", isInitOverlap);

	physx::PxSweepHit hit;
	PxU32 hitCount = PxGeometryQuery::sweep(unitDir, distance, capsuleGeom, pose0, triGeom, poseTri, hit, hitFlags);
	printf("\nSweep capsule hitCount = %d.\n", hitCount);
	if (hitCount > 0)
	{
		printf("hit position is (%f, %f, %f).\n", hit.position.x, hit.position.y, hit.position.z);
		printf("hit normal is (%f, %f, %f).\n", hit.normal.x, hit.normal.y, hit.normal.z);
		printf("hit distance is %f.\n", hit.distance);
	}

	triMesh->release();
}

This bug is because rejectTriangle before intersectCapsuleTriangle in Gu::sweepCapsuleTriangles_Precise.