BulletMultiThreaded (SPU/multi-core): added compound shape support and concave-convex (swapped case). Thanks to Marten Svanfeldt
This commit is contained in:
@@ -45,7 +45,8 @@ bool SpuGatheringCollisionDispatcher::supportsDispatchPairOnSpu(int proxyType0,i
|
|||||||
(proxyType0 == CYLINDER_SHAPE_PROXYTYPE) ||
|
(proxyType0 == CYLINDER_SHAPE_PROXYTYPE) ||
|
||||||
// (proxyType0 == CONE_SHAPE_PROXYTYPE) ||
|
// (proxyType0 == CONE_SHAPE_PROXYTYPE) ||
|
||||||
(proxyType0 == TRIANGLE_MESH_SHAPE_PROXYTYPE) ||
|
(proxyType0 == TRIANGLE_MESH_SHAPE_PROXYTYPE) ||
|
||||||
(proxyType0 == CONVEX_HULL_SHAPE_PROXYTYPE)
|
(proxyType0 == CONVEX_HULL_SHAPE_PROXYTYPE)||
|
||||||
|
(proxyType0 == COMPOUND_SHAPE_PROXYTYPE)
|
||||||
);
|
);
|
||||||
|
|
||||||
bool supported1 = (
|
bool supported1 = (
|
||||||
@@ -56,7 +57,8 @@ bool SpuGatheringCollisionDispatcher::supportsDispatchPairOnSpu(int proxyType0,i
|
|||||||
(proxyType1 == CYLINDER_SHAPE_PROXYTYPE) ||
|
(proxyType1 == CYLINDER_SHAPE_PROXYTYPE) ||
|
||||||
// (proxyType1 == CONE_SHAPE_PROXYTYPE) ||
|
// (proxyType1 == CONE_SHAPE_PROXYTYPE) ||
|
||||||
(proxyType1 == TRIANGLE_MESH_SHAPE_PROXYTYPE) ||
|
(proxyType1 == TRIANGLE_MESH_SHAPE_PROXYTYPE) ||
|
||||||
(proxyType1 == CONVEX_HULL_SHAPE_PROXYTYPE)
|
(proxyType1 == CONVEX_HULL_SHAPE_PROXYTYPE) ||
|
||||||
|
(proxyType1 == COMPOUND_SHAPE_PROXYTYPE)
|
||||||
);
|
);
|
||||||
|
|
||||||
return supported0 && supported1;
|
return supported0 && supported1;
|
||||||
|
|||||||
@@ -34,13 +34,14 @@ SpuContactResult::SpuContactResult()
|
|||||||
g_manifoldDmaExport.swapBuffers();
|
g_manifoldDmaExport.swapBuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpuContactResult::setContactInfo(btPersistentManifold* spuManifold, uint64_t manifoldAddress,const btTransform& worldTrans0,const btTransform& worldTrans1)
|
void SpuContactResult::setContactInfo(btPersistentManifold* spuManifold, uint64_t manifoldAddress,const btTransform& worldTrans0,const btTransform& worldTrans1, bool isSwapped)
|
||||||
{
|
{
|
||||||
// spu_printf("SpuContactResult::setContactInfo\n");
|
//spu_printf("SpuContactResult::setContactInfo ManifoldAddress: %lu\n", manifoldAddress);
|
||||||
m_rootWorldTransform0 = worldTrans0;
|
m_rootWorldTransform0 = worldTrans0;
|
||||||
m_rootWorldTransform1 = worldTrans1;
|
m_rootWorldTransform1 = worldTrans1;
|
||||||
m_manifoldAddress = manifoldAddress;
|
m_manifoldAddress = manifoldAddress;
|
||||||
m_spuManifold = spuManifold;
|
m_spuManifold = spuManifold;
|
||||||
|
m_isSwapped = isSwapped;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpuContactResult::setShapeIdentifiers(int partId0,int index0, int partId1,int index1)
|
void SpuContactResult::setShapeIdentifiers(int partId0,int index0, int partId1,int index1)
|
||||||
@@ -56,8 +57,8 @@ bool ManifoldResultAddContactPoint(const btVector3& normalOnBInWorld,
|
|||||||
float depth,
|
float depth,
|
||||||
btPersistentManifold* manifoldPtr,
|
btPersistentManifold* manifoldPtr,
|
||||||
btTransform& transA,
|
btTransform& transA,
|
||||||
btTransform& transB
|
btTransform& transB,
|
||||||
)
|
bool isSwapped)
|
||||||
{
|
{
|
||||||
|
|
||||||
float contactTreshold = manifoldPtr->getContactBreakingThreshold();
|
float contactTreshold = manifoldPtr->getContactBreakingThreshold();
|
||||||
@@ -74,10 +75,29 @@ bool ManifoldResultAddContactPoint(const btVector3& normalOnBInWorld,
|
|||||||
btTransform transAInv = transA.inverse();//m_body0->m_cachedInvertedWorldTransform;
|
btTransform transAInv = transA.inverse();//m_body0->m_cachedInvertedWorldTransform;
|
||||||
btTransform transBInv= transB.inverse();//m_body1->m_cachedInvertedWorldTransform;
|
btTransform transBInv= transB.inverse();//m_body1->m_cachedInvertedWorldTransform;
|
||||||
|
|
||||||
btVector3 pointA = pointInWorld + normalOnBInWorld * depth;
|
btVector3 pointA;
|
||||||
btVector3 localA = transAInv(pointA );
|
btVector3 localA;
|
||||||
btVector3 localB = transBInv(pointInWorld);
|
btVector3 localB;
|
||||||
btManifoldPoint newPt(localA,localB,normalOnBInWorld,depth);
|
btVector3 normal;
|
||||||
|
|
||||||
|
if (isSwapped)
|
||||||
|
{
|
||||||
|
normal = normalOnBInWorld * -1;
|
||||||
|
pointA = pointInWorld + normal * depth;
|
||||||
|
localA = transAInv(pointA );
|
||||||
|
localB = transBInv(pointInWorld);
|
||||||
|
/*localA = transBInv(pointA );
|
||||||
|
localB = transAInv(pointInWorld);*/
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
normal = normalOnBInWorld;
|
||||||
|
pointA = pointInWorld + normal * depth;
|
||||||
|
localA = transAInv(pointA );
|
||||||
|
localB = transBInv(pointInWorld);
|
||||||
|
}
|
||||||
|
|
||||||
|
btManifoldPoint newPt(localA,localB,normal,depth);
|
||||||
|
|
||||||
int insertIndex = manifoldPtr->getCacheEntry(newPt);
|
int insertIndex = manifoldPtr->getCacheEntry(newPt);
|
||||||
if (insertIndex >= 0)
|
if (insertIndex >= 0)
|
||||||
@@ -146,8 +166,8 @@ void SpuContactResult::addContactPoint(const btVector3& normalOnBInWorld,const b
|
|||||||
depth,
|
depth,
|
||||||
localManifold,
|
localManifold,
|
||||||
m_rootWorldTransform0,
|
m_rootWorldTransform0,
|
||||||
m_rootWorldTransform1
|
m_rootWorldTransform1,
|
||||||
);
|
m_isSwapped);
|
||||||
m_RequiresWriteBack = m_RequiresWriteBack || retVal;
|
m_RequiresWriteBack = m_RequiresWriteBack || retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,7 +176,9 @@ void SpuContactResult::flush()
|
|||||||
if (m_RequiresWriteBack)
|
if (m_RequiresWriteBack)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_SPU_COLLISION_DETECTION
|
#ifdef DEBUG_SPU_COLLISION_DETECTION
|
||||||
spu_printf("SPU: Start rage::phManifold Write (Put) DMA\n");
|
spu_printf("SPU: Start SpuContactResult::flush (Put) DMA\n");
|
||||||
|
spu_printf("Num contacts:%d\n", m_spuManifold->getNumContacts());
|
||||||
|
spu_printf("Manifold address: %llu\n", m_manifoldAddress);
|
||||||
#endif //DEBUG_SPU_COLLISION_DETECTION
|
#endif //DEBUG_SPU_COLLISION_DETECTION
|
||||||
// spu_printf("writeDoubleBufferedManifold\n");
|
// spu_printf("writeDoubleBufferedManifold\n");
|
||||||
writeDoubleBufferedManifold(m_spuManifold, (btPersistentManifold*)m_manifoldAddress);
|
writeDoubleBufferedManifold(m_spuManifold, (btPersistentManifold*)m_manifoldAddress);
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ class SpuContactResult
|
|||||||
|
|
||||||
btPersistentManifold* m_spuManifold;
|
btPersistentManifold* m_spuManifold;
|
||||||
bool m_RequiresWriteBack;
|
bool m_RequiresWriteBack;
|
||||||
|
bool m_isSwapped;
|
||||||
|
|
||||||
DoubleBuffer<btPersistentManifold, 1> g_manifoldDmaExport;
|
DoubleBuffer<btPersistentManifold, 1> g_manifoldDmaExport;
|
||||||
|
|
||||||
@@ -95,7 +96,7 @@ class SpuContactResult
|
|||||||
|
|
||||||
virtual void setShapeIdentifiers(int partId0,int index0, int partId1,int index1);
|
virtual void setShapeIdentifiers(int partId0,int index0, int partId1,int index1);
|
||||||
|
|
||||||
void setContactInfo(btPersistentManifold* spuManifold, uint64_t manifoldAddress,const btTransform& worldTrans0,const btTransform& worldTrans1);
|
void setContactInfo(btPersistentManifold* spuManifold, uint64_t manifoldAddress,const btTransform& worldTrans0,const btTransform& worldTrans1, bool isSwapped = false);
|
||||||
|
|
||||||
void writeDoubleBufferedManifold(btPersistentManifold* lsManifold, btPersistentManifold* mmManifold);
|
void writeDoubleBufferedManifold(btPersistentManifold* lsManifold, btPersistentManifold* mmManifold);
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#include "BulletCollision/CollisionShapes/btConvexShape.h"
|
#include "BulletCollision/CollisionShapes/btConvexShape.h"
|
||||||
#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h"
|
#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h"
|
||||||
#include "BulletCollision/CollisionShapes/btConvexHullShape.h"
|
#include "BulletCollision/CollisionShapes/btConvexHullShape.h"
|
||||||
|
#include "BulletCollision/CollisionShapes/btCompoundShape.h"
|
||||||
|
|
||||||
#include "SpuMinkowskiPenetrationDepthSolver.h"
|
#include "SpuMinkowskiPenetrationDepthSolver.h"
|
||||||
#include "SpuGjkPairDetector.h"
|
#include "SpuGjkPairDetector.h"
|
||||||
@@ -26,6 +27,9 @@
|
|||||||
|
|
||||||
#include "SpuLocalSupport.h" //definition of SpuConvexPolyhedronVertexData
|
#include "SpuLocalSupport.h" //definition of SpuConvexPolyhedronVertexData
|
||||||
|
|
||||||
|
#ifdef USE_SN_TUNER
|
||||||
|
#include <LibSN_SPU.h>
|
||||||
|
#endif //USE_SN_TUNER
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
|
||||||
@@ -87,6 +91,10 @@ struct CollisionTask_LocalStoreMemory
|
|||||||
|
|
||||||
SpuConvexPolyhedronVertexData convexVertexData;
|
SpuConvexPolyhedronVertexData convexVertexData;
|
||||||
|
|
||||||
|
// Compound data
|
||||||
|
#define MAX_SPU_COMPOUND_SUBSHAPES 16
|
||||||
|
ATTRIBUTE_ALIGNED16(btCompoundShapeChild gSubshapes[MAX_SPU_COMPOUND_SUBSHAPES*2]);
|
||||||
|
ATTRIBUTE_ALIGNED16(char gSubshapeShape[MAX_SPU_COMPOUND_SUBSHAPES*2][MAX_SHAPE_SIZE]);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -532,6 +540,13 @@ int getShapeTypeSize(int shapeType)
|
|||||||
return shapeSize;
|
return shapeSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case COMPOUND_SHAPE_PROXYTYPE:
|
||||||
|
{
|
||||||
|
int shapeSize = sizeof(btCompoundShape);
|
||||||
|
btAssert(shapeSize < MAX_SHAPE_SIZE);
|
||||||
|
return shapeSize;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
btAssert(0);
|
btAssert(0);
|
||||||
//unsupported shapetype, please add here
|
//unsupported shapetype, please add here
|
||||||
@@ -653,13 +668,13 @@ void ProcessSpuConvexConvexCollision(SpuCollisionPairInput* wuInput, CollisionTa
|
|||||||
cpInput.m_convexVertexData = &lsMemPtr->convexVertexData;
|
cpInput.m_convexVertexData = &lsMemPtr->convexVertexData;
|
||||||
cpInput.m_transformA = wuInput->m_worldTransform0;
|
cpInput.m_transformA = wuInput->m_worldTransform0;
|
||||||
cpInput.m_transformB = wuInput->m_worldTransform1;
|
cpInput.m_transformB = wuInput->m_worldTransform1;
|
||||||
float sumMargin = (marginA+marginB);
|
float sumMargin = (marginA+marginB+lsMemPtr->gPersistentManifold.getContactBreakingThreshold());
|
||||||
cpInput.m_maximumDistanceSquared = sumMargin * sumMargin;
|
cpInput.m_maximumDistanceSquared = sumMargin * sumMargin;
|
||||||
|
|
||||||
uint64_t manifoldAddress = (uint64_t)manifold;
|
uint64_t manifoldAddress = (uint64_t)manifold;
|
||||||
btPersistentManifold* spuManifold=&lsMemPtr->gPersistentManifold;
|
btPersistentManifold* spuManifold=&lsMemPtr->gPersistentManifold;
|
||||||
spuContacts.setContactInfo(spuManifold,manifoldAddress,wuInput->m_worldTransform0,wuInput->m_worldTransform1);
|
//spuContacts.setContactInfo(spuManifold,manifoldAddress,wuInput->m_worldTransform0,wuInput->m_worldTransform1,wuInput->m_isSwapped);
|
||||||
|
spuContacts.setContactInfo(spuManifold,manifoldAddress,lsMemPtr->gColObj0.getWorldTransform(),lsMemPtr->gColObj1.getWorldTransform(),wuInput->m_isSwapped);
|
||||||
|
|
||||||
SpuGjkPairDetector gjk(shape0Ptr,shape1Ptr,shapeType0,shapeType1,marginA,marginB,&vsSolver,&penetrationSolver);
|
SpuGjkPairDetector gjk(shape0Ptr,shape1Ptr,shapeType0,shapeType1,marginA,marginB,&vsSolver,&penetrationSolver);
|
||||||
gjk.getClosestPoints(cpInput,spuContacts);//,debugDraw);
|
gjk.getClosestPoints(cpInput,spuContacts);//,debugDraw);
|
||||||
@@ -668,7 +683,345 @@ void ProcessSpuConvexConvexCollision(SpuCollisionPairInput* wuInput, CollisionTa
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void DoSwap(T& a, T& b)
|
||||||
|
{
|
||||||
|
char tmp[sizeof(T)];
|
||||||
|
memcpy(tmp, &a, sizeof(T));
|
||||||
|
memcpy(&a, &b, sizeof(T));
|
||||||
|
memcpy(&b, tmp, sizeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
void dmaAndSetupCollisionObjects(SpuCollisionPairInput& collisionPairInput, CollisionTask_LocalStoreMemory& lsMem)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
int dmaSize = sizeof(btCollisionObject);
|
||||||
|
uint64_t dmaPpuAddress2 = /*collisionPairInput.m_isSwapped ? (uint64_t)lsMem.gProxyPtr1->m_clientObject :*/ (uint64_t)lsMem.gProxyPtr0->m_clientObject;
|
||||||
|
cellDmaGet(&lsMem.gColObj0, dmaPpuAddress2 , dmaSize, DMA_TAG(1), 0, 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
int dmaSize = sizeof(btCollisionObject);
|
||||||
|
uint64_t dmaPpuAddress2 = /*collisionPairInput.m_isSwapped ? (uint64_t)lsMem.gProxyPtr0->m_clientObject :*/ (uint64_t)lsMem.gProxyPtr1->m_clientObject;
|
||||||
|
cellDmaGet(&lsMem.gColObj1, dmaPpuAddress2 , dmaSize, DMA_TAG(2), 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
cellDmaWaitTagStatusAll(DMA_MASK(1) | DMA_MASK(2));
|
||||||
|
|
||||||
|
collisionPairInput.m_worldTransform0 = lsMem.gColObj0.getWorldTransform();
|
||||||
|
collisionPairInput.m_worldTransform1 = lsMem.gColObj1.getWorldTransform();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef DEBUG_SPU_COLLISION_DETECTION
|
||||||
|
spu_printf("SPU worldTrans0.origin = (%f,%f,%f)\n",
|
||||||
|
collisionPairInput->m_worldTransform0.getOrigin().getX(),
|
||||||
|
collisionPairInput->m_worldTransform0.getOrigin().getY(),
|
||||||
|
collisionPairInput->m_worldTransform0.getOrigin().getZ());
|
||||||
|
|
||||||
|
spu_printf("SPU worldTrans1.origin = (%f,%f,%f)\n",
|
||||||
|
collisionPairInput->m_worldTransform1.getOrigin().getX(),
|
||||||
|
collisionPairInput->m_worldTransform1.getOrigin().getY(),
|
||||||
|
collisionPairInput->m_worldTransform1.getOrigin().getZ());
|
||||||
|
#endif //DEBUG_SPU_COLLISION_DETECTION
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleCollisionPair(SpuCollisionPairInput& collisionPairInput, CollisionTask_LocalStoreMemory& lsMem,
|
||||||
|
SpuContactResult &spuContacts,
|
||||||
|
uint64_t collisionShape0Ptr, void* collisionShape0Loc,
|
||||||
|
uint64_t collisionShape1Ptr, void* collisionShape1Loc, bool dmaShapes = true)
|
||||||
|
{
|
||||||
|
if (btBroadphaseProxy::isConvex(collisionPairInput.m_shapeType0)
|
||||||
|
&& btBroadphaseProxy::isConvex(collisionPairInput.m_shapeType1))
|
||||||
|
{
|
||||||
|
|
||||||
|
//dmaAndSetupCollisionObjects(collisionPairInput, lsMem);
|
||||||
|
|
||||||
|
if (dmaShapes)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
int dmaSize = getShapeTypeSize(collisionPairInput.m_shapeType0);
|
||||||
|
//uint64_t dmaPpuAddress2 = (uint64_t)lsMem.gColObj0.getCollisionShape();
|
||||||
|
uint64_t dmaPpuAddress2 = collisionShape0Ptr;
|
||||||
|
cellDmaGet(collisionShape0Loc, dmaPpuAddress2 , dmaSize, DMA_TAG(1), 0, 0);
|
||||||
|
cellDmaWaitTagStatusAll(DMA_MASK(1));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
int dmaSize = getShapeTypeSize(collisionPairInput.m_shapeType1);
|
||||||
|
uint64_t dmaPpuAddress2 = collisionShape1Ptr;
|
||||||
|
cellDmaGet(collisionShape1Loc, dmaPpuAddress2 , dmaSize, DMA_TAG(2), 0, 0);
|
||||||
|
cellDmaWaitTagStatusAll(DMA_MASK(2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
btConvexInternalShape* spuConvexShape0 = (btConvexInternalShape*)collisionShape0Loc;
|
||||||
|
btConvexInternalShape* spuConvexShape1 = (btConvexInternalShape*)collisionShape1Loc;
|
||||||
|
|
||||||
|
btVector3 dim0 = spuConvexShape0->getImplicitShapeDimensions();
|
||||||
|
btVector3 dim1 = spuConvexShape1->getImplicitShapeDimensions();
|
||||||
|
|
||||||
|
collisionPairInput.m_primitiveDimensions0 = dim0;
|
||||||
|
collisionPairInput.m_primitiveDimensions1 = dim1;
|
||||||
|
collisionPairInput.m_collisionShapes[0] = collisionShape0Ptr;
|
||||||
|
collisionPairInput.m_collisionShapes[1] = collisionShape1Ptr;
|
||||||
|
collisionPairInput.m_spuCollisionShapes[0] = spuConvexShape0;
|
||||||
|
collisionPairInput.m_spuCollisionShapes[1] = spuConvexShape1;
|
||||||
|
ProcessSpuConvexConvexCollision(&collisionPairInput,&lsMem,spuContacts);
|
||||||
|
}
|
||||||
|
else if (btBroadphaseProxy::isCompound(collisionPairInput.m_shapeType0) &&
|
||||||
|
btBroadphaseProxy::isCompound(collisionPairInput.m_shapeType1))
|
||||||
|
{
|
||||||
|
//snPause();
|
||||||
|
|
||||||
|
// Both are compounds, do N^2 CD for now
|
||||||
|
// TODO: add some AABB-based pruning
|
||||||
|
{
|
||||||
|
int dmaSize = getShapeTypeSize(collisionPairInput.m_shapeType0);
|
||||||
|
uint64_t dmaPpuAddress2 = collisionShape0Ptr;
|
||||||
|
cellDmaGet(collisionShape0Loc, dmaPpuAddress2 , dmaSize, DMA_TAG(1), 0, 0);
|
||||||
|
cellDmaWaitTagStatusAll(DMA_MASK(1));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
int dmaSize = getShapeTypeSize(collisionPairInput.m_shapeType1);
|
||||||
|
uint64_t dmaPpuAddress2 = collisionShape1Ptr;
|
||||||
|
cellDmaGet(collisionShape1Loc, dmaPpuAddress2 , dmaSize, DMA_TAG(2), 0, 0);
|
||||||
|
cellDmaWaitTagStatusAll(DMA_MASK(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
btCompoundShape* spuCompoundShape0 = (btCompoundShape*)collisionShape0Loc;
|
||||||
|
btCompoundShape* spuCompoundShape1 = (btCompoundShape*)collisionShape1Loc;
|
||||||
|
|
||||||
|
int childShapeCount0 = spuCompoundShape0->getNumChildShapes();
|
||||||
|
int childShapeCount1 = spuCompoundShape1->getNumChildShapes();
|
||||||
|
|
||||||
|
// dma the first list of child shapes
|
||||||
|
{
|
||||||
|
int dmaSize = childShapeCount0 * sizeof(btCompoundShapeChild);
|
||||||
|
uint64_t dmaPpuAddress2 = (uint64_t)spuCompoundShape0->getChildList();
|
||||||
|
cellDmaGet(lsMem.gSubshapes, dmaPpuAddress2, dmaSize, DMA_TAG(1), 0, 0);
|
||||||
|
cellDmaWaitTagStatusAll(DMA_MASK(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
// dma the second list of child shapes
|
||||||
|
{
|
||||||
|
int dmaSize = childShapeCount1 * sizeof(btCompoundShapeChild);
|
||||||
|
uint64_t dmaPpuAddress2 = (uint64_t)spuCompoundShape1->getChildList();
|
||||||
|
cellDmaGet(&lsMem.gSubshapes[MAX_SPU_COMPOUND_SUBSHAPES], dmaPpuAddress2, dmaSize, DMA_TAG(2), 0, 0);
|
||||||
|
cellDmaWaitTagStatusAll(DMA_MASK(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
// DMA all the subshapes
|
||||||
|
for (int i = 0; i < childShapeCount0; ++i)
|
||||||
|
{
|
||||||
|
btCompoundShapeChild& childShape = lsMem.gSubshapes[i];
|
||||||
|
|
||||||
|
int dmaSize = getShapeTypeSize(childShape.m_childShapeType);
|
||||||
|
uint64_t dmaPpuAddress2 = (uint64_t)childShape.m_childShape;
|
||||||
|
cellDmaGet(lsMem.gSubshapeShape[i], dmaPpuAddress2, dmaSize, DMA_TAG(1), 0, 0);
|
||||||
|
cellDmaWaitTagStatusAll(DMA_MASK(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < childShapeCount1; ++i)
|
||||||
|
{
|
||||||
|
btCompoundShapeChild& childShape = lsMem.gSubshapes[MAX_SPU_COMPOUND_SUBSHAPES+i];
|
||||||
|
|
||||||
|
int dmaSize = getShapeTypeSize(childShape.m_childShapeType);
|
||||||
|
uint64_t dmaPpuAddress2 = (uint64_t)childShape.m_childShape;
|
||||||
|
cellDmaGet(lsMem.gSubshapeShape[MAX_SPU_COMPOUND_SUBSHAPES+i], dmaPpuAddress2, dmaSize, DMA_TAG(1), 0, 0);
|
||||||
|
cellDmaWaitTagStatusAll(DMA_MASK(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start the N^2
|
||||||
|
for (int i = 0; i < childShapeCount0; ++i)
|
||||||
|
{
|
||||||
|
btCompoundShapeChild& childShape0 = lsMem.gSubshapes[i];
|
||||||
|
|
||||||
|
for (int j = 0; j < childShapeCount1; ++j)
|
||||||
|
{
|
||||||
|
btCompoundShapeChild& childShape1 = lsMem.gSubshapes[MAX_SPU_COMPOUND_SUBSHAPES+j];
|
||||||
|
|
||||||
|
SpuCollisionPairInput cinput (collisionPairInput);
|
||||||
|
cinput.m_worldTransform0 = collisionPairInput.m_worldTransform0 * childShape0.m_transform;
|
||||||
|
cinput.m_shapeType0 = childShape0.m_childShapeType;
|
||||||
|
cinput.m_collisionMargin0 = childShape0.m_childMargin;
|
||||||
|
|
||||||
|
cinput.m_worldTransform1 = collisionPairInput.m_worldTransform1 * childShape1.m_transform;
|
||||||
|
cinput.m_shapeType1 = childShape1.m_childShapeType;
|
||||||
|
cinput.m_collisionMargin1 = childShape1.m_childMargin;
|
||||||
|
|
||||||
|
handleCollisionPair(cinput, lsMem, spuContacts,
|
||||||
|
(uint64_t)childShape0.m_childShape, lsMem.gSubshapeShape[i],
|
||||||
|
(uint64_t)childShape1.m_childShape, lsMem.gSubshapeShape[MAX_SPU_COMPOUND_SUBSHAPES+i], false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (btBroadphaseProxy::isCompound(collisionPairInput.m_shapeType0) )
|
||||||
|
{
|
||||||
|
//snPause();
|
||||||
|
{
|
||||||
|
int dmaSize = getShapeTypeSize(collisionPairInput.m_shapeType0);
|
||||||
|
uint64_t dmaPpuAddress2 = collisionShape0Ptr;
|
||||||
|
cellDmaGet(collisionShape0Loc, dmaPpuAddress2 , dmaSize, DMA_TAG(1), 0, 0);
|
||||||
|
cellDmaWaitTagStatusAll(DMA_MASK(1));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
int dmaSize = getShapeTypeSize(collisionPairInput.m_shapeType1);
|
||||||
|
uint64_t dmaPpuAddress2 = collisionShape1Ptr;
|
||||||
|
cellDmaGet(collisionShape1Loc, dmaPpuAddress2 , dmaSize, DMA_TAG(2), 0, 0);
|
||||||
|
cellDmaWaitTagStatusAll(DMA_MASK(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
// object 0 compound, object 1 non-compound
|
||||||
|
btCompoundShape* spuCompoundShape = (btCompoundShape*)collisionShape0Loc;
|
||||||
|
|
||||||
|
int childShapeCount = spuCompoundShape->getNumChildShapes();
|
||||||
|
|
||||||
|
// dma the list of child shapes
|
||||||
|
{
|
||||||
|
int dmaSize = childShapeCount * sizeof(btCompoundShapeChild);
|
||||||
|
uint64_t dmaPpuAddress2 = (uint64_t)spuCompoundShape->getChildList();
|
||||||
|
cellDmaGet(lsMem.gSubshapes, dmaPpuAddress2, dmaSize, DMA_TAG(1), 0, 0);
|
||||||
|
cellDmaWaitTagStatusAll(DMA_MASK(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < childShapeCount; ++i)
|
||||||
|
{
|
||||||
|
btCompoundShapeChild& childShape = lsMem.gSubshapes[i];
|
||||||
|
|
||||||
|
// Dma the child shape
|
||||||
|
{
|
||||||
|
int dmaSize = getShapeTypeSize(childShape.m_childShapeType);
|
||||||
|
uint64_t dmaPpuAddress2 = (uint64_t)childShape.m_childShape;
|
||||||
|
cellDmaGet(lsMem.gSubshapeShape[i], dmaPpuAddress2, dmaSize, DMA_TAG(1), 0, 0);
|
||||||
|
cellDmaWaitTagStatusAll(DMA_MASK(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
SpuCollisionPairInput cinput (collisionPairInput);
|
||||||
|
cinput.m_worldTransform0 = collisionPairInput.m_worldTransform0 * childShape.m_transform;
|
||||||
|
cinput.m_shapeType0 = childShape.m_childShapeType;
|
||||||
|
cinput.m_collisionMargin0 = childShape.m_childMargin;
|
||||||
|
|
||||||
|
handleCollisionPair(cinput, lsMem, spuContacts,
|
||||||
|
(uint64_t)childShape.m_childShape, lsMem.gSubshapeShape[i],
|
||||||
|
collisionShape1Ptr, collisionShape1Loc, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (btBroadphaseProxy::isCompound(collisionPairInput.m_shapeType1) )
|
||||||
|
{
|
||||||
|
//snPause();
|
||||||
|
{
|
||||||
|
int dmaSize = getShapeTypeSize(collisionPairInput.m_shapeType0);
|
||||||
|
uint64_t dmaPpuAddress2 = collisionShape0Ptr;
|
||||||
|
cellDmaGet(collisionShape0Loc, dmaPpuAddress2 , dmaSize, DMA_TAG(1), 0, 0);
|
||||||
|
cellDmaWaitTagStatusAll(DMA_MASK(1));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
int dmaSize = getShapeTypeSize(collisionPairInput.m_shapeType1);
|
||||||
|
uint64_t dmaPpuAddress2 = collisionShape1Ptr;
|
||||||
|
cellDmaGet(collisionShape1Loc, dmaPpuAddress2 , dmaSize, DMA_TAG(2), 0, 0);
|
||||||
|
cellDmaWaitTagStatusAll(DMA_MASK(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
// object 0 non-compound, object 1 compound
|
||||||
|
btCompoundShape* spuCompoundShape = (btCompoundShape*)collisionShape1Loc;
|
||||||
|
|
||||||
|
int childShapeCount = spuCompoundShape->getNumChildShapes();
|
||||||
|
|
||||||
|
// dma the list of child shapes
|
||||||
|
{
|
||||||
|
int dmaSize = childShapeCount * sizeof(btCompoundShapeChild);
|
||||||
|
uint64_t dmaPpuAddress2 = (uint64_t)spuCompoundShape->getChildList();
|
||||||
|
cellDmaGet(lsMem.gSubshapes, dmaPpuAddress2, dmaSize, DMA_TAG(1), 0, 0);
|
||||||
|
cellDmaWaitTagStatusAll(DMA_MASK(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < childShapeCount; ++i)
|
||||||
|
{
|
||||||
|
btCompoundShapeChild& childShape = lsMem.gSubshapes[i];
|
||||||
|
|
||||||
|
// Dma the child shape
|
||||||
|
{
|
||||||
|
int dmaSize = getShapeTypeSize(childShape.m_childShapeType);
|
||||||
|
uint64_t dmaPpuAddress2 = (uint64_t)childShape.m_childShape;
|
||||||
|
cellDmaGet(lsMem.gSubshapeShape[i], dmaPpuAddress2, dmaSize, DMA_TAG(1), 0, 0);
|
||||||
|
cellDmaWaitTagStatusAll(DMA_MASK(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
SpuCollisionPairInput cinput (collisionPairInput);
|
||||||
|
cinput.m_worldTransform1 = collisionPairInput.m_worldTransform1 * childShape.m_transform;
|
||||||
|
cinput.m_shapeType1 = childShape.m_childShapeType;
|
||||||
|
cinput.m_collisionMargin1 = childShape.m_childMargin;
|
||||||
|
|
||||||
|
handleCollisionPair(cinput, lsMem, spuContacts,
|
||||||
|
collisionShape0Ptr, collisionShape0Loc,
|
||||||
|
(uint64_t)childShape.m_childShape, lsMem.gSubshapeShape[i], false);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//a non-convex shape is involved
|
||||||
|
bool handleConvexConcave = false;
|
||||||
|
|
||||||
|
//snPause();
|
||||||
|
|
||||||
|
if (btBroadphaseProxy::isConcave(collisionPairInput.m_shapeType0) &&
|
||||||
|
btBroadphaseProxy::isConvex(collisionPairInput.m_shapeType1))
|
||||||
|
{
|
||||||
|
// Swap stuff
|
||||||
|
DoSwap(collisionShape0Ptr, collisionShape1Ptr);
|
||||||
|
DoSwap(collisionShape0Loc, collisionShape1Loc);
|
||||||
|
DoSwap(collisionPairInput.m_shapeType0, collisionPairInput.m_shapeType1);
|
||||||
|
DoSwap(collisionPairInput.m_worldTransform0, collisionPairInput.m_worldTransform1);
|
||||||
|
DoSwap(collisionPairInput.m_collisionMargin0, collisionPairInput.m_collisionMargin1);
|
||||||
|
|
||||||
|
collisionPairInput.m_isSwapped = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (btBroadphaseProxy::isConvex(collisionPairInput.m_shapeType0)&&
|
||||||
|
btBroadphaseProxy::isConcave(collisionPairInput.m_shapeType1))
|
||||||
|
{
|
||||||
|
handleConvexConcave = true;
|
||||||
|
}
|
||||||
|
if (handleConvexConcave)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (dmaShapes)
|
||||||
|
{
|
||||||
|
///dma and initialize the convex object
|
||||||
|
{
|
||||||
|
int dmaSize = getShapeTypeSize(collisionPairInput.m_shapeType0);
|
||||||
|
//uint64_t dmaPpuAddress2 = (uint64_t)lsMem.gColObj0.getCollisionShape();
|
||||||
|
uint64_t dmaPpuAddress2 = collisionShape0Ptr;
|
||||||
|
cellDmaGet(collisionShape0Loc, dmaPpuAddress2 , dmaSize, DMA_TAG(1), 0, 0);
|
||||||
|
cellDmaWaitTagStatusAll(DMA_MASK(1));
|
||||||
|
}
|
||||||
|
///dma and initialize the concave object
|
||||||
|
{
|
||||||
|
int dmaSize = getShapeTypeSize(collisionPairInput.m_shapeType1);
|
||||||
|
uint64_t dmaPpuAddress2 = collisionShape1Ptr;
|
||||||
|
cellDmaGet(collisionShape1Loc, dmaPpuAddress2 , dmaSize, DMA_TAG(2), 0, 0);
|
||||||
|
cellDmaWaitTagStatusAll(DMA_MASK(2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
btConvexInternalShape* spuConvexShape0 = (btConvexInternalShape*)collisionShape0Loc;
|
||||||
|
btBvhTriangleMeshShape* trimeshShape = (btBvhTriangleMeshShape*)collisionShape1Loc;
|
||||||
|
|
||||||
|
btVector3 dim0 = spuConvexShape0->getImplicitShapeDimensions();
|
||||||
|
collisionPairInput.m_primitiveDimensions0 = dim0;
|
||||||
|
collisionPairInput.m_collisionShapes[0] = collisionShape0Ptr;
|
||||||
|
collisionPairInput.m_collisionShapes[1] = collisionShape1Ptr;
|
||||||
|
collisionPairInput.m_spuCollisionShapes[0] = spuConvexShape0;
|
||||||
|
collisionPairInput.m_spuCollisionShapes[1] = trimeshShape;
|
||||||
|
|
||||||
|
ProcessConvexConcaveSpuCollision(&collisionPairInput,&lsMem,spuContacts);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
spuContacts.flush();
|
||||||
|
}
|
||||||
|
|
||||||
void processCollisionTask(void* userPtr, void* lsMemPtr)
|
void processCollisionTask(void* userPtr, void* lsMemPtr)
|
||||||
{
|
{
|
||||||
@@ -761,6 +1114,8 @@ void processCollisionTask(void* userPtr, void* lsMemPtr)
|
|||||||
|
|
||||||
SpuCollisionPairInput collisionPairInput;
|
SpuCollisionPairInput collisionPairInput;
|
||||||
collisionPairInput.m_persistentManifoldPtr = (uint64_t) lsMem.gSpuContactManifoldAlgo.getContactManifoldPtr();
|
collisionPairInput.m_persistentManifoldPtr = (uint64_t) lsMem.gSpuContactManifoldAlgo.getContactManifoldPtr();
|
||||||
|
collisionPairInput.m_isSwapped = false;
|
||||||
|
//snPause();
|
||||||
|
|
||||||
#ifdef DEBUG_SPU_COLLISION_DETECTION
|
#ifdef DEBUG_SPU_COLLISION_DETECTION
|
||||||
spu_printf("SPU: manifoldPtr: %llx",collisionPairInput->m_persistentManifoldPtr);
|
spu_printf("SPU: manifoldPtr: %llx",collisionPairInput->m_persistentManifoldPtr);
|
||||||
@@ -785,23 +1140,10 @@ void processCollisionTask(void* userPtr, void* lsMemPtr)
|
|||||||
//btCollisionObject* colObj0 = (btCollisionObject*)gProxy0.m_clientObject;
|
//btCollisionObject* colObj0 = (btCollisionObject*)gProxy0.m_clientObject;
|
||||||
//btCollisionObject* colObj1 = (btCollisionObject*)gProxy1.m_clientObject;
|
//btCollisionObject* colObj1 = (btCollisionObject*)gProxy1.m_clientObject;
|
||||||
|
|
||||||
{
|
|
||||||
int dmaSize = sizeof(btCollisionObject);
|
|
||||||
uint64_t dmaPpuAddress2 = (uint64_t)lsMem.gProxyPtr0->m_clientObject;
|
|
||||||
cellDmaGet(&lsMem.gColObj0, dmaPpuAddress2 , dmaSize, DMA_TAG(1), 0, 0);
|
|
||||||
cellDmaWaitTagStatusAll(DMA_MASK(1));
|
|
||||||
}
|
|
||||||
{
|
|
||||||
int dmaSize = sizeof(btCollisionObject);
|
|
||||||
uint64_t dmaPpuAddress2 = (uint64_t)lsMem.gProxyPtr1->m_clientObject;
|
|
||||||
cellDmaGet(&lsMem.gColObj1, dmaPpuAddress2 , dmaSize, DMA_TAG(2), 0, 0);
|
|
||||||
cellDmaWaitTagStatusAll(DMA_MASK(2));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (1)
|
if (1)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
///can wait on the combined DMA_MASK, or dma on the same tag
|
///can wait on the combined DMA_MASK, or dma on the same tag
|
||||||
|
|
||||||
collisionPairInput.m_shapeType0 = lsMem.gSpuContactManifoldAlgo.getShapeType0();
|
collisionPairInput.m_shapeType0 = lsMem.gSpuContactManifoldAlgo.getShapeType0();
|
||||||
@@ -814,152 +1156,24 @@ void processCollisionTask(void* userPtr, void* lsMemPtr)
|
|||||||
spu_printf("SPU collisionPairInput->m_shapeType1 = %d\n",collisionPairInput->m_shapeType1);
|
spu_printf("SPU collisionPairInput->m_shapeType1 = %d\n",collisionPairInput->m_shapeType1);
|
||||||
#endif //DEBUG_SPU_COLLISION_DETECTION
|
#endif //DEBUG_SPU_COLLISION_DETECTION
|
||||||
|
|
||||||
if (1)
|
|
||||||
{
|
|
||||||
|
|
||||||
collisionPairInput.m_worldTransform0 = lsMem.gColObj0.getWorldTransform();
|
|
||||||
collisionPairInput.m_worldTransform1 = lsMem.gColObj1.getWorldTransform();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG_SPU_COLLISION_DETECTION
|
|
||||||
spu_printf("SPU worldTrans0.origin = (%f,%f,%f)\n",
|
|
||||||
collisionPairInput->m_worldTransform0.getOrigin().getX(),
|
|
||||||
collisionPairInput->m_worldTransform0.getOrigin().getY(),
|
|
||||||
collisionPairInput->m_worldTransform0.getOrigin().getZ());
|
|
||||||
|
|
||||||
spu_printf("SPU worldTrans1.origin = (%f,%f,%f)\n",
|
|
||||||
collisionPairInput->m_worldTransform1.getOrigin().getX(),
|
|
||||||
collisionPairInput->m_worldTransform1.getOrigin().getY(),
|
|
||||||
collisionPairInput->m_worldTransform1.getOrigin().getZ());
|
|
||||||
#endif //DEBUG_SPU_COLLISION_DETECTION
|
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
int dmaSize = sizeof(btPersistentManifold);
|
int dmaSize = sizeof(btPersistentManifold);
|
||||||
|
|
||||||
uint64_t dmaPpuAddress2 = collisionPairInput.m_persistentManifoldPtr;
|
uint64_t dmaPpuAddress2 = collisionPairInput.m_persistentManifoldPtr;
|
||||||
if (dmaPpuAddress2 & 0x0f)
|
|
||||||
{
|
|
||||||
#ifndef IGNORE_ALIGNMENT
|
|
||||||
spu_printf("SPU ALIGNMENT ERROR\n");
|
|
||||||
|
|
||||||
spuContacts.flush();
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
cellDmaGet(&lsMem.gPersistentManifold, dmaPpuAddress2 , dmaSize, DMA_TAG(1), 0, 0);
|
cellDmaGet(&lsMem.gPersistentManifold, dmaPpuAddress2 , dmaSize, DMA_TAG(1), 0, 0);
|
||||||
cellDmaWaitTagStatusAll(DMA_MASK(1));
|
cellDmaWaitTagStatusAll(DMA_MASK(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (btBroadphaseProxy::isConvex(collisionPairInput.m_shapeType0)
|
if (1)
|
||||||
&& btBroadphaseProxy::isConvex(collisionPairInput.m_shapeType1))
|
|
||||||
{
|
{
|
||||||
|
//snPause();
|
||||||
|
|
||||||
{
|
// Get the collision objects
|
||||||
int dmaSize = getShapeTypeSize(collisionPairInput.m_shapeType0);
|
dmaAndSetupCollisionObjects(collisionPairInput, lsMem);
|
||||||
uint64_t dmaPpuAddress2 = (uint64_t)lsMem.gColObj0.getCollisionShape();
|
|
||||||
cellDmaGet(lsMem.gCollisionShape0, dmaPpuAddress2 , dmaSize, DMA_TAG(1), 0, 0);
|
|
||||||
cellDmaWaitTagStatusAll(DMA_MASK(1));
|
|
||||||
}
|
|
||||||
{
|
|
||||||
int dmaSize = getShapeTypeSize(collisionPairInput.m_shapeType1);
|
|
||||||
uint64_t dmaPpuAddress2 = (uint64_t)lsMem.gColObj1.getCollisionShape();
|
|
||||||
if (dmaPpuAddress2 & 0x0f)
|
|
||||||
{
|
|
||||||
#ifndef IGNORE_ALIGNMENT
|
|
||||||
spu_printf("SPU ALIGNMENT ERROR2\n");
|
|
||||||
|
|
||||||
spuContacts.flush();
|
|
||||||
return;
|
|
||||||
#endif //IGNORE_ALIGNMENT
|
|
||||||
}
|
|
||||||
cellDmaGet(lsMem.gCollisionShape1, dmaPpuAddress2 , dmaSize, DMA_TAG(2), 0, 0);
|
|
||||||
cellDmaWaitTagStatusAll(DMA_MASK(2));
|
|
||||||
}
|
|
||||||
|
|
||||||
btConvexInternalShape* spuConvexShape0 = (btConvexInternalShape*)lsMem.gCollisionShape0;
|
|
||||||
btConvexInternalShape* spuConvexShape1 = (btConvexInternalShape*)lsMem.gCollisionShape1;
|
|
||||||
|
|
||||||
btVector3 dim0 = spuConvexShape0->getImplicitShapeDimensions();
|
|
||||||
btVector3 dim1 = spuConvexShape1->getImplicitShapeDimensions();
|
|
||||||
|
|
||||||
collisionPairInput.m_primitiveDimensions0 = dim0;
|
|
||||||
collisionPairInput.m_primitiveDimensions1 = dim1;
|
|
||||||
collisionPairInput.m_collisionShapes[0] = (uint64_t)lsMem.gColObj0.getCollisionShape();
|
|
||||||
collisionPairInput.m_collisionShapes[1] = (uint64_t)lsMem.gColObj1.getCollisionShape();
|
|
||||||
collisionPairInput.m_spuCollisionShapes[0] = spuConvexShape0;
|
|
||||||
collisionPairInput.m_spuCollisionShapes[1] = spuConvexShape1;
|
|
||||||
ProcessSpuConvexConvexCollision(&collisionPairInput,&lsMem,spuContacts);
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
//a non-convex shape is involved
|
|
||||||
|
|
||||||
bool isSwapped = false;
|
|
||||||
bool handleConvexConcave = false;
|
|
||||||
|
|
||||||
if (btBroadphaseProxy::isConcave(collisionPairInput.m_shapeType0) &&
|
|
||||||
btBroadphaseProxy::isConvex(collisionPairInput.m_shapeType1))
|
|
||||||
{
|
|
||||||
isSwapped = true;
|
|
||||||
spu_printf("SPU convex/concave swapped, unsupported!\n");
|
|
||||||
handleConvexConcave = true;
|
|
||||||
}
|
|
||||||
if (btBroadphaseProxy::isConvex(collisionPairInput.m_shapeType0)&&
|
|
||||||
btBroadphaseProxy::isConcave(collisionPairInput.m_shapeType1))
|
|
||||||
{
|
|
||||||
handleConvexConcave = true;
|
|
||||||
}
|
|
||||||
if (handleConvexConcave && !isSwapped)
|
|
||||||
{
|
|
||||||
// spu_printf("SPU: non-convex detected\n");
|
|
||||||
|
|
||||||
{
|
|
||||||
// uint64_t dmaPpuAddress2 = (uint64_t)gProxy1.m_clientObject;
|
|
||||||
// spu_printf("SPU: gColObj1 trimesh = %llx\n",dmaPpuAddress2);
|
|
||||||
}
|
|
||||||
|
|
||||||
///dma and initialize the convex object
|
|
||||||
{
|
|
||||||
int dmaSize = getShapeTypeSize(collisionPairInput.m_shapeType0);
|
|
||||||
uint64_t dmaPpuAddress2 = (uint64_t)lsMem.gColObj0.getCollisionShape();
|
|
||||||
cellDmaGet(lsMem.gCollisionShape0, dmaPpuAddress2 , dmaSize, DMA_TAG(1), 0, 0);
|
|
||||||
cellDmaWaitTagStatusAll(DMA_MASK(1));
|
|
||||||
}
|
|
||||||
///dma and initialize the convex object
|
|
||||||
{
|
|
||||||
int dmaSize = getShapeTypeSize(collisionPairInput.m_shapeType1);
|
|
||||||
uint64_t dmaPpuAddress2 = (uint64_t)lsMem.gColObj1.getCollisionShape();
|
|
||||||
if (dmaPpuAddress2 & 0x0f)
|
|
||||||
{
|
|
||||||
#ifndef IGNORE_ALIGNMENT
|
|
||||||
spu_printf("SPU ALIGNMENT ERROR3\n");
|
|
||||||
|
|
||||||
spuContacts.flush();
|
|
||||||
return;
|
|
||||||
#endif //
|
|
||||||
}
|
|
||||||
// spu_printf("SPU: trimesh = %llx\n",dmaPpuAddress2);
|
|
||||||
cellDmaGet(lsMem.gCollisionShape1, dmaPpuAddress2 , dmaSize, DMA_TAG(2), 0, 0);
|
|
||||||
cellDmaWaitTagStatusAll(DMA_MASK(2));
|
|
||||||
}
|
|
||||||
btConvexInternalShape* spuConvexShape0 = (btConvexInternalShape*)lsMem.gCollisionShape0;
|
|
||||||
btBvhTriangleMeshShape* trimeshShape = (btBvhTriangleMeshShape*)lsMem.gCollisionShape1;
|
|
||||||
|
|
||||||
btVector3 dim0 = spuConvexShape0->getImplicitShapeDimensions();
|
|
||||||
collisionPairInput.m_primitiveDimensions0 = dim0;
|
|
||||||
collisionPairInput.m_collisionShapes[0] = (uint64_t)lsMem.gColObj0.getCollisionShape();
|
|
||||||
collisionPairInput.m_collisionShapes[1] = (uint64_t)lsMem.gColObj1.getCollisionShape();
|
|
||||||
collisionPairInput.m_spuCollisionShapes[0] = spuConvexShape0;
|
|
||||||
collisionPairInput.m_spuCollisionShapes[1] = trimeshShape;
|
|
||||||
|
|
||||||
ProcessConvexConcaveSpuCollision(&collisionPairInput,&lsMem,spuContacts);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
spuContacts.flush();
|
|
||||||
|
|
||||||
|
handleCollisionPair(collisionPairInput, lsMem, spuContacts,
|
||||||
|
(uint64_t)lsMem.gColObj0.getCollisionShape(), lsMem.gCollisionShape0,
|
||||||
|
(uint64_t)lsMem.gColObj1.getCollisionShape(), lsMem.gCollisionShape1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,8 +35,15 @@ btCompoundShape::~btCompoundShape()
|
|||||||
|
|
||||||
void btCompoundShape::addChildShape(const btTransform& localTransform,btCollisionShape* shape)
|
void btCompoundShape::addChildShape(const btTransform& localTransform,btCollisionShape* shape)
|
||||||
{
|
{
|
||||||
m_childTransforms.push_back(localTransform);
|
//m_childTransforms.push_back(localTransform);
|
||||||
m_childShapes.push_back(shape);
|
//m_childShapes.push_back(shape);
|
||||||
|
btCompoundShapeChild child;
|
||||||
|
child.m_transform = localTransform;
|
||||||
|
child.m_childShape = shape;
|
||||||
|
child.m_childShapeType = shape->getShapeType();
|
||||||
|
child.m_childMargin = shape->getMargin();
|
||||||
|
|
||||||
|
m_children.push_back(child);
|
||||||
|
|
||||||
//extend the local aabbMin/aabbMax
|
//extend the local aabbMin/aabbMax
|
||||||
btVector3 localAabbMin,localAabbMax;
|
btVector3 localAabbMin,localAabbMax;
|
||||||
|
|||||||
@@ -26,12 +26,21 @@ subject to the following restrictions:
|
|||||||
|
|
||||||
class btOptimizedBvh;
|
class btOptimizedBvh;
|
||||||
|
|
||||||
|
ATTRIBUTE_ALIGNED16(struct) btCompoundShapeChild
|
||||||
|
{
|
||||||
|
btTransform m_transform;
|
||||||
|
btCollisionShape* m_childShape;
|
||||||
|
int m_childShapeType;
|
||||||
|
btScalar m_childMargin;
|
||||||
|
};
|
||||||
|
|
||||||
/// btCompoundShape allows to store multiple other btCollisionShapes
|
/// btCompoundShape allows to store multiple other btCollisionShapes
|
||||||
/// This allows for concave collision objects. This is more general then the Static Concave btTriangleMeshShape.
|
/// This allows for concave collision objects. This is more general then the Static Concave btTriangleMeshShape.
|
||||||
class btCompoundShape : public btCollisionShape
|
ATTRIBUTE_ALIGNED16(class) btCompoundShape : public btCollisionShape
|
||||||
{
|
{
|
||||||
btAlignedObjectArray<btTransform> m_childTransforms;
|
//btAlignedObjectArray<btTransform> m_childTransforms;
|
||||||
btAlignedObjectArray<btCollisionShape*> m_childShapes;
|
//btAlignedObjectArray<btCollisionShape*> m_childShapes;
|
||||||
|
btAlignedObjectArray<btCompoundShapeChild> m_children;
|
||||||
btVector3 m_localAabbMin;
|
btVector3 m_localAabbMin;
|
||||||
btVector3 m_localAabbMax;
|
btVector3 m_localAabbMax;
|
||||||
|
|
||||||
@@ -46,25 +55,31 @@ public:
|
|||||||
|
|
||||||
int getNumChildShapes() const
|
int getNumChildShapes() const
|
||||||
{
|
{
|
||||||
return int (m_childShapes.size());
|
return int (m_children.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
btCollisionShape* getChildShape(int index)
|
btCollisionShape* getChildShape(int index)
|
||||||
{
|
{
|
||||||
return m_childShapes[index];
|
return m_children[index].m_childShape;
|
||||||
}
|
}
|
||||||
const btCollisionShape* getChildShape(int index) const
|
const btCollisionShape* getChildShape(int index) const
|
||||||
{
|
{
|
||||||
return m_childShapes[index];
|
return m_children[index].m_childShape;
|
||||||
}
|
}
|
||||||
|
|
||||||
btTransform& getChildTransform(int index)
|
btTransform getChildTransform(int index)
|
||||||
{
|
{
|
||||||
return m_childTransforms[index];
|
return m_children[index].m_transform;
|
||||||
}
|
}
|
||||||
const btTransform& getChildTransform(int index) const
|
const btTransform getChildTransform(int index) const
|
||||||
{
|
{
|
||||||
return m_childTransforms[index];
|
return m_children[index].m_transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
btCompoundShapeChild* getChildList()
|
||||||
|
{
|
||||||
|
return &m_children[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version
|
///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version
|
||||||
|
|||||||
Reference in New Issue
Block a user