parallel/SPU collision task: contact points have to be replaced, otherwise small positional errors accumulate (and spheres start rolling automatically etc)

This commit is contained in:
erwin.coumans
2010-02-18 01:51:30 +00:00
parent 45e7c7f564
commit 2b7c0989a0
2 changed files with 27 additions and 22 deletions

View File

@@ -17,6 +17,12 @@ subject to the following restrictions:
//#define DEBUG_SPU_COLLISION_DETECTION 1 //#define DEBUG_SPU_COLLISION_DETECTION 1
#ifdef DEBUG_SPU_COLLISION_DETECTION
#ifndef __SPU__
#include <stdio.h>
#define spu_printf printf
#endif
#endif DEBUG_SPU_COLLISION_DETECTION
SpuContactResult::SpuContactResult() SpuContactResult::SpuContactResult()
{ {
@@ -99,44 +105,38 @@ bool ManifoldResultAddContactPoint(const btVector3& normalOnBInWorld,
if (depth > manifoldPtr->getContactBreakingThreshold()) if (depth > manifoldPtr->getContactBreakingThreshold())
return false; return false;
//provide inverses or just calculate?
btTransform transAInv = transA.inverse();//m_body0->m_cachedInvertedWorldTransform;
btTransform transBInv= transB.inverse();//m_body1->m_cachedInvertedWorldTransform;
btVector3 pointA; btVector3 pointA;
btVector3 localA; btVector3 localA;
btVector3 localB; btVector3 localB;
btVector3 normal; btVector3 normal;
if (isSwapped) if (isSwapped)
{ {
normal = normalOnBInWorld * -1; normal = normalOnBInWorld * -1;
pointA = pointInWorld + normal * depth; pointA = pointInWorld + normal * depth;
localA = transAInv(pointA ); localA = transA.invXform(pointA );
localB = transBInv(pointInWorld); localB = transB.invXform(pointInWorld);
/*localA = transBInv(pointA );
localB = transAInv(pointInWorld);*/
} }
else else
{ {
normal = normalOnBInWorld; normal = normalOnBInWorld;
pointA = pointInWorld + normal * depth; pointA = pointInWorld + normal * depth;
localA = transAInv(pointA ); localA = transA.invXform(pointA );
localB = transBInv(pointInWorld); localB = transB.invXform(pointInWorld);
} }
btManifoldPoint newPt(localA,localB,normal,depth); btManifoldPoint newPt(localA,localB,normal,depth);
newPt.m_positionWorldOnA = pointA;
newPt.m_positionWorldOnB = pointInWorld;
int insertIndex = manifoldPtr->getCacheEntry(newPt); int insertIndex = manifoldPtr->getCacheEntry(newPt);
if (insertIndex >= 0) if (insertIndex >= 0)
{ {
// manifoldPtr->replaceContactPoint(newPt,insertIndex); // we need to replace the current contact point, otherwise small errors will accumulate (spheres start rolling etc)
// return true; manifoldPtr->replaceContactPoint(newPt,insertIndex);
return true;
#ifdef DEBUG_SPU_COLLISION_DETECTION
spu_printf("SPU: same contact detected, nothing done\n");
#endif //DEBUG_SPU_COLLISION_DETECTION
// This is not needed, just use the old info! saves a DMA transfer as well
} else } else
{ {
@@ -181,7 +181,12 @@ void SpuContactResult::writeDoubleBufferedManifold(btPersistentManifold* lsManif
void SpuContactResult::addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth) void SpuContactResult::addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth)
{ {
//spu_printf("*** SpuContactResult::addContactPoint: depth = %f\n",depth); #ifdef DEBUG_SPU_COLLISION_DETECTION
spu_printf("*** SpuContactResult::addContactPoint: depth = %f\n",depth);
spu_printf("*** normal = %f,%f,%f\n",normalOnBInWorld.getX(),normalOnBInWorld.getY(),normalOnBInWorld.getZ());
spu_printf("*** position = %f,%f,%f\n",pointInWorld.getX(),pointInWorld.getY(),pointInWorld.getZ());
#endif //DEBUG_SPU_COLLISION_DETECTION
#ifdef DEBUG_SPU_COLLISION_DETECTION #ifdef DEBUG_SPU_COLLISION_DETECTION
// int sman = sizeof(rage::phManifold); // int sman = sizeof(rage::phManifold);

View File

@@ -481,10 +481,10 @@ void ProcessConvexPlaneSpuCollision(SpuCollisionPairInput* wuInput, CollisionTas
} }
const btConvexShape* shape0Ptr = (const btConvexShape*)wuInput->m_spuCollisionShapes[0]; // const btConvexShape* shape0Ptr = (const btConvexShape*)wuInput->m_spuCollisionShapes[0];
const btConvexShape* shape1Ptr = (const btConvexShape*)wuInput->m_spuCollisionShapes[1]; // const btConvexShape* shape1Ptr = (const btConvexShape*)wuInput->m_spuCollisionShapes[1];
int shapeType0 = wuInput->m_shapeType0; // int shapeType0 = wuInput->m_shapeType0;
int shapeType1 = wuInput->m_shapeType1; // int shapeType1 = wuInput->m_shapeType1;
float marginA = wuInput->m_collisionMargin0; float marginA = wuInput->m_collisionMargin0;
float marginB = wuInput->m_collisionMargin1; float marginB = wuInput->m_collisionMargin1;