diff --git a/Demos/InternalEdgeDemo/CMakeLists.txt b/Demos/InternalEdgeDemo/CMakeLists.txt index 826dd6780..365af37ec 100644 --- a/Demos/InternalEdgeDemo/CMakeLists.txt +++ b/Demos/InternalEdgeDemo/CMakeLists.txt @@ -26,13 +26,13 @@ IF (USE_GLUT) IF (WIN32) IF (CMAKE_CL_64) ADD_CUSTOM_COMMAND( - TARGET InternalEdgeDemo + TARGET AppInternalEdgeDemo POST_BUILD COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} ) ELSE(CMAKE_CL_64) ADD_CUSTOM_COMMAND( - TARGET InternalEdgeDemo + TARGET AppInternalEdgeDemo POST_BUILD COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR} ) diff --git a/src/BulletCollision/CollisionDispatch/btInternalEdgeUtility.cpp b/src/BulletCollision/CollisionDispatch/btInternalEdgeUtility.cpp index 7601efd89..e1db4c444 100644 --- a/src/BulletCollision/CollisionDispatch/btInternalEdgeUtility.cpp +++ b/src/BulletCollision/CollisionDispatch/btInternalEdgeUtility.cpp @@ -6,15 +6,16 @@ #include "BulletCollision/NarrowPhaseCollision/btManifoldPoint.h" #include "LinearMath/btIDebugDraw.h" + //#define DEBUG_INTERNAL_EDGE + #ifdef DEBUG_INTERNAL_EDGE #include #endif //DEBUG_INTERNAL_EDGE #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW -//quick hack for debug drawing static btIDebugDraw* gDebugDrawer = 0; void btSetDebugDrawer(btIDebugDraw* debugDrawer) @@ -432,10 +433,9 @@ bool btClampNormal(const btVector3& edge,const btVector3& tri_normal_org,const b /// Changes a btManifoldPoint collision normal to the normal from the mesh. -void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObject* colObj0,const btCollisionObject* colObj1, int partId0, int index0) +void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObject* colObj0,const btCollisionObject* colObj1, int partId0, int index0, int normalAdjustFlags) { - - btAssert(colObj0->getCollisionShape()->getShapeType() == TRIANGLE_SHAPE_PROXYTYPE); + //btAssert(colObj0->getCollisionShape()->getShapeType() == TRIANGLE_SHAPE_PROXYTYPE); if (colObj0->getCollisionShape()->getShapeType() != TRIANGLE_SHAPE_PROXYTYPE) return; @@ -450,6 +450,8 @@ void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObject* if (!info) return; + btScalar frontFacing = (normalAdjustFlags & BT_TRIANGLE_CONVEX_BACKFACE_MODE)==0? 1.f : -1.f; + const btTriangleShape* tri_shape = static_cast(colObj0->getCollisionShape()); btVector3 v0,v1,v2; tri_shape->getVertex(0,v0); @@ -536,12 +538,16 @@ void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObject* bool isClamped = btClampNormal(edge,swapFactor*tri_normal,localContactNormalOnB, info->m_edgeV0V1Angle,clampedLocalNormal); if (isClamped) { - btVector3 newNormal = colObj0->getWorldTransform().getBasis() * clampedLocalNormal; - // cp.m_distance1 = cp.m_distance1 * newNormal.dot(cp.m_normalWorldOnB); - cp.m_normalWorldOnB = newNormal; - // Reproject collision point along normal. (what about cp.m_distance1?) - cp.m_positionWorldOnB = cp.m_positionWorldOnA - cp.m_normalWorldOnB * cp.m_distance1; - cp.m_localPointB = colObj0->getWorldTransform().invXform(cp.m_positionWorldOnB); + if (clampedLocalNormal.dot(frontFacing*tri_normal)>0) + { + btVector3 newNormal = colObj0->getWorldTransform().getBasis() * clampedLocalNormal; + // cp.m_distance1 = cp.m_distance1 * newNormal.dot(cp.m_normalWorldOnB); + cp.m_normalWorldOnB = newNormal; + // Reproject collision point along normal. (what about cp.m_distance1?) + cp.m_positionWorldOnB = cp.m_positionWorldOnA - cp.m_normalWorldOnB * cp.m_distance1; + cp.m_localPointB = colObj0->getWorldTransform().invXform(cp.m_positionWorldOnB); + + } } } } @@ -615,12 +621,15 @@ void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObject* bool isClamped = btClampNormal(edge,swapFactor*tri_normal,localContactNormalOnB, info->m_edgeV1V2Angle,clampedLocalNormal); if (isClamped) { - btVector3 newNormal = colObj0->getWorldTransform().getBasis() * clampedLocalNormal; - // cp.m_distance1 = cp.m_distance1 * newNormal.dot(cp.m_normalWorldOnB); - cp.m_normalWorldOnB = newNormal; - // Reproject collision point along normal. - cp.m_positionWorldOnB = cp.m_positionWorldOnA - cp.m_normalWorldOnB * cp.m_distance1; - cp.m_localPointB = colObj0->getWorldTransform().invXform(cp.m_positionWorldOnB); + if (clampedLocalNormal.dot(frontFacing*tri_normal)>0) + { + btVector3 newNormal = colObj0->getWorldTransform().getBasis() * clampedLocalNormal; + // cp.m_distance1 = cp.m_distance1 * newNormal.dot(cp.m_normalWorldOnB); + cp.m_normalWorldOnB = newNormal; + // Reproject collision point along normal. + cp.m_positionWorldOnB = cp.m_positionWorldOnA - cp.m_normalWorldOnB * cp.m_distance1; + cp.m_localPointB = colObj0->getWorldTransform().invXform(cp.m_positionWorldOnB); + } } } } @@ -693,12 +702,15 @@ void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObject* bool isClamped = btClampNormal(edge,swapFactor*tri_normal,localContactNormalOnB,info->m_edgeV2V0Angle,clampedLocalNormal); if (isClamped) { - btVector3 newNormal = colObj0->getWorldTransform().getBasis() * clampedLocalNormal; - // cp.m_distance1 = cp.m_distance1 * newNormal.dot(cp.m_normalWorldOnB); - cp.m_normalWorldOnB = newNormal; - // Reproject collision point along normal. - cp.m_positionWorldOnB = cp.m_positionWorldOnA - cp.m_normalWorldOnB * cp.m_distance1; - cp.m_localPointB = colObj0->getWorldTransform().invXform(cp.m_positionWorldOnB); + if (clampedLocalNormal.dot(frontFacing*tri_normal)>0) + { + btVector3 newNormal = colObj0->getWorldTransform().getBasis() * clampedLocalNormal; + // cp.m_distance1 = cp.m_distance1 * newNormal.dot(cp.m_normalWorldOnB); + cp.m_normalWorldOnB = newNormal; + // Reproject collision point along normal. + cp.m_positionWorldOnB = cp.m_positionWorldOnA - cp.m_normalWorldOnB * cp.m_distance1; + cp.m_localPointB = colObj0->getWorldTransform().invXform(cp.m_positionWorldOnB); + } } } } @@ -719,13 +731,22 @@ void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObject* if (numConcaveEdgeHits>0) { - //fix tri_normal so it pointing the same direction as the current local contact normal - if (tri_normal.dot(localContactNormalOnB) < 0) + + if ((normalAdjustFlags & BT_TRIANGLE_CONCAVE_SINGLE_SIDED)!=0) { - tri_normal *= -1; + //modify the normal to be the triangle normal (or backfacing normal) + cp.m_normalWorldOnB = colObj0->getWorldTransform().getBasis() *(tri_normal *frontFacing); + } else + { + //fix tri_normal so it pointing the same direction as the current local contact normal + if (tri_normal.dot(localContactNormalOnB) < 0) + { + tri_normal *= -1; + } + cp.m_normalWorldOnB = colObj0->getWorldTransform().getBasis()*tri_normal; } - //for concave edge hits, just modify the normal to be the triangle normal - cp.m_normalWorldOnB = colObj0->getWorldTransform().getBasis() * tri_normal; + + // Reproject collision point along normal. cp.m_positionWorldOnB = cp.m_positionWorldOnA - cp.m_normalWorldOnB * cp.m_distance1; cp.m_localPointB = colObj0->getWorldTransform().invXform(cp.m_positionWorldOnB); diff --git a/src/BulletCollision/CollisionDispatch/btInternalEdgeUtility.h b/src/BulletCollision/CollisionDispatch/btInternalEdgeUtility.h index e7e25e609..c6219417c 100644 --- a/src/BulletCollision/CollisionDispatch/btInternalEdgeUtility.h +++ b/src/BulletCollision/CollisionDispatch/btInternalEdgeUtility.h @@ -63,6 +63,11 @@ struct btTriangleInfoMap : public btInternalTriangleInfoMap } }; +enum btInternalEdgeAdjustFlags +{ + BT_TRIANGLE_CONVEX_BACKFACE_MODE = 1, + BT_TRIANGLE_CONCAVE_SINGLE_SIDED = 2 +}; ///Call btGenerateInternalEdgeInfo to create triangle info, store in the shape 'userInfo' @@ -71,7 +76,7 @@ void btGenerateInternalEdgeInfo (btBvhTriangleMeshShape*trimeshShape, btTriangle ///Call the btFixMeshNormal to adjust the collision normal, using the triangle info map (generated using btGenerateInternalEdgeInfo) ///If this info map is missing, or the triangle is not store in this map, nothing will be done -void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObject* trimeshColObj0,const btCollisionObject* otherColObj1, int partId0, int index0); +void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObject* trimeshColObj0,const btCollisionObject* otherColObj1, int partId0, int index0, int normalAdjustFlags = 0); ///Enable the BT_INTERNAL_EDGE_DEBUG_DRAW define and call btSetDebugDrawer, to get visual info to see if the internal edge utility works properly. ///If the utility doesn't work properly, you might have to adjust the threshold values in btTriangleInfoMap