My test program is a simple btDiscreteDynamicWorld with two rigid bodies, one is static, one is dynamic, it uses the SPUs, i post the code and makefile at the end.
The error msg like this:
the line 98 in SpuGatheringCollisionTask.h is this:Nullpointer EA: GET ./SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.h:98 from: 0x0, to: 0x3fdb0 - 128 bytes
Code: Select all
cellDmaGet(&taskDesc, status.m_taskDesc.p, sizeof(SpuGatherAndProcessPairsTaskDesc), DMA_TAG(3), 0, 0);
look in the file SpuFakeDma.h for the cellDmaGet() macro definition and the details of error message, it seems like because the statement (uintsize)(status.m_taskDesc.p) is false, so print out the error message.here the "uintsize" type is "unsigned long int".
so the error is because: the (void *) pointer cast to a "unsigned long int" becomes a zero.
it's not normal to cast a point to a none pointer variable, but at least it should work. i tested the cast on cell withe spu-gcc compiler.
Now i know where the problem is, but i don't know why, and i don't know whether it's a bug from bullet, or i did something wrong. So i post it here, see maybe someone has a clue.
cheers
kun
Here is the program:
Code: Select all
#include "btBulletDynamicsCommon.h"
#include "btBulletCollisionCommon.h"
#include <stdio.h>
#include <unistd.h>
#define USE_PARALLEL_DISPATCHER 1
#ifdef USE_PARALLEL_DISPATCHER
#include "BulletMultiThreaded/SpuGatheringCollisionDispatcher.h"
#include "BulletMultiThreaded/PlatformDefinitions.h"
#ifdef USE_LIBSPE2
#include "BulletMultiThreaded/SpuLibspe2Support.h"
#endif //USE_LIBSPE
#endif //USE_PARALLEL_DISPATCHER
main () {
btDefaultCollisionConfiguration* m_collisionConfiguration;
btDiscreteDynamicsWorld* m_dynamicsWorld;
btBroadphaseInterface* m_broadphase;
btCollisionDispatcher* m_dispatcher;
btConstraintSolver* m_solver;
class btThreadSupportInterface* m_threadSupportCollision;
m_collisionConfiguration = new btDefaultCollisionConfiguration();
//load the spu program
int maxNumOutstandingTasks = 16;
#ifdef USE_LIBSPE2
spe_program_handle_t * program_handle;
#ifndef USE_CESOF
program_handle = spe_image_open ("../lib.spu.64/spuCollision.elf");
if (program_handle == NULL)
{
perror( "SPU OPEN IMAGE ERROR\n");
}
else
{
printf( "IMAGE OPENED\n");
}
#else
extern spe_program_handle_t spu_program;
program_handle = &spu_program;
#endif
SpuLibspe2Support* threadSupportCollision = new SpuLibspe2Support( program_handle, maxNumOutstandingTasks);
m_threadSupportCollision = threadSupportCollision;
btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
m_dispatcher = new SpuGatheringCollisionDispatcher(threadSupportCollision,maxNumOutstandingTasks,collisionConfiguration);
#endif
// use groundplane, just for debuggin !!!
m_broadphase = new btDbvtBroadphase();
btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver();
m_solver = solver;
btDiscreteDynamicsWorld* world = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration);
m_dynamicsWorld = world;
world->getSolverInfo().m_numIterations = 4;
world->getSolverInfo().m_solverMode = SOLVER_USE_WARMSTARTING;
//m_dynamicsWorld->getDispatchInfo().m_enableSPU = true;
m_dynamicsWorld->setGravity(btVector3(0,0,-10));
//add a big box asground
btCollisionShape *shape = new btBoxShape(btVector3(50,50,50));
btTransform trans;
trans.setIdentity();
trans.setOrigin(btVector3(0,0,-50));
btDefaultMotionState *motion = new btDefaultMotionState(trans);
btVector3 localInertia(0,0,0);
btScalar mass = 0.0f;
btRigidBody::btRigidBodyConstructionInfo info(mass,motion,shape,localInertia);
btRigidBody *body = new btRigidBody(info);
m_dynamicsWorld->addRigidBody(body);
//add a box falling from point(0,0,20)
btCollisionShape *boxShape = new btBoxShape(btVector3(1,1,1));
btTransform boxTrans;
boxTrans.setIdentity();
boxTrans.setOrigin(btVector3(0,0,20));
btDefaultMotionState* boxMotion = new btDefaultMotionState(boxTrans);
btVector3 boxLocalIntertia(0,0,0);
mass = 10.0f;
btRigidBody::btRigidBodyConstructionInfo boxInfo(mass, boxMotion,boxShape,boxLocalIntertia);
btRigidBody* box = new btRigidBody(boxInfo);
m_dynamicsWorld->addRigidBody(box);
//do the simulation and print out the origin of box;
while(1){
m_dynamicsWorld->stepSimulation(1.0f/60.0f,1);
usleep(17000);
box->getMotionState()->getWorldTransform(boxTrans);
printf("X:%f, Y:%f, Z:%f\n", boxTrans.getOrigin().getX(), boxTrans.getOrigin().getY(),boxTrans.getOrigin().getZ());
}
}
Code: Select all
.PHONY: clean
CCC=ppu-g++
INCLUDES=../lib/src
CFLAGS= -Wall -g -O3 -m64 -DUSE_LIBSPE2
LFLAGS = -L../lib.spu.64
LFLAGS += -lspe2
LFLAGS += -lpthread
LFLAGS += ../lib.spu.64/bulletmultithreaded.a
LFLAGS += ../lib.spu.64/bulletdynamics.a
LFLAGS += ../lib.spu.64/bulletcollision.a
LFLAGS += ../lib.spu.64/bulletmath.a
testOnly: testOnly.o
@$(CCC) -o testOnly $(CFLAGS) testOnly.o $(LFLAGS)
testOnly.o: testOnly.cc
@$(CCC) -I$(INCLUDES) $(CFLAGS) -c testOnly.cc -o testOnly.o
clean:
@echo "Removing testOnly.o, and testOnly"
@rm testOnly testOnly.o