add btAdjustInternalEdgeContacts options for BT_TRIANGLE_CONVEX_BACKFACE_MODE (defaults to front facing) and BT_TRIANGLE_CONCAVE_SINGLE_SIDED

This commit is contained in:
erwin.coumans
2010-01-30 10:21:40 +00:00
parent 01b66a6799
commit fbc4089e3f
3 changed files with 56 additions and 30 deletions

View File

@@ -26,13 +26,13 @@ IF (USE_GLUT)
IF (WIN32) IF (WIN32)
IF (CMAKE_CL_64) IF (CMAKE_CL_64)
ADD_CUSTOM_COMMAND( ADD_CUSTOM_COMMAND(
TARGET InternalEdgeDemo TARGET AppInternalEdgeDemo
POST_BUILD POST_BUILD
COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR} COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR}
) )
ELSE(CMAKE_CL_64) ELSE(CMAKE_CL_64)
ADD_CUSTOM_COMMAND( ADD_CUSTOM_COMMAND(
TARGET InternalEdgeDemo TARGET AppInternalEdgeDemo
POST_BUILD POST_BUILD
COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR} COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR}
) )

View File

@@ -6,15 +6,16 @@
#include "BulletCollision/NarrowPhaseCollision/btManifoldPoint.h" #include "BulletCollision/NarrowPhaseCollision/btManifoldPoint.h"
#include "LinearMath/btIDebugDraw.h" #include "LinearMath/btIDebugDraw.h"
//#define DEBUG_INTERNAL_EDGE //#define DEBUG_INTERNAL_EDGE
#ifdef DEBUG_INTERNAL_EDGE #ifdef DEBUG_INTERNAL_EDGE
#include <stdio.h> #include <stdio.h>
#endif //DEBUG_INTERNAL_EDGE #endif //DEBUG_INTERNAL_EDGE
#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
//quick hack for debug drawing
static btIDebugDraw* gDebugDrawer = 0; static btIDebugDraw* gDebugDrawer = 0;
void btSetDebugDrawer(btIDebugDraw* debugDrawer) 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. /// 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) if (colObj0->getCollisionShape()->getShapeType() != TRIANGLE_SHAPE_PROXYTYPE)
return; return;
@@ -450,6 +450,8 @@ void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObject*
if (!info) if (!info)
return; return;
btScalar frontFacing = (normalAdjustFlags & BT_TRIANGLE_CONVEX_BACKFACE_MODE)==0? 1.f : -1.f;
const btTriangleShape* tri_shape = static_cast<const btTriangleShape*>(colObj0->getCollisionShape()); const btTriangleShape* tri_shape = static_cast<const btTriangleShape*>(colObj0->getCollisionShape());
btVector3 v0,v1,v2; btVector3 v0,v1,v2;
tri_shape->getVertex(0,v0); tri_shape->getVertex(0,v0);
@@ -535,6 +537,8 @@ void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObject*
btVector3 clampedLocalNormal; btVector3 clampedLocalNormal;
bool isClamped = btClampNormal(edge,swapFactor*tri_normal,localContactNormalOnB, info->m_edgeV0V1Angle,clampedLocalNormal); bool isClamped = btClampNormal(edge,swapFactor*tri_normal,localContactNormalOnB, info->m_edgeV0V1Angle,clampedLocalNormal);
if (isClamped) if (isClamped)
{
if (clampedLocalNormal.dot(frontFacing*tri_normal)>0)
{ {
btVector3 newNormal = colObj0->getWorldTransform().getBasis() * clampedLocalNormal; btVector3 newNormal = colObj0->getWorldTransform().getBasis() * clampedLocalNormal;
// cp.m_distance1 = cp.m_distance1 * newNormal.dot(cp.m_normalWorldOnB); // cp.m_distance1 = cp.m_distance1 * newNormal.dot(cp.m_normalWorldOnB);
@@ -542,6 +546,8 @@ void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObject*
// Reproject collision point along normal. (what about cp.m_distance1?) // Reproject collision point along normal. (what about cp.m_distance1?)
cp.m_positionWorldOnB = cp.m_positionWorldOnA - cp.m_normalWorldOnB * cp.m_distance1; cp.m_positionWorldOnB = cp.m_positionWorldOnA - cp.m_normalWorldOnB * cp.m_distance1;
cp.m_localPointB = colObj0->getWorldTransform().invXform(cp.m_positionWorldOnB); cp.m_localPointB = colObj0->getWorldTransform().invXform(cp.m_positionWorldOnB);
}
} }
} }
} }
@@ -614,6 +620,8 @@ void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObject*
btVector3 clampedLocalNormal; btVector3 clampedLocalNormal;
bool isClamped = btClampNormal(edge,swapFactor*tri_normal,localContactNormalOnB, info->m_edgeV1V2Angle,clampedLocalNormal); bool isClamped = btClampNormal(edge,swapFactor*tri_normal,localContactNormalOnB, info->m_edgeV1V2Angle,clampedLocalNormal);
if (isClamped) if (isClamped)
{
if (clampedLocalNormal.dot(frontFacing*tri_normal)>0)
{ {
btVector3 newNormal = colObj0->getWorldTransform().getBasis() * clampedLocalNormal; btVector3 newNormal = colObj0->getWorldTransform().getBasis() * clampedLocalNormal;
// cp.m_distance1 = cp.m_distance1 * newNormal.dot(cp.m_normalWorldOnB); // cp.m_distance1 = cp.m_distance1 * newNormal.dot(cp.m_normalWorldOnB);
@@ -626,6 +634,7 @@ void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObject*
} }
} }
} }
}
btNearestPointInLineSegment(contact,v2,v0,nearest); btNearestPointInLineSegment(contact,v2,v0,nearest);
#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
@@ -692,6 +701,8 @@ void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObject*
btVector3 clampedLocalNormal; btVector3 clampedLocalNormal;
bool isClamped = btClampNormal(edge,swapFactor*tri_normal,localContactNormalOnB,info->m_edgeV2V0Angle,clampedLocalNormal); bool isClamped = btClampNormal(edge,swapFactor*tri_normal,localContactNormalOnB,info->m_edgeV2V0Angle,clampedLocalNormal);
if (isClamped) if (isClamped)
{
if (clampedLocalNormal.dot(frontFacing*tri_normal)>0)
{ {
btVector3 newNormal = colObj0->getWorldTransform().getBasis() * clampedLocalNormal; btVector3 newNormal = colObj0->getWorldTransform().getBasis() * clampedLocalNormal;
// cp.m_distance1 = cp.m_distance1 * newNormal.dot(cp.m_normalWorldOnB); // cp.m_distance1 = cp.m_distance1 * newNormal.dot(cp.m_normalWorldOnB);
@@ -702,6 +713,7 @@ void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObject*
} }
} }
} }
}
} }
@@ -718,14 +730,23 @@ void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObject*
{ {
if (numConcaveEdgeHits>0) if (numConcaveEdgeHits>0)
{
if ((normalAdjustFlags & BT_TRIANGLE_CONCAVE_SINGLE_SIDED)!=0)
{
//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 //fix tri_normal so it pointing the same direction as the current local contact normal
if (tri_normal.dot(localContactNormalOnB) < 0) if (tri_normal.dot(localContactNormalOnB) < 0)
{ {
tri_normal *= -1; tri_normal *= -1;
} }
//for concave edge hits, just modify the normal to be the triangle normal cp.m_normalWorldOnB = colObj0->getWorldTransform().getBasis()*tri_normal;
cp.m_normalWorldOnB = colObj0->getWorldTransform().getBasis() * tri_normal; }
// Reproject collision point along normal. // Reproject collision point along normal.
cp.m_positionWorldOnB = cp.m_positionWorldOnA - cp.m_normalWorldOnB * cp.m_distance1; cp.m_positionWorldOnB = cp.m_positionWorldOnA - cp.m_normalWorldOnB * cp.m_distance1;
cp.m_localPointB = colObj0->getWorldTransform().invXform(cp.m_positionWorldOnB); cp.m_localPointB = colObj0->getWorldTransform().invXform(cp.m_positionWorldOnB);

View File

@@ -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' ///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) ///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 ///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. ///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 ///If the utility doesn't work properly, you might have to adjust the threshold values in btTriangleInfoMap