From c5e6044e53ba0005a56e8b6c7c009fd65ebdd35d Mon Sep 17 00:00:00 2001 From: ejcoumans Date: Fri, 14 Dec 2007 07:17:35 +0000 Subject: [PATCH] added MultiThreadedDemo --- Demos/CMakeLists.txt | 2 +- Demos/Jamfile | 3 +- Demos/MultiThreadedDemo/CMakeLists.txt | 63 ++ Demos/MultiThreadedDemo/Jamfile | 3 + Demos/MultiThreadedDemo/MultiThreadedDemo.cpp | 690 ++++++++++++++++++ Demos/MultiThreadedDemo/MultiThreadedDemo.h | 79 ++ Demos/MultiThreadedDemo/main.cpp | 36 + .../SpuGatheringCollisionTask.cpp | 13 +- .../SpuSolverTask/SpuParallellSolverTask.cpp | 14 +- 9 files changed, 888 insertions(+), 15 deletions(-) create mode 100644 Demos/MultiThreadedDemo/CMakeLists.txt create mode 100644 Demos/MultiThreadedDemo/Jamfile create mode 100644 Demos/MultiThreadedDemo/MultiThreadedDemo.cpp create mode 100644 Demos/MultiThreadedDemo/MultiThreadedDemo.h create mode 100644 Demos/MultiThreadedDemo/main.cpp diff --git a/Demos/CMakeLists.txt b/Demos/CMakeLists.txt index 2b5d2b317..66d7f5d54 100644 --- a/Demos/CMakeLists.txt +++ b/Demos/CMakeLists.txt @@ -1,2 +1,2 @@ -SUBDIRS( OpenGL CcdPhysicsDemo ConstraintDemo GenericJointDemo RagdollDemo BasicDemo BspDemo MovingConcaveDemo VehicleDemo ColladaDemo UserCollisionAlgorithm ) +SUBDIRS( OpenGL MultiThreadedDemo CcdPhysicsDemo ConstraintDemo GenericJointDemo RagdollDemo BasicDemo BspDemo MovingConcaveDemo VehicleDemo ColladaDemo UserCollisionAlgorithm ) diff --git a/Demos/Jamfile b/Demos/Jamfile index 86bfbfa76..f5aef97d9 100644 --- a/Demos/Jamfile +++ b/Demos/Jamfile @@ -35,7 +35,7 @@ if $(GLUT.AVAILABLE) = "yes" rule FrameWorkDemo { Application $(<) : $(>) : noinstall console nomanifest ; - LinkWith $(<) : GIMPACTUtils GIMPACT bulletopenglsupport convexdecomposition bulletdynamics bulletcollision bulletmath glui ; + LinkWith $(<) : GIMPACTUtils GIMPACT bulletopenglsupport bulletmultithreaded convexdecomposition bulletdynamics bulletcollision bulletmath glui ; CFlags $(<) : [ FIncludes $(TOP)/Extras ] [ FIncludes $(TOP)/Demos/OpenGL ] @@ -58,6 +58,7 @@ if $(GLUT.AVAILABLE) = "yes" SubInclude TOP Demos AllBulletDemos ; SubInclude TOP Demos CcdPhysicsDemo ; SubInclude TOP Demos UserCollisionAlgorithm ; +SubInclude TOP Demos MultiThreadedDemo ; #SubInclude TOP Demos ForkLiftDemo ; SubInclude TOP Demos BulletDinoDemo ; SubInclude TOP Demos EPAPenDepthDemo ; diff --git a/Demos/MultiThreadedDemo/CMakeLists.txt b/Demos/MultiThreadedDemo/CMakeLists.txt new file mode 100644 index 000000000..b07352ca0 --- /dev/null +++ b/Demos/MultiThreadedDemo/CMakeLists.txt @@ -0,0 +1,63 @@ +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + +# This is the variable for Windows. I use this to define the root of my directory structure. +SET(GLUT_ROOT ${BULLET_PHYSICS_SOURCE_DIR}/Glut) + +# You shouldn't have to modify anything below this line +######################################################## + + +# This is the shortcut to finding GLU, GLUT and OpenGL if they are properly installed on your system +# This should be the case. +INCLUDE (${CMAKE_ROOT}/Modules/FindGLU.cmake) +INCLUDE (${CMAKE_ROOT}/Modules/FindGLUT.cmake) +INCLUDE (${CMAKE_ROOT}/Modules/FindOpenGL.cmake) + + +IF (WIN32) + # This is the Windows code for which Opengl, and Glut are not properly installed + # since I can't install them I must cheat and copy libraries around + INCLUDE_DIRECTORIES(${GLUT_ROOT}) + # LINK_DIRECTORIES(${GLUT_ROOT}\\lib) + IF (${GLUT_glut_LIBRARY} MATCHES "GLUT_glut_LIBRARY-NOTFOUND") + SET(GLUT_glut_LIBRARY ${BULLET_PHYSICS_SOURCE_DIR}/Glut/glut32.lib) + # LINK_LIBRARIES(${GLUT_ROOT}\\lib\\glut32 ${OPENGL_gl_LIBRARY} ${OPENGL_glU_LIBRARY}) + # TARGET_LINK_LIBRARIES(table ${GLUT_ROOT}\\lib\\glut32) +# +# ADD_CUSTOM_COMMAND(TARGET table POST_BUILD COMMAND copy ${GLUT_ROOT}\\lib\\glut32.dll ${GLUT_ROOT}\\bin\\vs2005\\Debug +# COMMAND copy ${GLUT_ROOT}\\lib\\glut32.dll ${GLUT_ROOT}\\bin\\vs2003\\Debug +# COMMAND copy ${GLUT_ROOT}\\lib\\glut32.dll ${GLUT_ROOT}\\bin\\vs6\\Debug) + ELSE (${GLUT_glut_LIBRARY} MATCHES "GLUT_glut_LIBRARY-NOTFOUND") +# LINK_LIBRARIES(${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glU_LIBRARY}) +# TARGET_LINK_LIBRARIES(table ${GLUT_glut_LIBRARY}) + ENDIF(${GLUT_glut_LIBRARY} MATCHES "GLUT_glut_LIBRARY-NOTFOUND") +# TARGET_LINK_LIBRARIES(table ${OPENGL_gl_LIBRARY}) +# TARGET_LINK_LIBRARIES(table ${OPENGL_glu_LIBRARY}) +ELSE (WIN32) + # This is the lines for linux. This should always work if everything is installed and working fine. +# SET(CMAKE_BUILD_TYPE Debug) +# SET(CMAKE_CXX_FLAGS_DEBUG "-g") + INCLUDE_DIRECTORIES(/usr/include /usr/local/include ${GLUT_INCLUDE_DIR}) +# TARGET_LINK_LIBRARIES(table ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glU_LIBRARY}) +# TARGET_LINK_LIBRARIES(checker ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glU_LIBRARY}) +ENDIF (WIN32) + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL } +) + +LINK_LIBRARIES( +LibOpenGLSupport LibBulletMultiThreaded LibBulletDynamics LibBulletCollision LibLinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} +) + +ADD_EXECUTABLE(MultiThreadedDemo + main.cpp + MultiThreadedDemo.cpp + MultiThreadedDemo.h +) + diff --git a/Demos/MultiThreadedDemo/Jamfile b/Demos/MultiThreadedDemo/Jamfile new file mode 100644 index 000000000..389d4b854 --- /dev/null +++ b/Demos/MultiThreadedDemo/Jamfile @@ -0,0 +1,3 @@ +SubDir TOP Demos MultiThreadedDemo ; + +FrameWorkDemo MultiThreadedDemo : [ Wildcard *.h *.cpp ] ; diff --git a/Demos/MultiThreadedDemo/MultiThreadedDemo.cpp b/Demos/MultiThreadedDemo/MultiThreadedDemo.cpp new file mode 100644 index 000000000..0a754aaed --- /dev/null +++ b/Demos/MultiThreadedDemo/MultiThreadedDemo.cpp @@ -0,0 +1,690 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +//enable just one, DO_BENCHMARK_PYRAMIDS or DO_WALL +#define DO_BENCHMARK_PYRAMIDS 1 +//#define DO_WALL 1 + +//Note: some of those settings need 'DO_WALL' demo +//#define USE_KINEMATIC_GROUND 1 +//#define PRINT_CONTACT_STATISTICS 1 +//#define REGISTER_BOX_BOX 1 //needs to be used in combination with REGISTER_CUSTOM_COLLISION_ALGORITHM +//#define USER_DEFINED_FRICTION_MODEL 1 +//#define USE_CUSTOM_NEAR_CALLBACK 1 +//#define CENTER_OF_MASS_SHIFT 1 +//#define VERBOSE_TIMESTEPPING_CONSOLEOUTPUT 1 + +#define USE_PARALLEL_SOLVER 1 //experimental parallel solver +#define USE_PARALLEL_DISPATCHER 1 + +//following define allows to compare/replace Bullet's constraint solver with ODE quickstep +//this define requires to either add the libquickstep library (win32, see msvc/8/libquickstep.vcproj) or manually add the files from Extras/quickstep +//#define COMPARE_WITH_QUICKSTEP 1 + + +#include "btBulletDynamicsCommon.h" +#include "BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h" +#ifdef REGISTER_BOX_BOX +#include "../Extras/AlternativeCollisionAlgorithms/BoxBoxCollisionAlgorithm.h" +#endif //REGISTER_BOX_BOX +#include "BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h" + +#ifdef USE_PARALLEL_DISPATCHER +#include "../../Extras/BulletMultiThreaded/SpuGatheringCollisionDispatcher.h" +#ifdef WIN32 +#endif //WIN32 + +#ifdef USE_LIBSPE2 +#include "../../Extras/BulletMultiThreaded/SpuLibspe2Support.h" +#elif defined (WIN32) +#include "../../Extras/BulletMultiThreaded/Win32ThreadSupport.h" +#include "../../Extras/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.h" +#else +//other platforms run the parallel code sequentially (until pthread support or other parallel implementation is added) +#include "../../Extras/BulletMultiThreaded/SequentialThreadSupport.h" +#include "../../Extras/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.h" +#endif //USE_LIBSPE2 + +#ifdef USE_PARALLEL_SOLVER +#include "../../Extras/BulletMultiThreaded/SpuParallelSolver.h" +#include "../../Extras/BulletMultiThreaded/SpuSolverTask/SpuParallellSolverTask.h" +#endif //USE_PARALLEL_SOLVER + +#endif//USE_PARALLEL_DISPATCHER + + +#ifdef COMPARE_WITH_QUICKSTEP +#include "../Extras/quickstep/OdeConstraintSolver.h" +#endif //COMPARE_WITH_QUICKSTEP + +#include "LinearMath/btQuickprof.h" +#include "LinearMath/btIDebugDraw.h" + + +#include "BMF_Api.h" +#include //printf debugging + +#include "MultiThreadedDemo.h" +#include "GL_ShapeDrawer.h" + +#include "GlutStuff.h" + +btTransform comOffset; +btVector3 comOffsetVec(0,2,0); + +extern float eye[3]; +extern int glutScreenWidth; +extern int glutScreenHeight; + +const int maxProxies = 32766; +const int maxOverlap = 65535; + +bool createConstraint = true;//false; +#ifdef CENTER_OF_MASS_SHIFT +bool useCompound = true; +#else +bool useCompound = false; +#endif + + + +#ifdef _DEBUG +const int gNumObjects = 120; +#else +const int gNumObjects = 120;//try this in release mode: 3000. never go above 16384, unless you increate maxNumObjects value in DemoApplication.cp +#endif + + +const int maxNumObjects = 32760; + +int shapeIndex[maxNumObjects]; + + +#define CUBE_HALF_EXTENTS 0.5 + +#define EXTRA_HEIGHT -10.f +//GL_LineSegmentShape shapeE(btPoint3(-50,0,0), +// btPoint3(50,0,0)); + + +void MultiThreadedDemo::createStack( btCollisionShape* boxShape, float halfCubeSize, int size, float zPos ) +{ + btTransform trans; + trans.setIdentity(); + + for(int i=0; im_frictionSolverType = USER_CONTACT_SOLVER_TYPE1; +#endif //USER_DEFINED_FRICTION_MODEL + + } + } +} + + +//////////////////////////////////// + + + +//by default, Bullet will use its own nearcallback, but you can override it using dispatcher->setNearCallback() +void customNearCallback(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, btDispatcherInfo& dispatchInfo) +{ + btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject; + btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject; + + if (dispatcher.needsCollision(colObj0,colObj1)) + { + //dispatcher will keep algorithms persistent in the collision pair + if (!collisionPair.m_algorithm) + { + collisionPair.m_algorithm = dispatcher.findAlgorithm(colObj0,colObj1); + } + + if (collisionPair.m_algorithm) + { + btManifoldResult contactPointResult(colObj0,colObj1); + + if (dispatchInfo.m_dispatchFunc == btDispatcherInfo::DISPATCH_DISCRETE) + { + //discrete collision detection query + collisionPair.m_algorithm->processCollision(colObj0,colObj1,dispatchInfo,&contactPointResult); + } else + { + //continuous collision detection query, time of impact (toi) + float toi = collisionPair.m_algorithm->calculateTimeOfImpact(colObj0,colObj1,dispatchInfo,&contactPointResult); + if (dispatchInfo.m_timeOfImpact > toi) + dispatchInfo.m_timeOfImpact = toi; + + } + } + } + +} + + + + + + +//experimental jitter damping (1 = no damping, 0 = total damping once motion below threshold) +extern btScalar gJitterVelocityDampingFactor; + + + + +extern int gNumManifold; +extern int gOverlappingPairs; +extern int gTotalContactPoints; + +void MultiThreadedDemo::clientMoveAndDisplay() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + +#ifdef USE_KINEMATIC_GROUND + //btQuaternion kinRotation(btVector3(0,0,1),0.); + btVector3 kinTranslation(-0.01,0,0); + //kinematic object + btCollisionObject* colObj = m_dynamicsWorld->getCollisionObjectArray()[0]; + //is this a rigidbody with a motionstate? then use the motionstate to update positions! + if (btRigidBody::upcast(colObj) && btRigidBody::upcast(colObj)->getMotionState()) + { + btTransform newTrans; + btRigidBody::upcast(colObj)->getMotionState()->getWorldTransform(newTrans); + newTrans.getOrigin()+=kinTranslation; + btRigidBody::upcast(colObj)->getMotionState()->setWorldTransform(newTrans); + } else + { + m_dynamicsWorld->getCollisionObjectArray()[0]->getWorldTransform().getOrigin() += kinTranslation; + } + +#endif //USE_KINEMATIC_GROUND + + + float dt = m_clock.getTimeMicroseconds() * 0.000001f; + m_clock.reset(); +// printf("dt = %f: ",dt); + + if (m_dynamicsWorld) + { + +//#define FIXED_STEP 1 +#ifdef FIXED_STEP + m_dynamicsWorld->stepSimulation(1.0f/60.f,0); + +#else + //during idle mode, just run 1 simulation step maximum + int maxSimSubSteps = m_idle ? 1 : 1; + if (m_idle) + dt = 1.0/420.f; + + int numSimSteps = 0; + numSimSteps = m_dynamicsWorld->stepSimulation(dt,maxSimSubSteps); + + //optional but useful: debug drawing + m_dynamicsWorld->debugDrawWorld(); + +#ifdef VERBOSE_TIMESTEPPING_CONSOLEOUTPUT + if (!numSimSteps) + printf("Interpolated transforms\n"); + else + { + if (numSimSteps > maxSimSubSteps) + { + //detect dropping frames + printf("Dropped (%i) simulation steps out of %i\n",numSimSteps - maxSimSubSteps,numSimSteps); + } else + { + printf("Simulated (%i) steps\n",numSimSteps); + } + } +#endif //VERBOSE_TIMESTEPPING_CONSOLEOUTPUT + +#endif + } + +#ifdef USE_QUICKPROF + btProfiler::beginBlock("render"); +#endif //USE_QUICKPROF + + renderme(); + + + //render the graphics objects, with center of mass shift + + updateCamera(); + + + +#ifdef USE_QUICKPROF + btProfiler::endBlock("render"); +#endif + glFlush(); + //some additional debugging info +#ifdef PRINT_CONTACT_STATISTICS + printf("num manifolds: %i\n",gNumManifold); + printf("num gOverlappingPairs: %i\n",gOverlappingPairs); + printf("num gTotalContactPoints : %i\n",gTotalContactPoints ); +#endif //PRINT_CONTACT_STATISTICS + + gTotalContactPoints = 0; + glutSwapBuffers(); + +} + + + +void MultiThreadedDemo::displayCallback(void) { + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + + renderme(); + + glFlush(); + glutSwapBuffers(); +} + + + + + +///User-defined friction model, the most simple friction model available: no friction +float myFrictionModel( btRigidBody& body1, btRigidBody& body2, btManifoldPoint& contactPoint, const btContactSolverInfo& solverInfo ) +{ + //don't do any friction + return 0.f; +} + +void MultiThreadedDemo::initPhysics() +{ +#ifdef USE_PARALLEL_DISPATCHER +#ifdef WIN32 + m_threadSupportSolver = 0; + m_threadSupportCollision = 0; +#endif // +#endif + +//#define USE_GROUND_PLANE 1 +#ifdef USE_GROUND_PLANE + m_collisionShapes.push_back(new btStaticPlaneShape(btVector3(0,1,0),0.5)); +#else + + ///Please don't make the box sizes larger then 1000: the collision detection will be inaccurate. + ///See http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=346 + m_collisionShapes.push_back(new btBoxShape (btVector3(200,CUBE_HALF_EXTENTS,200))); +#endif + +#ifdef DO_BENCHMARK_PYRAMIDS + m_collisionShapes.push_back(new btBoxShape (btVector3(CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS))); +#else + m_collisionShapes.push_back(new btCylinderShape (btVector3(CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS))); +#endif + + + +#ifdef DO_BENCHMARK_PYRAMIDS + setCameraDistance(32.5f); +#endif + +#ifdef DO_BENCHMARK_PYRAMIDS + m_azi = 90.f; +#endif //DO_BENCHMARK_PYRAMIDS + + m_dispatcher=0; + m_collisionConfiguration = new btDefaultCollisionConfiguration(); + +#ifdef USE_PARALLEL_DISPATCHER +int maxNumOutstandingTasks = 4; + +#ifdef USE_WIN32_THREADING + + m_threadSupportCollision = new Win32ThreadSupport(Win32ThreadSupport::Win32ThreadConstructionInfo( + "collision", + processCollisionTask, + createCollisionLocalStoreMemory, + maxNumOutstandingTasks)); +#else + +#ifdef USE_LIBSPE2 + + spe_program_handle_t * program_handle; +#ifndef USE_CESOF + program_handle = spe_image_open ("./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); +#else + + SequentialThreadSupport::SequentialThreadConstructionInfo colCI("collision",processCollisionTask,createCollisionLocalStoreMemory); + SequentialThreadSupport* m_threadSupportCollision = new SequentialThreadSupport(colCI); + +#endif //USE_LIBSPE2 + +///Playstation 3 SPU (SPURS) version is available through PS3 Devnet +/// For Unix/Mac someone could implement a pthreads version of btThreadSupportInterface? +///you can hook it up to your custom task scheduler by deriving from btThreadSupportInterface +#endif + + + m_dispatcher = new SpuGatheringCollisionDispatcher(m_threadSupportCollision,maxNumOutstandingTasks,m_collisionConfiguration); +// m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); +#else + + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); +#endif //USE_PARALLEL_DISPATCHER + +#ifdef USE_CUSTOM_NEAR_CALLBACK + //this is optional + m_dispatcher->setNearCallback(customNearCallback); +#endif + + btVector3 worldAabbMin(-1000,-1000,-1000); + btVector3 worldAabbMax(1000,1000,1000); + + m_broadphase = new btAxisSweep3(worldAabbMin,worldAabbMax,maxProxies); +/// For large worlds or over 16384 objects, use the bt32BitAxisSweep3 broadphase +// m_broadphase = new bt32BitAxisSweep3(worldAabbMin,worldAabbMax,maxProxies); +/// When trying to debug broadphase issues, try to use the btSimpleBroadphase +// m_broadphase = new btSimpleBroadphase; + + //box-box is in Extras/AlternativeCollisionAlgorithms:it requires inclusion of those files +#ifdef REGISTER_BOX_BOX + m_dispatcher->registerCollisionCreateFunc(BOX_SHAPE_PROXYTYPE,BOX_SHAPE_PROXYTYPE,new BoxBoxCollisionAlgorithm::CreateFunc); +#endif //REGISTER_BOX_BOX + +#ifdef COMPARE_WITH_QUICKSTEP + m_solver = new OdeConstraintSolver(); +#else + + +#ifdef USE_PARALLEL_SOLVER + +#ifdef USE_WIN32_THREADING + m_threadSupportSolver = new Win32ThreadSupport(Win32ThreadSupport::Win32ThreadConstructionInfo( + "solver", + processSolverTask, + createSolverLocalStoreMemory, + maxNumOutstandingTasks)); + +#else + //for now use sequential version + SequentialThreadSupport::SequentialThreadConstructionInfo solverCI("solver",processSolverTask,createSolverLocalStoreMemory); + m_threadSupportSolver = new SequentialThreadSupport(solverCI); + +#endif //USE_WIN32_THREADING + m_solver = new btParallelSequentialImpulseSolver(m_threadSupportSolver,maxNumOutstandingTasks); + +#else + + btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver(); + + m_solver = solver; + //default solverMode is SOLVER_RANDMIZE_ORDER. Warmstarting seems not to improve convergence, see + //solver->setSolverMode(0);//btSequentialImpulseConstraintSolver::SOLVER_USE_WARMSTARTING | btSequentialImpulseConstraintSolver::SOLVER_RANDMIZE_ORDER); + +#endif //USE_PARALLEL_SOLVER + +#endif + + + btDiscreteDynamicsWorld* world = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); + m_dynamicsWorld = world; + + world->getSolverInfo().m_numIterations = 4; + + m_dynamicsWorld->getDispatchInfo().m_enableSPU = true; + m_dynamicsWorld->setGravity(btVector3(0,-10,0)); + + + + int i; + + btTransform tr; + tr.setIdentity(); + + + for (i=0;i0) + { + shapeIndex[i] = 1;//sphere + } + else + shapeIndex[i] = 0; + } + + if (useCompound) + { + btCompoundShape* compoundShape = new btCompoundShape(); + btCollisionShape* oldShape = m_collisionShapes[1]; + m_collisionShapes[1] = compoundShape; + btVector3 sphereOffset(0,0,2); + + comOffset.setIdentity(); + +#ifdef CENTER_OF_MASS_SHIFT + comOffset.setOrigin(comOffsetVec); + compoundShape->addChildShape(comOffset,oldShape); + +#else + compoundShape->addChildShape(tr,oldShape); + tr.setOrigin(sphereOffset); + compoundShape->addChildShape(tr,new btSphereShape(0.9)); +#endif + } + +#ifdef DO_WALL + + for (i=0;isetMargin(gCollisionMargin); + + bool isDyna = i>0; + + btTransform trans; + trans.setIdentity(); + + if (i>0) + { + //stack them + int colsize = 10; + int row = (i*CUBE_HALF_EXTENTS*2)/(colsize*2*CUBE_HALF_EXTENTS); + int row2 = row; + int col = (i)%(colsize)-colsize/2; + + + if (col>3) + { + col=11; + row2 |=1; + } + + btVector3 pos(col*2*CUBE_HALF_EXTENTS + (row2%2)*CUBE_HALF_EXTENTS, + row*2*CUBE_HALF_EXTENTS+CUBE_HALF_EXTENTS+EXTRA_HEIGHT,0); + + trans.setOrigin(pos); + } else + { + trans.setOrigin(btVector3(0,EXTRA_HEIGHT-CUBE_HALF_EXTENTS,0)); + } + + float mass = 1.f; + + if (!isDyna) + mass = 0.f; + + btRigidBody* body = localCreateRigidBody(mass,trans,shape); +#ifdef USE_KINEMATIC_GROUND + if (mass == 0.f) + { + body->setCollisionFlags( body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); + body->setActivationState(DISABLE_DEACTIVATION); + } +#endif //USE_KINEMATIC_GROUND + + + // Only do CCD if motion in one timestep (1.f/60.f) exceeds CUBE_HALF_EXTENTS + body->setCcdSquareMotionThreshold( CUBE_HALF_EXTENTS ); + + //Experimental: better estimation of CCD Time of Impact: + body->setCcdSweptSphereRadius( 0.2*CUBE_HALF_EXTENTS ); + +#ifdef USER_DEFINED_FRICTION_MODEL + ///Advanced use: override the friction solver + body->m_frictionSolverType = USER_CONTACT_SOLVER_TYPE1; +#endif //USER_DEFINED_FRICTION_MODEL + + } +#endif + + +#ifdef DO_BENCHMARK_PYRAMIDS + btTransform trans; + trans.setIdentity(); + + btScalar halfExtents = CUBE_HALF_EXTENTS; + + trans.setOrigin(btVector3(0,-halfExtents,0)); + + + + localCreateRigidBody(0.f,trans,m_collisionShapes[shapeIndex[0]]); + + int numWalls = 15; + int wallHeight = 15; + float wallDistance = 3; + + + for (int i=0;isetLinearVelocity(btVector3(0,0,-10)); +#endif +#endif //DO_BENCHMARK_PYRAMIDS +// clientResetScene(); + + +} + + + + + + +void MultiThreadedDemo::exitPhysics() +{ + + + //cleanup in the reverse order of creation/initialization + + //remove the rigidbodies from the dynamics world and delete them + int i; + for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + m_dynamicsWorld->removeCollisionObject( obj ); + delete obj; + } + + //delete collision shapes + for (int j=0;j m_collisionShapes; + + btBroadphaseInterface* m_broadphase; + + btCollisionDispatcher* m_dispatcher; + + class btThreadSupportInterface* m_threadSupportCollision; + class btThreadSupportInterface* m_threadSupportSolver; + + btConstraintSolver* m_solver; + + btCollisionAlgorithmCreateFunc* m_boxBoxCF; + + btDefaultCollisionConfiguration* m_collisionConfiguration; + + + public: + + void initPhysics(); + + void exitPhysics(); + + virtual ~MultiThreadedDemo() + { + exitPhysics(); + } + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + + void createStack( btCollisionShape* boxShape, float halfCubeSize, int size, float zPos ); + + static DemoApplication* Create() + { + MultiThreadedDemo* demo = new MultiThreadedDemo; + demo->myinit(); + demo->initPhysics(); + return demo; + } + +}; + +#endif //MULTI_THREADED_DEMO_H + diff --git a/Demos/MultiThreadedDemo/main.cpp b/Demos/MultiThreadedDemo/main.cpp new file mode 100644 index 000000000..363f69a6f --- /dev/null +++ b/Demos/MultiThreadedDemo/main.cpp @@ -0,0 +1,36 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "MultiThreadedDemo.h" +#include "GlutStuff.h" +#include "GLDebugDrawer.h" +#include "btBulletDynamicsCommon.h" + +GLDebugDrawer gDebugDrawer; + +int main(int argc,char** argv) +{ + + MultiThreadedDemo* demo = new MultiThreadedDemo(); + + demo->initPhysics(); + demo->getDynamicsWorld()->setDebugDrawer(&gDebugDrawer); + + + glutmain(argc, argv,640,480,"Bullet Physics Demo. http://bullet.sf.net",demo); + + delete demo; + +} diff --git a/Extras/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.cpp b/Extras/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.cpp index 98c8b22c0..47ef0c1f4 100644 --- a/Extras/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.cpp +++ b/Extras/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.cpp @@ -171,14 +171,9 @@ struct CollisionTask_LocalStoreMemory -#ifdef WIN32 -void* createCollisionLocalStoreMemory() -{ - return new CollisionTask_LocalStoreMemory; -}; -#elif defined(__CELLOS_LV2__) || defined(USE_LIBSPE2) +#if defined(__CELLOS_LV2__) || defined(USE_LIBSPE2) ATTRIBUTE_ALIGNED16(CollisionTask_LocalStoreMemory gLocalStoreMemory); @@ -186,6 +181,12 @@ void* createCollisionLocalStoreMemory() { return &gLocalStoreMemory; } +#else +void* createCollisionLocalStoreMemory() +{ + return new CollisionTask_LocalStoreMemory; +}; + #endif diff --git a/Extras/BulletMultiThreaded/SpuSolverTask/SpuParallellSolverTask.cpp b/Extras/BulletMultiThreaded/SpuSolverTask/SpuParallellSolverTask.cpp index 2f6fc5446..6307053e5 100644 --- a/Extras/BulletMultiThreaded/SpuSolverTask/SpuParallellSolverTask.cpp +++ b/Extras/BulletMultiThreaded/SpuSolverTask/SpuParallellSolverTask.cpp @@ -55,14 +55,8 @@ struct SolverTask_LocalStoreMemory }; -#ifdef WIN32 -void* createSolverLocalStoreMemory() -{ - return new SolverTask_LocalStoreMemory; -}; - -#elif defined(__CELLOS_LV2__) +#if defined(__CELLOS_LV2__) || defined (LIBSPE2) ATTRIBUTE_ALIGNED16(SolverTask_LocalStoreMemory gLocalStoreMemory); @@ -70,6 +64,12 @@ void* createSolverLocalStoreMemory() { return &gLocalStoreMemory; } +#else +void* createSolverLocalStoreMemory() +{ + return new SolverTask_LocalStoreMemory; +}; + #endif