Initial work on batch raycast support.
This commit is contained in:
118
Extras/BulletMultiThreaded/SpuRaycastTask/SpuRaycastTask.cpp
Normal file
118
Extras/BulletMultiThreaded/SpuRaycastTask/SpuRaycastTask.cpp
Normal file
@@ -0,0 +1,118 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "SpuRaycastTask.h"
|
||||
#include "SpuCollisionObjectWrapper.h"
|
||||
#include "SpuNarrowPhaseCollisionTask/SpuCollisionShapes.h"
|
||||
|
||||
|
||||
|
||||
struct RaycastTask_LocalStoreMemory
|
||||
{
|
||||
ATTRIBUTE_ALIGNED16(char gColObj [sizeof(btCollisionObject)+16]);
|
||||
btCollisionObject* getColObj()
|
||||
{
|
||||
return (btCollisionObject*) gColObj;
|
||||
}
|
||||
|
||||
SpuCollisionObjectWrapper gCollisionObjectWrapper;
|
||||
SpuCollisionObjectWrapper* getCollisionObjectWrapper ()
|
||||
{
|
||||
return &gCollisionObjectWrapper;
|
||||
}
|
||||
|
||||
CollisionShape_LocalStoreMemory gCollisionShape;
|
||||
ATTRIBUTE_ALIGNED16(int spuIndices[16]);
|
||||
|
||||
bvhMeshShape_LocalStoreMemory bvhShapeData;
|
||||
SpuConvexPolyhedronVertexData convexVertexData;
|
||||
CompoundShape_LocalStoreMemory compoundShapeData;
|
||||
};
|
||||
|
||||
#ifdef WIN32
|
||||
void* createRaycastLocalStoreMemory()
|
||||
{
|
||||
return new RaycastTask_LocalStoreMemory;
|
||||
};
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
ATTRIBUTE_ALIGNED16(RaycastTask_LocalStoreMemory gLocalStoreMemory);
|
||||
void* createRaycastLocalStoreMemory()
|
||||
{
|
||||
return &gLocalStoreMemory;
|
||||
}
|
||||
#endif
|
||||
|
||||
void GatherCollisionObjectAndShapeData (RaycastGatheredObjectData& gatheredObjectData, RaycastTask_LocalStoreMemory& lsMem, ppu_address_t objectWrapper)
|
||||
{
|
||||
register int dmaSize;
|
||||
register ppu_address_t dmaPpuAddress2;
|
||||
|
||||
/* DMA Collision object wrapper into local store */
|
||||
dmaSize = sizeof(SpuCollisionObjectWrapper);
|
||||
dmaPpuAddress2 = objectWrapper;
|
||||
cellDmaGet(&lsMem.gCollisionObjectWrapper, dmaPpuAddress2, dmaSize, DMA_TAG(1), 0, 0);
|
||||
cellDmaWaitTagStatusAll(DMA_MASK(1));
|
||||
|
||||
/* DMA Collision object into local store */
|
||||
dmaSize = sizeof(btCollisionObject);
|
||||
dmaPpuAddress2 = lsMem.getCollisionObjectWrapper()->getCollisionObjectPtr();
|
||||
cellDmaGet(&lsMem.gColObj, dmaPpuAddress2 , dmaSize, DMA_TAG(2), 0, 0);
|
||||
cellDmaWaitTagStatusAll(DMA_MASK(2));
|
||||
|
||||
/* Gather information about collision object and shape */
|
||||
gatheredObjectData.m_worldTransform = lsMem.getColObj()->getWorldTransform();
|
||||
gatheredObjectData.m_collisionMargin = lsMem.getCollisionObjectWrapper()->getCollisionMargin ();
|
||||
gatheredObjectData.m_shapeType = lsMem.getCollisionObjectWrapper()->getShapeType ();
|
||||
gatheredObjectData.m_collisionShape = (ppu_address_t)lsMem.getColObj()->getCollisionShape();
|
||||
gatheredObjectData.m_spuCollisionShape = (void*)&lsMem.gCollisionShape.collisionShape[0];
|
||||
|
||||
/* DMA shape data */
|
||||
dmaCollisionShape (gatheredObjectData.m_spuCollisionShape, gatheredObjectData.m_collisionShape, 1, gatheredObjectData.m_shapeType);
|
||||
cellDmaWaitTagStatusAll(DMA_MASK(1));
|
||||
btConvexInternalShape* spuConvexShape = (btConvexInternalShape*)gatheredObjectData.m_spuCollisionShape;
|
||||
gatheredObjectData.m_primitiveDimensions = spuConvexShape->getImplicitShapeDimensions ();
|
||||
}
|
||||
|
||||
void dmaLoadRayOutput (ppu_address_t rayOutputAddr, SpuRaycastTaskWorkUnitOut* rayOutput, uint32_t dmaTag)
|
||||
{
|
||||
cellDmaGet(rayOutput, rayOutputAddr, sizeof(*rayOutput), DMA_TAG(dmaTag), 0, 0);
|
||||
}
|
||||
|
||||
void dmaStoreRayOutput (ppu_address_t rayOutputAddr, const SpuRaycastTaskWorkUnitOut* rayOutput, uint32_t dmaTag)
|
||||
{
|
||||
cellDmaLargePut (rayOutput, rayOutputAddr, sizeof(*rayOutput), DMA_TAG(dmaTag), 0, 0);
|
||||
}
|
||||
|
||||
void processRaycastTask(void* userPtr, void* lsMemory)
|
||||
{
|
||||
RaycastTask_LocalStoreMemory* localMemory = (RaycastTask_LocalStoreMemory*)lsMemory;
|
||||
|
||||
SpuRaycastTaskDesc* taskDescPtr = (SpuRaycastTaskDesc*)userPtr;
|
||||
SpuRaycastTaskDesc& taskDesc = *taskDescPtr;
|
||||
|
||||
SpuCollisionObjectWrapper* cows = (SpuCollisionObjectWrapper*)taskDesc.spuCollisionObjectsWrappers;
|
||||
|
||||
/* for each object */
|
||||
for (int objectId = 0; objectId < taskDesc.numSpuCollisionObjectWrappers; objectId++)
|
||||
{
|
||||
RaycastGatheredObjectData gatheredObjectData;
|
||||
GatherCollisionObjectAndShapeData (gatheredObjectData, *localMemory, (ppu_address_t)&cows[objectId]);
|
||||
/* load initial collision shape */
|
||||
for (int rayId = 0; rayId < taskDesc.numWorkUnits; rayId++)
|
||||
{
|
||||
SpuRaycastTaskWorkUnitOut rayOut;
|
||||
|
||||
dmaLoadRayOutput ((ppu_address_t)taskDesc.workUnits[rayId].output, &rayOut, 1);
|
||||
cellDmaWaitTagStatusAll(DMA_MASK(1));
|
||||
|
||||
float t = (float)rayId/(float)taskDesc.numWorkUnits;
|
||||
/* performRaycast */
|
||||
rayOut.hitFraction = 0.1f * t;
|
||||
rayOut.hitNormal = btVector3(1.0, 0.0, 0.0);
|
||||
|
||||
/* write ray cast data back */
|
||||
dmaStoreRayOutput ((ppu_address_t)taskDesc.workUnits[rayId].output, &rayOut, 1);
|
||||
cellDmaWaitTagStatusAll(DMA_MASK(1));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user