diff --git a/Demos/AllBulletDemos/CMakeLists.txt b/Demos/AllBulletDemos/CMakeLists.txt index b5ce3c912..3279f8130 100644 --- a/Demos/AllBulletDemos/CMakeLists.txt +++ b/Demos/AllBulletDemos/CMakeLists.txt @@ -41,7 +41,10 @@ SET(AllBulletDemos_SRCS ../ConcaveConvexcastDemo/ConcaveConvexcastDemo.cpp ../ConvexDecompositionDemo/ConvexDecompositionDemo.cpp ../SliderConstraintDemo/SliderConstraintDemo.cpp - ../RagdollDemo/RagdollDemo.cpp + ../RagdollDemo/RagdollDemo.cpp + ../FractureDemo/FractureDemo.cpp + ../FractureDemo/btFractureBody.cpp + ../FractureDemo/btFractureDynamicsWorld.cpp ../GimpactTestDemo/GimpactTestDemo.cpp ../Raytracer/Raytracer.cpp ../GjkConvexCastDemo/LinearConvexCastDemo.cpp diff --git a/Demos/AllBulletDemos/DemoEntries.cpp b/Demos/AllBulletDemos/DemoEntries.cpp index eb35f02c0..87e848905 100644 --- a/Demos/AllBulletDemos/DemoEntries.cpp +++ b/Demos/AllBulletDemos/DemoEntries.cpp @@ -18,6 +18,7 @@ subject to the following restrictions: #include "../CcdPhysicsDemo/CcdPhysicsDemo.h" #include "../BspDemo/BspDemo.h" #include "../BasicDemo/BasicDemo.h" +#include "../FractureDemo/FractureDemo.h" #include "../ConcaveDemo/ConcaveDemo.h" #include "../ConcaveRaycastDemo/ConcaveRaycastDemo.h" #include "../ConcaveConvexcastDemo/ConcaveConvexcastDemo.h" @@ -107,6 +108,7 @@ public: btDemoEntry g_demoEntries[] = { // {"Box2dDemo",Box2dDemo::Create}, + {"FractureDemo",FractureDemo::Create}, {"ForkLift Demo",ForkLiftDemo::Create}, {"Dynamic Control Demo",MotorDemo::Create}, {"ConstraintDemo",ConstraintDemo::Create}, diff --git a/Demos/BasicDemo/BasicDemo.cpp b/Demos/BasicDemo/BasicDemo.cpp index d4099d8ac..8f2bfc8ba 100644 --- a/Demos/BasicDemo/BasicDemo.cpp +++ b/Demos/BasicDemo/BasicDemo.cpp @@ -30,23 +30,10 @@ subject to the following restrictions: #include "BasicDemo.h" #include "GlutStuff.h" -#include "GLDebugFont.h" - ///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files. #include "btBulletDynamicsCommon.h" #include //printf debugging -#include "GLDebugDrawer.h" - -static GLDebugDrawer sDebugDrawer; - - -BasicDemo::BasicDemo() -:m_ccdMode(USE_SPECULULATIVE_CONTACTS) -{ - setDebugMode(btIDebugDraw::DBG_DrawText); - setCameraDistance(btScalar(SCALING*50.)); -} void BasicDemo::clientMoveAndDisplay() @@ -59,15 +46,13 @@ void BasicDemo::clientMoveAndDisplay() ///step the simulation if (m_dynamicsWorld) { - m_dynamicsWorld->stepSimulation(1./60.);//ms / 1000000.f); + m_dynamicsWorld->stepSimulation(ms / 1000000.f); //optional but useful: debug drawing m_dynamicsWorld->debugDrawWorld(); } renderme(); - displayText(); - glFlush(); swapBuffers(); @@ -75,62 +60,6 @@ void BasicDemo::clientMoveAndDisplay() } -void BasicDemo::displayText() -{ - int lineWidth=400; - int xStart = m_glutScreenWidth - lineWidth; - int yStart = 20; - - if((getDebugMode() & btIDebugDraw::DBG_DrawText)!=0) - { - setOrthographicProjection(); - glDisable(GL_LIGHTING); - glColor3f(0, 0, 0); - char buf[124]; - - glRasterPos3f(xStart, yStart, 0); - switch (m_ccdMode) - { - case USE_SPECULULATIVE_CONTACTS: - { - sprintf(buf,"Predictive contacts enabled"); - break; - } - case USE_CONSERVATIVE_ADVANCEMENT: - { - sprintf(buf,"Conservative advancement enabled"); - break; - }; - case USE_NO_CCD: - { - sprintf(buf,"CCD disabled"); - break; - } - default: - { - sprintf(buf,"unknown CCD setting"); - }; - }; - - GLDebugDrawString(xStart,20,buf); - glRasterPos3f(xStart, yStart, 0); - sprintf(buf,"Press 'p' to change CCD mode"); - yStart+=20; - GLDebugDrawString(xStart,yStart,buf); - glRasterPos3f(xStart, yStart, 0); - sprintf(buf,"Press '.' or right mouse to shoot boxes"); - yStart+=20; - GLDebugDrawString(xStart,yStart,buf); - glRasterPos3f(xStart, yStart, 0); - sprintf(buf,"space to restart, h(elp), t(ext), w(ire)"); - yStart+=20; - GLDebugDrawString(xStart,yStart,buf); - - resetPerspectiveProjection(); - glEnable(GL_LIGHTING); - } - -} void BasicDemo::displayCallback(void) { @@ -138,13 +67,9 @@ void BasicDemo::displayCallback(void) { renderme(); - displayText(); - //optional but useful: debug drawing to detect problems if (m_dynamicsWorld) - { m_dynamicsWorld->debugDrawWorld(); - } glFlush(); swapBuffers(); @@ -158,17 +83,15 @@ void BasicDemo::initPhysics() { setTexturing(true); setShadows(true); - - m_ShootBoxInitialSpeed = 1000.f; + setCameraDistance(btScalar(SCALING*50.)); ///collision configuration contains default setup for memory, collision setup m_collisionConfiguration = new btDefaultCollisionConfiguration(); - m_collisionConfiguration->setConvexConvexMultipointIterations(); + //m_collisionConfiguration->setConvexConvexMultipointIterations(); ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); - m_dispatcher->registerCollisionCreateFunc(BOX_SHAPE_PROXYTYPE,BOX_SHAPE_PROXYTYPE,m_collisionConfiguration->getCollisionAlgorithmCreateFunc(CONVEX_SHAPE_PROXYTYPE,CONVEX_SHAPE_PROXYTYPE)); m_broadphase = new btDbvtBroadphase(); @@ -177,13 +100,7 @@ void BasicDemo::initPhysics() m_solver = sol; m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); - m_dynamicsWorld ->setDebugDrawer(&sDebugDrawer); - - if (m_ccdMode==USE_SPECULULATIVE_CONTACTS) - { - m_dynamicsWorld->getDispatchInfo().m_convexMaxDistanceUseCPT = true; - } - + m_dynamicsWorld->setGravity(btVector3(0,-10,0)); ///create a few basic rigid bodies @@ -258,9 +175,8 @@ void BasicDemo::initPhysics() btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,colShape,localInertia); btRigidBody* body = new btRigidBody(rbInfo); - if (m_ccdMode==USE_SPECULULATIVE_CONTACTS) - body->setContactProcessingThreshold(1e30); + m_dynamicsWorld->addRigidBody(body); } } @@ -269,82 +185,12 @@ void BasicDemo::initPhysics() } - void BasicDemo::clientResetScene() { exitPhysics(); initPhysics(); } - -void BasicDemo::keyboardCallback(unsigned char key, int x, int y) -{ - if (key=='p') - { - switch (m_ccdMode) - { - case USE_SPECULULATIVE_CONTACTS: - { - m_ccdMode = USE_CONSERVATIVE_ADVANCEMENT; - break; - } - case USE_CONSERVATIVE_ADVANCEMENT: - { - m_ccdMode = USE_NO_CCD; - break; - }; - case USE_NO_CCD: - default: - { - m_ccdMode = USE_SPECULULATIVE_CONTACTS; - } - }; - clientResetScene(); - } else - { - DemoApplication::keyboardCallback(key,x,y); - } -} - - -void BasicDemo::shootBox(const btVector3& destination) -{ - - if (m_dynamicsWorld) - { - float mass = 1.f; - btTransform startTransform; - startTransform.setIdentity(); - btVector3 camPos = getCameraPosition(); - startTransform.setOrigin(camPos); - - setShootBoxShape (); - - btRigidBody* body = this->localCreateRigidBody(mass, startTransform,m_shootBoxShape); - body->setLinearFactor(btVector3(1,1,1)); - //body->setRestitution(1); - - btVector3 linVel(destination[0]-camPos[0],destination[1]-camPos[1],destination[2]-camPos[2]); - linVel.normalize(); - linVel*=m_ShootBoxInitialSpeed; - - body->getWorldTransform().setOrigin(camPos); - body->getWorldTransform().setRotation(btQuaternion(0,0,0,1)); - body->setLinearVelocity(linVel); - body->setAngularVelocity(btVector3(0,0,0)); - body->setContactProcessingThreshold(1e30); - - ///when using m_ccdMode, disable regular CCD - if (m_ccdMode==USE_CONSERVATIVE_ADVANCEMENT) - { - body->setCcdMotionThreshold(1.); - body->setCcdSweptSphereRadius(0.5f*SCALING); - } - - } -} - - - + void BasicDemo::exitPhysics() { diff --git a/Demos/BasicDemo/BasicDemo.h b/Demos/BasicDemo/BasicDemo.h index 4876a2e48..7a6851f7d 100644 --- a/Demos/BasicDemo/BasicDemo.h +++ b/Demos/BasicDemo/BasicDemo.h @@ -47,20 +47,13 @@ class BasicDemo : public PlatformDemoApplication btConstraintSolver* m_solver; - enum - { - USE_SPECULULATIVE_CONTACTS=0, - USE_CONSERVATIVE_ADVANCEMENT, - USE_NO_CCD - }; - int m_ccdMode; - btDefaultCollisionConfiguration* m_collisionConfiguration; public: - BasicDemo(); - + BasicDemo() + { + } virtual ~BasicDemo() { exitPhysics(); @@ -71,14 +64,8 @@ class BasicDemo : public PlatformDemoApplication virtual void clientMoveAndDisplay(); - void displayText(); - - virtual void keyboardCallback(unsigned char key, int x, int y); - virtual void displayCallback(); - virtual void shootBox(const btVector3& destination); virtual void clientResetScene(); - static DemoApplication* Create() { diff --git a/Demos/BasicDemo/main.cpp b/Demos/BasicDemo/main.cpp index eadcb6d70..ac2d8dabe 100644 --- a/Demos/BasicDemo/main.cpp +++ b/Demos/BasicDemo/main.cpp @@ -18,62 +18,17 @@ subject to the following restrictions: #include "btBulletDynamicsCommon.h" #include "LinearMath/btHashMap.h" -class OurValue - { - int m_uid; +#include "GLDebugDrawer.h" +static GLDebugDrawer sDebugDraw; - public: - OurValue(const btVector3& initialPos) - :m_position(initialPos) - { - static int gUid=0; - m_uid=gUid; - gUid++; - } - - btVector3 m_position; - int getUid() const - { - return m_uid; - } - }; int main(int argc,char** argv) { - ///testing the btHashMap - btHashMap,OurValue> map; - - OurValue value1(btVector3(2,3,4)); - btHashKey key1(value1.getUid()); - map.insert(key1,value1); - - - OurValue value2(btVector3(5,6,7)); - btHashKey key2(value2.getUid()); - map.insert(key2,value2); - - - { - OurValue value3(btVector3(7,8,9)); - btHashKey key3(value3.getUid()); - map.insert(key3,value3); - } - - - map.remove(key2); - -// const OurValue* ourPtr = map.find(key1); -// for (int i=0;im_position.getX(),tmp->m_position.getY(),tmp->m_position.getZ()); -// } - BasicDemo ccdDemo; ccdDemo.initPhysics(); - + ccdDemo.getDynamicsWorld()->setDebugDrawer(&sDebugDraw); #ifdef CHECK_MEMORY_LEAKS ccdDemo.exitPhysics(); diff --git a/Demos/Benchmarks/BenchmarkDemo.cpp b/Demos/Benchmarks/BenchmarkDemo.cpp index d85600b55..7c01e883e 100644 --- a/Demos/Benchmarks/BenchmarkDemo.cpp +++ b/Demos/Benchmarks/BenchmarkDemo.cpp @@ -324,10 +324,14 @@ void BenchmarkDemo::initPhysics() setCameraDistance(btScalar(100.)); ///collision configuration contains default setup for memory, collision setup - m_collisionConfiguration = new btDefaultCollisionConfiguration(); + btDefaultCollisionConstructionInfo cci; + cci.m_defaultMaxPersistentManifoldPoolSize = 32768; + m_collisionConfiguration = new btDefaultCollisionConfiguration(cci); ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); + + m_dispatcher->setDispatcherFlags(btCollisionDispatcher::CD_DISABLE_CONTACTPOOL_DYNAMIC_ALLOCATION); #if USE_PARALLEL_DISPATCHER_BENCHMARK @@ -967,6 +971,9 @@ void BenchmarkDemo::createTest4() convexHullShape->addPoint(vtx*btScalar(1./scaling)); } + //this will enable polyhedral contact clipping, better quality, slightly slower + //convexHullShape->initializePolyhedralFeatures(); + btTransform trans; trans.setIdentity(); diff --git a/Demos/Benchmarks/main.cpp b/Demos/Benchmarks/main.cpp index 3683e3bea..48e23bbdd 100644 --- a/Demos/Benchmarks/main.cpp +++ b/Demos/Benchmarks/main.cpp @@ -22,7 +22,7 @@ subject to the following restrictions: #include "GlutStuff.h" #include "GLDebugDrawer.h" GLDebugDrawer gDebugDrawer; -#define benchmarkDemo benchmarkDemo2 +#define benchmarkDemo benchmarkDemo4 #endif //USE_GRAPHICAL_BENCHMARK diff --git a/Demos/CcdPhysicsDemo/CcdPhysicsDemo.cpp b/Demos/CcdPhysicsDemo/CcdPhysicsDemo.cpp index 82e00f6cc..86df8cd33 100644 --- a/Demos/CcdPhysicsDemo/CcdPhysicsDemo.cpp +++ b/Demos/CcdPhysicsDemo/CcdPhysicsDemo.cpp @@ -4,8 +4,8 @@ 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, +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. @@ -13,280 +13,118 @@ subject to the following restrictions: 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 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_DISPATCHER 1 -//#define USE_PARALLEL_SOLVER 1 //experimental parallel solver - - -//from Bullet 2.68 onwards ODE Quickstep constraint solver is optional part of Bullet, re-distributed under the ZLib license with permission of Russell L. Smith -//#define COMPARE_WITH_QUICKSTEP 1 - - -#include "btBulletDynamicsCommon.h" -#include "BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h" -#include "BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h" - -#ifdef USE_PARALLEL_DISPATCHER -#include "BulletMultiThreaded/SpuGatheringCollisionDispatcher.h" -#ifdef _WIN32 -#include "BulletMultiThreaded/Win32ThreadSupport.h" -#include "BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.h" -#endif //_WIN32 - -#ifdef USE_LIBSPE2 -#include "../../Extras/BulletMultiThreaded/SpuLibspe2Support.h" -#endif //USE_LIBSPE2 - -#ifdef USE_PARALLEL_SOLVER -#include "BulletMultiThreaded/SpuParallelSolver.h" -#include "BulletMultiThreaded/SpuSolverTask/SpuParallellSolverTask.h" -#endif //USE_PARALLEL_SOLVER - -#endif//USE_PARALLEL_DISPATCHER - - - -#include "LinearMath/btQuickprof.h" -#include "LinearMath/btIDebugDraw.h" - - -#include "GLDebugFont.h" -#include //printf debugging - -static float gCollisionMargin = 0.05f; -#include "CcdPhysicsDemo.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 1.f -#define EXTRA_HEIGHT -10.f -//GL_LineSegmentShape shapeE(btVector3(-50,0,0), -// btVector3(50,0,0)); +#include "CcdPhysicsDemo.h" +#include "GlutStuff.h" +#include "GLDebugFont.h" + +///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files. +#include "btBulletDynamicsCommon.h" + +#include //printf debugging +#include "GLDebugDrawer.h" + +#if 0 +extern btAlignedObjectArray debugContacts; +extern btAlignedObjectArray debugNormals; +#endif + +static GLDebugDrawer sDebugDrawer; -void CcdPhysicsDemo::createStack( btCollisionShape* boxShape, float halfCubeSize, int size, float zPos ) +CcdPhysicsDemo::CcdPhysicsDemo() +:m_ccdMode(USE_CCD) { - btTransform trans; - trans.setIdentity(); - - for(int i=0; im_frictionSolverType = USER_CONTACT_SOLVER_TYPE1; -#endif //USER_DEFINED_FRICTION_MODEL - - } - } + setDebugMode(btIDebugDraw::DBG_DrawText+btIDebugDraw::DBG_NoHelpText); + setCameraDistance(btScalar(20.)); } -//////////////////////////////////// - - - -//by default, Bullet will use its own nearcallback, but you can override it using dispatcher->setNearCallback() -void customNearCallback(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, const 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; - - void CcdPhysicsDemo::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 = getDeltaTimeMicroseconds() * 0.000001f; - -// printf("dt = %f: ",dt); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + //simple dynamics world doesn't handle fixed-time-stepping + float ms = getDeltaTimeMicroseconds(); + + ///step the simulation 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); - + m_dynamicsWorld->stepSimulation(1./60.);//ms / 1000000.f); //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 } + + renderme(); -#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"); + displayText(); +#if 0 + for (int i=0;igetDebugDrawer()->drawContactPoint(debugContacts[i],debugNormals[i],0,0,btVector3(1,0,0)); + } #endif - glFlush(); - //some additional debugging info -#ifdef PRINT_CONTACT_STATISTICS - printf("num manifolds: %i\n",gNumManifold); - printf("num gOverlappingPairs: %i\n",gOverlappingPairs); - -#endif //PRINT_CONTACT_STATISTICS - - glutSwapBuffers(); + glFlush(); + + swapBuffers(); + +} + + +void CcdPhysicsDemo::displayText() +{ + int lineWidth=440; + int xStart = m_glutScreenWidth - lineWidth; + int yStart = 20; + + if((getDebugMode() & btIDebugDraw::DBG_DrawText)!=0) + { + setOrthographicProjection(); + glDisable(GL_LIGHTING); + glColor3f(0, 0, 0); + char buf[124]; + + glRasterPos3f(xStart, yStart, 0); + switch (m_ccdMode) + { + case USE_CCD: + { + sprintf(buf,"Predictive contacts and motion clamping"); + break; + } + case USE_NO_CCD: + { + sprintf(buf,"CCD handling disabled"); + break; + } + default: + { + sprintf(buf,"unknown CCD setting"); + }; + }; + + GLDebugDrawString(xStart,20,buf); + glRasterPos3f(xStart, yStart, 0); + sprintf(buf,"Press 'p' to change CCD mode"); + yStart+=20; + GLDebugDrawString(xStart,yStart,buf); + glRasterPos3f(xStart, yStart, 0); + sprintf(buf,"Press '.' or right mouse to shoot bullets"); + yStart+=20; + GLDebugDrawString(xStart,yStart,buf); + glRasterPos3f(xStart, yStart, 0); + sprintf(buf,"space to restart, h(elp), t(ext), w(ire)"); + yStart+=20; + GLDebugDrawString(xStart,yStart,buf); + + resetPerspectiveProjection(); + glEnable(GL_LIGHTING); + } } @@ -294,233 +132,136 @@ void CcdPhysicsDemo::clientMoveAndDisplay() void CcdPhysicsDemo::displayCallback(void) { - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + renderme(); - //optional but useful: debug drawing + displayText(); + + //optional but useful: debug drawing to detect problems if (m_dynamicsWorld) + { m_dynamicsWorld->debugDrawWorld(); + } +#if 0 + for (int i=0;igetDebugDrawer()->drawContactPoint(debugContacts[i],debugNormals[i],0,0,btVector3(1,0,0)); + } +#endif glFlush(); - glutSwapBuffers(); + swapBuffers(); } -///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 CcdPhysicsDemo::initPhysics() { setTexturing(true); - setShadows(false); - -#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 btBoxShape (btVector3(CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS))); - m_collisionShapes.push_back(new btCylinderShape (btVector3(CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS))); -#endif + setShadows(true); + + m_ShootBoxInitialSpeed = 4000.f; - -#ifdef DO_BENCHMARK_PYRAMIDS - setCameraDistance(32.5f); -#endif - -#ifdef DO_BENCHMARK_PYRAMIDS - m_azi = 90.f; -#endif //DO_BENCHMARK_PYRAMIDS - - m_dispatcher=0; + ///collision configuration contains default setup for memory, collision setup m_collisionConfiguration = new btDefaultCollisionConfiguration(); +// m_collisionConfiguration->setConvexConvexMultipointIterations(); -#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); -#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 - + ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); -#endif //USE_PARALLEL_DISPATCHER - -#ifdef USE_CUSTOM_NEAR_CALLBACK - //this is optional - m_dispatcher->setNearCallback(customNearCallback); -#endif - + m_dispatcher->registerCollisionCreateFunc(BOX_SHAPE_PROXYTYPE,BOX_SHAPE_PROXYTYPE,m_collisionConfiguration->getCollisionAlgorithmCreateFunc(CONVEX_SHAPE_PROXYTYPE,CONVEX_SHAPE_PROXYTYPE)); m_broadphase = new btDbvtBroadphase(); -#ifdef COMPARE_WITH_QUICKSTEP - m_solver = new btOdeQuickstepConstraintSolver(); -#else + ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded) + btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver; + m_solver = sol; + + m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); + m_dynamicsWorld ->setDebugDrawer(&sDebugDrawer); + m_dynamicsWorld->getSolverInfo().m_splitImpulse=true; + m_dynamicsWorld->getSolverInfo().m_numIterations = 20; -#ifdef USE_PARALLEL_SOLVER - - m_threadSupportSolver = new Win32ThreadSupport(Win32ThreadSupport::Win32ThreadConstructionInfo( - "solver", - processSolverTask, - createSolverLocalStoreMemory, - maxNumOutstandingTasks)); - - m_solver = new btParallelSequentialImpulseSolver(m_threadSupportSolver,maxNumOutstandingTasks); -#else - btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver(); - - m_solver = solver;//new btOdeQuickstepConstraintSolver(); - -#endif //USE_PARALLEL_SOLVER - -#endif - - - - btDiscreteDynamicsWorld* world = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); - m_dynamicsWorld = world; - - ///SOLVER_RANDMIZE_ORDER makes cylinder stacking a bit more stable - world->getSolverInfo().m_solverMode |= SOLVER_RANDMIZE_ORDER; - -#ifdef USER_DEFINED_FRICTION_MODEL - //user defined friction model is not supported in 'cache friendly' solver yet, so switch to old solver - - world->getSolverInfo().m_solverMode = SOLVER_RANDMIZE_ORDER; - -#endif //USER_DEFINED_FRICTION_MODEL - -#ifdef DO_BENCHMARK_PYRAMIDS - world->getSolverInfo().m_numIterations = 4; -#endif //DO_BENCHMARK_PYRAMIDS - - m_dynamicsWorld->getDispatchInfo().m_enableSPU = true; - m_dynamicsWorld->setGravity(btVector3(0,-10,0)); - - - -#ifdef USER_DEFINED_FRICTION_MODEL + if (m_ccdMode==USE_CCD) { - //m_solver->setContactSolverFunc(ContactSolverFunc func,USER_CONTACT_SOLVER_TYPE1,DEFAULT_CONTACT_SOLVER_TYPE); - solver->SetFrictionSolverFunc(myFrictionModel,USER_CONTACT_SOLVER_TYPE1,DEFAULT_CONTACT_SOLVER_TYPE); - solver->SetFrictionSolverFunc(myFrictionModel,DEFAULT_CONTACT_SOLVER_TYPE,USER_CONTACT_SOLVER_TYPE1); - solver->SetFrictionSolverFunc(myFrictionModel,USER_CONTACT_SOLVER_TYPE1,USER_CONTACT_SOLVER_TYPE1); - //m_physicsEnvironmentPtr->setNumIterations(2); + m_dynamicsWorld->getDispatchInfo().m_useContinuous=true; + } else + { + m_dynamicsWorld->getDispatchInfo().m_useContinuous=false; } -#endif //USER_DEFINED_FRICTION_MODEL + m_dynamicsWorld->setGravity(btVector3(0,-10,0)); + ///create a few basic rigid bodies + btBoxShape* box = new btBoxShape(btVector3(btScalar(110.),btScalar(1.),btScalar(110.))); + box->initializePolyhedralFeatures(); + btCollisionShape* groundShape = box; - int i; +// btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),50); + + m_collisionShapes.push_back(groundShape); + m_collisionShapes.push_back(new btCylinderShape (btVector3(CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS))); - btTransform tr; - tr.setIdentity(); + btTransform groundTransform; + groundTransform.setIdentity(); + //groundTransform.setOrigin(btVector3(5,5,5)); - - for (i=0;i0) + btScalar mass(0.); + + //rigidbody is dynamic if and only if mass is non zero, otherwise static + bool isDynamic = (mass != 0.f); + + btVector3 localInertia(0,0,0); + if (isDynamic) + groundShape->calculateLocalInertia(mass,localInertia); + + //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects + btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia); + btRigidBody* body = new btRigidBody(rbInfo); + + //add the body to the dynamics world + m_dynamicsWorld->addRigidBody(body); + } + + + { + //create a few dynamic rigidbodies + // Re-using the same collision is better for memory usage and performance + + btCollisionShape* colShape = new btBoxShape(btVector3(1,1,1)); + + //btCollisionShape* colShape = new btSphereShape(btScalar(1.)); + m_collisionShapes.push_back(colShape); + + /// Create Dynamic Objects + btTransform startTransform; + startTransform.setIdentity(); + + btScalar mass(1.f); + + //rigidbody is dynamic if and only if mass is non zero, otherwise static + bool isDynamic = (mass != 0.f); + + btVector3 localInertia(0,0,0); + if (isDynamic) + colShape->calculateLocalInertia(mass,localInertia); + + int gNumObjects = 120; + int i; + for (i=0;iaddChildShape(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); @@ -538,83 +279,91 @@ int maxNumOutstandingTasks = 4; 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; + + btRigidBody* body = localCreateRigidBody(mass,trans,shape); + + + ///when using m_ccdMode + if (m_ccdMode==USE_CCD) + { + body->setCcdMotionThreshold(1e-7); + body->setCcdSweptSphereRadius(0.9*CUBE_HALF_EXTENTS); + } } - - 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->setCcdMotionThreshold( 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 CcdPhysicsDemo::clientResetScene() +{ + exitPhysics(); + initPhysics(); +} +void CcdPhysicsDemo::keyboardCallback(unsigned char key, int x, int y) +{ + if (key=='p') + { + switch (m_ccdMode) + { + case USE_CCD: + { + m_ccdMode = USE_NO_CCD; + break; + } + case USE_NO_CCD: + default: + { + m_ccdMode = USE_CCD; + } + }; + clientResetScene(); + } else + { + DemoApplication::keyboardCallback(key,x,y); + } +} + + +void CcdPhysicsDemo::shootBox(const btVector3& destination) +{ + + if (m_dynamicsWorld) + { + float mass = 1.f; + btTransform startTransform; + startTransform.setIdentity(); + btVector3 camPos = getCameraPosition(); + startTransform.setOrigin(camPos); + + setShootBoxShape (); + + + btRigidBody* body = this->localCreateRigidBody(mass, startTransform,m_shootBoxShape); + body->setLinearFactor(btVector3(1,1,1)); + //body->setRestitution(1); + + btVector3 linVel(destination[0]-camPos[0],destination[1]-camPos[1],destination[2]-camPos[2]); + linVel.normalize(); + linVel*=m_ShootBoxInitialSpeed; + + body->getWorldTransform().setOrigin(camPos); + body->getWorldTransform().setRotation(btQuaternion(0,0,0,1)); + body->setLinearVelocity(linVel); + body->setAngularVelocity(btVector3(0,0,0)); + body->setContactProcessingThreshold(1e30); + + ///when using m_ccdMode, disable regular CCD + if (m_ccdMode==USE_CCD) + { + body->setCcdMotionThreshold(0.0001); + body->setCcdSweptSphereRadius(0.4f); + } + + } +} @@ -622,7 +371,6 @@ int maxNumOutstandingTasks = 4; void CcdPhysicsDemo::exitPhysics() { - //cleanup in the reverse order of creation/initialization //remove the rigidbodies from the dynamics world and delete them @@ -643,42 +391,23 @@ void CcdPhysicsDemo::exitPhysics() for (int j=0;jgetDispatchInfo().m_allowedCcdPenetration=0.0001f; #ifdef DYNAMIC_CHARACTER_CONTROLLER m_character = new DynamicCharacterController (); diff --git a/Demos/ConcaveRaycastDemo/ConcaveRaycastDemo.cpp b/Demos/ConcaveRaycastDemo/ConcaveRaycastDemo.cpp index c272517ba..d880402d0 100644 --- a/Demos/ConcaveRaycastDemo/ConcaveRaycastDemo.cpp +++ b/Demos/ConcaveRaycastDemo/ConcaveRaycastDemo.cpp @@ -20,22 +20,7 @@ subject to the following restrictions: #include "GL_ShapeDrawer.h" #include "GlutStuff.h" -//#define BATCH_RAYCASTER - -#ifdef BATCH_RAYCASTER -#include "BulletMultiThreaded/SpuBatchRaycaster.h" -static SpuBatchRaycaster* gBatchRaycaster = NULL; - - -#ifdef USE_LIBSPE2 -#include "BulletMultiThreaded/SpuLibspe2Support.h" -#elif defined (_WIN32) -#include "BulletMultiThreaded/Win32ThreadSupport.h" -#else -//other platforms run the parallel code sequentially (until pthread support or other parallel implementation is added) -#include "BulletMultiThreaded/SequentialThreadSupport.h" -#endif //USE_LIBSPE2 -#endif //BATCH_RAYCASTER +static GLDebugDrawer sDebugDraw; static btVector3* gVertices=0; static int* gIndices=0; @@ -290,6 +275,7 @@ void ConcaveRaycastDemo::keyboardCallback(unsigned char key, int x, int y) void ConcaveRaycastDemo::initPhysics() { + m_ShootBoxInitialSpeed = 1000; #define TRISIZE 10.f @@ -346,7 +332,8 @@ void ConcaveRaycastDemo::initPhysics() m_broadphase = new btAxisSweep3(worldMin,worldMax); m_solver = new btSequentialImpulseConstraintSolver(); m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); - + m_dynamicsWorld->getSolverInfo().m_splitImpulse=true; + m_dynamicsWorld->setDebugDrawer(&sDebugDraw); float mass = 0.f; btTransform startTransform; @@ -387,6 +374,41 @@ int maxNumOutstandingTasks = 4; raycastBar = btRaycastBar (4000.0, 0.0); //raycastBar = btRaycastBar (true, 40.0, -50.0, 50.0); + + + + + { + btVector3 camPos(0.000000,10.260604,-28.190779); + btVector3 destination(6958.333333,-8539.096384,7501.875480); + + float mass = 1.f; + btTransform startTransform; + startTransform.setIdentity(); + startTransform.setOrigin(camPos); + + setShootBoxShape (); + + btRigidBody* body = this->localCreateRigidBody(mass, startTransform,m_shootBoxShape); + body->setLinearFactor(btVector3(1,1,1)); + //body->setRestitution(1); + + btVector3 linVel(destination[0]-camPos[0],destination[1]-camPos[1],destination[2]-camPos[2]); + linVel.normalize(); + linVel*=m_ShootBoxInitialSpeed; + + body->getWorldTransform().setOrigin(camPos); + body->getWorldTransform().setRotation(btQuaternion(0,0,0,1)); + body->setLinearVelocity(linVel); + body->setAngularVelocity(btVector3(0,0,0)); + body->setCcdMotionThreshold(0.5); + body->setCcdSweptSphereRadius(0.9f); + printf("shootBox uid=%d\n", body->getBroadphaseHandle()->getUid()); + printf("camPos=%f,%f,%f\n",camPos.getX(),camPos.getY(),camPos.getZ()); + printf("destination=%f,%f,%f\n",destination.getX(),destination.getY(),destination.getZ()); + + + } } void ConcaveRaycastDemo::clientMoveAndDisplay() @@ -411,7 +433,7 @@ void ConcaveRaycastDemo::clientMoveAndDisplay() m_dynamicsWorld->getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(staticBody->getBroadphaseHandle(),getDynamicsWorld()->getDispatcher()); } - m_dynamicsWorld->stepSimulation(dt); + m_dynamicsWorld->stepSimulation(1./60.,0); //optional but useful: debug drawing m_dynamicsWorld->debugDrawWorld(); @@ -432,6 +454,10 @@ void ConcaveRaycastDemo::displayCallback(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + //optional but useful: debug drawing + if (m_dynamicsWorld) + m_dynamicsWorld->debugDrawWorld(); + renderme(); raycastBar.draw (); glFlush(); diff --git a/Demos/ConvexHullDistance/ConvexHullDistanceDemo.cpp b/Demos/ConvexHullDistance/ConvexHullDistanceDemo.cpp index 2242c88c0..cef9e8567 100644 --- a/Demos/ConvexHullDistance/ConvexHullDistanceDemo.cpp +++ b/Demos/ConvexHullDistance/ConvexHullDistanceDemo.cpp @@ -39,7 +39,7 @@ subject to the following restrictions: #define TaruVtxCount 43 -static float TaruVtx[] = { +static btScalar TaruVtx[] = { 1.08664f,-1.99237f,0.0f, 0.768369f,-1.99237f,-0.768369f, 1.28852f,1.34412e-007f,-1.28852f, @@ -246,7 +246,7 @@ int main(int argc,char** argv) //btVector3 points1[5]={btVector3(1,0,0),btVector3(0,1,0),btVector3(0,0,1),btVector3(0,0,-1),btVector3(-1,-1,0)}; btConvexHullShape hullA(&points0[0].getX(),3); - btConvexHullShape hullB(TaruVtx,TaruVtxCount,3*sizeof(float)); + btConvexHullShape hullB(TaruVtx,TaruVtxCount,3*sizeof(btScalar)); shapePtr[0] = &hullA; shapePtr[1] = &hullB; @@ -276,7 +276,7 @@ void clientDisplay(void) { //GL_ShapeDrawer::drawCoordSystem(); - float m[16]; + btScalar m[16]; int i; #ifdef USE_GJK btGjkEpaPenetrationDepthSolver epa; diff --git a/Demos/FractureDemo/FractureDemo.cpp b/Demos/FractureDemo/FractureDemo.cpp index e2602de99..16b739657 100644 --- a/Demos/FractureDemo/FractureDemo.cpp +++ b/Demos/FractureDemo/FractureDemo.cpp @@ -76,7 +76,6 @@ void FractureDemo::initPhysics() btFractureDynamicsWorld* fractureWorld = new btFractureDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); m_dynamicsWorld = fractureWorld; - m_dynamicsWorld->getDispatchInfo().m_convexMaxDistanceUseCPT = true; m_ShootBoxInitialSpeed=100; //m_splitImpulse removes the penetration resolution from the applied impulse, otherwise objects might fracture due to deep penetrations. diff --git a/Demos/FractureDemo/btFractureBody.cpp b/Demos/FractureDemo/btFractureBody.cpp index e7513f647..b7a52896b 100644 --- a/Demos/FractureDemo/btFractureBody.cpp +++ b/Demos/FractureDemo/btFractureBody.cpp @@ -27,8 +27,8 @@ void btFractureBody::recomputeConnectivity(btCollisionWorld* world) } virtual btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObject* colObj0,int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1) { - //@todo additional check on cp? - m_connected = true; + if (cp.getDistance()<=0) + m_connected = true; return 1.f; } }; diff --git a/Demos/InternalEdgeDemo/InternalEdgeDemo.cpp b/Demos/InternalEdgeDemo/InternalEdgeDemo.cpp index 264092261..bac267f65 100644 --- a/Demos/InternalEdgeDemo/InternalEdgeDemo.cpp +++ b/Demos/InternalEdgeDemo/InternalEdgeDemo.cpp @@ -342,8 +342,7 @@ void InternalEdgeDemo::initPhysics() #endif //USE_TRIMESH_SHAPE m_collisionConfiguration = new btDefaultCollisionConfiguration(); - m_collisionConfiguration->setConvexConvexMultipointIterations(10,5); - + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); @@ -367,7 +366,9 @@ void InternalEdgeDemo::initPhysics() startTransform.setIdentity(); startTransform.setOrigin(btVector3(0,-2,0)); - btCollisionShape* colShape = new btBoxShape(btVector3(1,1,1)); + btBoxShape* colShape = new btBoxShape(btVector3(1,1,1)); + colShape->initializePolyhedralFeatures(); + //colShape->setMargin(0.f); colShape->setMargin(0.1f); @@ -399,7 +400,7 @@ void InternalEdgeDemo::initPhysics() staticBody->setCollisionFlags(staticBody->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); getDynamicsWorld()->setDebugDrawer(&gDebugDrawer); - setDebugMode(btIDebugDraw::DBG_DrawText|btIDebugDraw::DBG_NoHelpText); + setDebugMode(btIDebugDraw::DBG_DrawText|btIDebugDraw::DBG_NoHelpText+btIDebugDraw::DBG_DrawWireframe+btIDebugDraw::DBG_DrawContactPoints); #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW @@ -482,9 +483,7 @@ void InternalEdgeDemo::clientMoveAndDisplay() //m_dynamicsWorld->stepSimulation(1./60.,100,1./800.); //m_dynamicsWorld->stepSimulation(1./60.,0); - //optional but useful: debug drawing - m_dynamicsWorld->debugDrawWorld(); - + int lineWidth=450; int xStart = m_glutScreenWidth - lineWidth; int yStart = 20; @@ -519,6 +518,10 @@ void InternalEdgeDemo::clientMoveAndDisplay() renderme(); + //optional but useful: debug drawing + m_dynamicsWorld->debugDrawWorld(); + + glFlush(); swapBuffers(); diff --git a/Demos/OpenCLClothDemo/bmpLoader.h b/Demos/OpenCLClothDemo/bmpLoader.h index 301ad0d12..69964d68d 100644 --- a/Demos/OpenCLClothDemo/bmpLoader.h +++ b/Demos/OpenCLClothDemo/bmpLoader.h @@ -17,8 +17,7 @@ subject to the following restrictions: #ifndef BMPLOADER_H_ #define BMPLOADER_H_ -#include -#include +#include namespace amd { diff --git a/Demos/OpenCLClothDemo/cloth.h b/Demos/OpenCLClothDemo/cloth.h index 800133403..bb743c8dc 100644 --- a/Demos/OpenCLClothDemo/cloth.h +++ b/Demos/OpenCLClothDemo/cloth.h @@ -182,7 +182,7 @@ class piece_of_cloth glBindTexture(GL_TEXTURE_2D, 0); } else { - std::cout << "ERROR: could not load bitmap, using placeholder " << std::endl; + printf("ERROR: could not load bitmap, using placeholder\n"); GLubyte* image=new GLubyte[256*256*3]; for(int y=0;y<256;++y) diff --git a/Demos/OpenCLClothDemo/gl_win.cpp b/Demos/OpenCLClothDemo/gl_win.cpp index 1826330a3..b1143ff71 100644 --- a/Demos/OpenCLClothDemo/gl_win.cpp +++ b/Demos/OpenCLClothDemo/gl_win.cpp @@ -17,14 +17,10 @@ subject to the following restrictions: #include "clstuff.h" #include "gl_win.h" -#include -#include -#include -#include -#include +#include +#include #include -#include -#include +#include //#ifndef _WIN32 && !defined(__APPLE__) diff --git a/Demos/OpenGL/DemoApplication.cpp b/Demos/OpenGL/DemoApplication.cpp index 859d67d29..7129bf763 100644 --- a/Demos/OpenGL/DemoApplication.cpp +++ b/Demos/OpenGL/DemoApplication.cpp @@ -540,7 +540,9 @@ void DemoApplication::setShootBoxShape () { if (!m_shootBoxShape) { - m_shootBoxShape = new btBoxShape(btVector3(.5f,.5f,.5f)); + btBoxShape* box = new btBoxShape(btVector3(.5f,.5f,.5f)); + box->initializePolyhedralFeatures(); + m_shootBoxShape = box; } } @@ -569,8 +571,11 @@ void DemoApplication::shootBox(const btVector3& destination) body->getWorldTransform().setRotation(btQuaternion(0,0,0,1)); body->setLinearVelocity(linVel); body->setAngularVelocity(btVector3(0,0,0)); - body->setCcdMotionThreshold(1.); - body->setCcdSweptSphereRadius(0.2f); + body->setCcdMotionThreshold(0.5); + body->setCcdSweptSphereRadius(0.9f); +// printf("shootBox uid=%d\n", body->getBroadphaseHandle()->getUid()); +// printf("camPos=%f,%f,%f\n",camPos.getX(),camPos.getY(),camPos.getZ()); +// printf("destination=%f,%f,%f\n",destination.getX(),destination.getY(),destination.getZ()); } } @@ -1318,7 +1323,7 @@ void DemoApplication::renderme() resetPerspectiveProjection(); } - glEnable(GL_LIGHTING); + glDisable(GL_LIGHTING); } diff --git a/Extras/Serialize/BulletWorldImporter/btBulletWorldImporter.cpp b/Extras/Serialize/BulletWorldImporter/btBulletWorldImporter.cpp index f9d386546..eed947a60 100644 --- a/Extras/Serialize/BulletWorldImporter/btBulletWorldImporter.cpp +++ b/Extras/Serialize/BulletWorldImporter/btBulletWorldImporter.cpp @@ -860,7 +860,6 @@ bool btBulletWorldImporter::convertAllObjects( bParse::btBulletFile* bulletFile } } - printf("bla"); } diff --git a/src/BulletCollision/BroadphaseCollision/btDispatcher.h b/src/BulletCollision/BroadphaseCollision/btDispatcher.h index 77e784ec2..a79cf9402 100644 --- a/src/BulletCollision/BroadphaseCollision/btDispatcher.h +++ b/src/BulletCollision/BroadphaseCollision/btDispatcher.h @@ -40,15 +40,14 @@ struct btDispatcherInfo m_stepCount(0), m_dispatchFunc(DISPATCH_DISCRETE), m_timeOfImpact(btScalar(1.)), - m_useContinuous(false), + m_useContinuous(true), m_debugDraw(0), - m_enableSatConvex(true), + m_enableSatConvex(false), m_enableSPU(true), m_useEpa(true), m_allowedCcdPenetration(btScalar(0.04)), m_useConvexConservativeDistanceUtil(false), m_convexConservativeDistanceThreshold(0.0f), - m_convexMaxDistanceUseCPT(false), m_stackAllocator(0) { @@ -65,7 +64,6 @@ struct btDispatcherInfo btScalar m_allowedCcdPenetration; bool m_useConvexConservativeDistanceUtil; btScalar m_convexConservativeDistanceThreshold; - bool m_convexMaxDistanceUseCPT; btStackAlloc* m_stackAllocator; }; diff --git a/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp b/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp index 206ff4028..807b3d66b 100644 --- a/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp +++ b/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp @@ -155,7 +155,7 @@ void btCollisionWorld::updateSingleAabb(btCollisionObject* colObj) minAabb -= contactThreshold; maxAabb += contactThreshold; - if(getDispatchInfo().m_convexMaxDistanceUseCPT) + if(getDispatchInfo().m_useContinuous && colObj->getInternalType()==btCollisionObject::CO_RIGID_BODY) { btVector3 minAabb2,maxAabb2; colObj->getCollisionShape()->getAabb(colObj->getInterpolationWorldTransform(),minAabb2,maxAabb2); @@ -1452,12 +1452,14 @@ void btCollisionWorld::debugDrawWorld() btVector3 minAabb2,maxAabb2; - colObj->getCollisionShape()->getAabb(colObj->getInterpolationWorldTransform(),minAabb2,maxAabb2); - minAabb2 -= contactThreshold; - maxAabb2 += contactThreshold; - - minAabb.setMin(minAabb2); - maxAabb.setMax(maxAabb2); + if(colObj->getInternalType()==btCollisionObject::CO_RIGID_BODY) + { + colObj->getCollisionShape()->getAabb(colObj->getInterpolationWorldTransform(),minAabb2,maxAabb2); + minAabb2 -= contactThreshold; + maxAabb2 += contactThreshold; + minAabb.setMin(minAabb2); + maxAabb.setMax(maxAabb2); + } m_debugDrawer->drawAabb(minAabb,maxAabb,colorvec); } diff --git a/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp b/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp index 81ffa2a19..b4e2acc90 100644 --- a/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp +++ b/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp @@ -361,13 +361,14 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl } else #endif //USE_SEPDISTANCE_UTIL2 { - if (dispatchInfo.m_convexMaxDistanceUseCPT) - { - input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactProcessingThreshold(); - } else - { - input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactBreakingThreshold(); - } + //if (dispatchInfo.m_convexMaxDistanceUseCPT) + //{ + // input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactProcessingThreshold(); + //} else + //{ + input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactBreakingThreshold(); +// } + input.m_maximumDistanceSquared*= input.m_maximumDistanceSquared; } diff --git a/src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp b/src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp index d97096d9f..888591829 100644 --- a/src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp +++ b/src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp @@ -68,9 +68,53 @@ void btContactConstraint::buildJacobian() #include "LinearMath/btMinMax.h" #include "BulletCollision/NarrowPhaseCollision/btManifoldPoint.h" -#define ASSERT2 btAssert -#define USE_INTERNAL_APPLY_IMPULSE 1 + +//response between two dynamic objects without friction, assuming 0 penetration depth +btScalar resolveSingleCollision( + btRigidBody* body1, + btCollisionObject* colObj2, + const btVector3& contactPositionWorld, + const btVector3& contactNormalOnB, + const btContactSolverInfo& solverInfo, + btScalar distance) +{ + btRigidBody* body2 = btRigidBody::upcast(colObj2); + + + const btVector3& normal = contactNormalOnB; + + btVector3 rel_pos1 = contactPositionWorld - body1->getWorldTransform().getOrigin(); + btVector3 rel_pos2 = contactPositionWorld - colObj2->getWorldTransform().getOrigin(); + + btVector3 vel1 = body1->getVelocityInLocalPoint(rel_pos1); + btVector3 vel2 = body2? body2->getVelocityInLocalPoint(rel_pos2) : btVector3(0,0,0); + btVector3 vel = vel1 - vel2; + btScalar rel_vel; + rel_vel = normal.dot(vel); + + btScalar combinedRestitution = body1->getRestitution() * colObj2->getRestitution(); + btScalar restitution = combinedRestitution* -rel_vel; + + btScalar positionalError = solverInfo.m_erp *-distance /solverInfo.m_timeStep ; + btScalar velocityError = -(1.0f + restitution) * rel_vel;// * damping; + btScalar denom0 = body1->computeImpulseDenominator(contactPositionWorld,normal); + btScalar denom1 = body2? body2->computeImpulseDenominator(contactPositionWorld,normal) : 0.f; + btScalar relaxation = 1.f; + btScalar jacDiagABInv = relaxation/(denom0+denom1); + + btScalar penetrationImpulse = positionalError * jacDiagABInv; + btScalar velocityImpulse = velocityError * jacDiagABInv; + + btScalar normalImpulse = penetrationImpulse+velocityImpulse; + normalImpulse = 0.f > normalImpulse ? 0.f: normalImpulse; + + body1->applyImpulse(normal*(normalImpulse), rel_pos1); + if (body2) + body2->applyImpulse(-normal*(normalImpulse), rel_pos2); + + return normalImpulse; +} //bilateral constraint between two dynamic objects @@ -83,7 +127,7 @@ void resolveSingleBilateral(btRigidBody& body1, const btVector3& pos1, btScalar normalLenSqr = normal.length2(); - ASSERT2(btFabs(normalLenSqr) < btScalar(1.1)); + btAssert(btFabs(normalLenSqr) < btScalar(1.1)); if (normalLenSqr > btScalar(1.1)) { impulse = btScalar(0.); diff --git a/src/BulletDynamics/ConstraintSolver/btContactConstraint.h b/src/BulletDynamics/ConstraintSolver/btContactConstraint.h index 2fcaeff25..477c79d17 100644 --- a/src/BulletDynamics/ConstraintSolver/btContactConstraint.h +++ b/src/BulletDynamics/ConstraintSolver/btContactConstraint.h @@ -57,6 +57,9 @@ public: }; +///very basic collision resolution without friction +btScalar resolveSingleCollision(btRigidBody* body1, class btCollisionObject* colObj2, const btVector3& contactPositionWorld,const btVector3& contactNormalOnB, const struct btContactSolverInfo& solverInfo,btScalar distance); + ///resolveSingleBilateral is an obsolete methods used for vehicle friction between two dynamic objects void resolveSingleBilateral(btRigidBody& body1, const btVector3& pos1, diff --git a/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp b/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp index ce5f6f746..b08dcf0b8 100644 --- a/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp +++ b/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp @@ -35,6 +35,8 @@ subject to the following restrictions: #include "BulletDynamics/ConstraintSolver/btConeTwistConstraint.h" #include "BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h" #include "BulletDynamics/ConstraintSolver/btSliderConstraint.h" +#include "BulletDynamics/ConstraintSolver/btContactConstraint.h" + #include "LinearMath/btIDebugDraw.h" #include "BulletCollision/CollisionShapes/btSphereShape.h" @@ -325,7 +327,8 @@ void btDiscreteDynamicsWorld::internalSingleStepSimulation(btScalar timeStep) ///perform collision detection performDiscreteCollisionDetection(); - addSpeculativeContacts(timeStep); + if (getDispatchInfo().m_useContinuous) + addSpeculativeContacts(timeStep); calculateSimulationIslands(); @@ -851,36 +854,93 @@ void btDiscreteDynamicsWorld::integrateTransforms(btScalar timeStep) if (body->isActive() && (!body->isStaticOrKinematicObject())) { + body->predictIntegratedTransform(timeStep, predictedTrans); + btScalar squareMotion = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2(); - if (body->getCcdSquareMotionThreshold() && body->getCcdSquareMotionThreshold() < squareMotion) + + + if (getDispatchInfo().m_useContinuous && body->getCcdSquareMotionThreshold() && body->getCcdSquareMotionThreshold() < squareMotion) { BT_PROFILE("CCD motion clamping"); if (body->getCollisionShape()->isConvex()) { gNumClampedCcdMotions++; - +#ifdef USE_STATIC_ONLY + class StaticOnlyCallback : public btClosestNotMeConvexResultCallback + { + public: + + StaticOnlyCallback (btCollisionObject* me,const btVector3& fromA,const btVector3& toA,btOverlappingPairCache* pairCache,btDispatcher* dispatcher) : + btClosestNotMeConvexResultCallback(me,fromA,toA,pairCache,dispatcher) + { + } + + virtual bool needsCollision(btBroadphaseProxy* proxy0) const + { + btCollisionObject* otherObj = (btCollisionObject*) proxy0->m_clientObject; + if (!otherObj->isStaticOrKinematicObject()) + return false; + return btClosestNotMeConvexResultCallback::needsCollision(proxy0); + } + }; + + StaticOnlyCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache(),getDispatcher()); +#else btClosestNotMeConvexResultCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache(),getDispatcher()); +#endif //btConvexShape* convexShape = static_cast(body->getCollisionShape()); btSphereShape tmpSphere(body->getCcdSweptSphereRadius());//btConvexShape* convexShape = static_cast(body->getCollisionShape()); + sweepResults.m_allowedPenetration=getDispatchInfo().m_allowedCcdPenetration; sweepResults.m_collisionFilterGroup = body->getBroadphaseProxy()->m_collisionFilterGroup; sweepResults.m_collisionFilterMask = body->getBroadphaseProxy()->m_collisionFilterMask; + btTransform modifiedPredictedTrans = predictedTrans; + modifiedPredictedTrans.setBasis(body->getWorldTransform().getBasis()); - convexSweepTest(&tmpSphere,body->getWorldTransform(),predictedTrans,sweepResults); + convexSweepTest(&tmpSphere,body->getWorldTransform(),modifiedPredictedTrans,sweepResults); if (sweepResults.hasHit() && (sweepResults.m_closestHitFraction < 1.f)) { + + //printf("clamped integration to hit fraction = %f\n",fraction); body->setHitFraction(sweepResults.m_closestHitFraction); body->predictIntegratedTransform(timeStep*body->getHitFraction(), predictedTrans); body->setHitFraction(0.f); - body->setLinearVelocity(btVector3(0,0.1,0)); + body->proceedToTransform( predictedTrans); -// printf("clamped integration to hit fraction = %f\n",fraction); +#if 0 + btVector3 linVel = body->getLinearVelocity(); + + btScalar maxSpeed = body->getCcdMotionThreshold()/getSolverInfo().m_timeStep; + btScalar maxSpeedSqr = maxSpeed*maxSpeed; + if (linVel.length2()>maxSpeedSqr) + { + linVel.normalize(); + linVel*= maxSpeed; + body->setLinearVelocity(linVel); + btScalar ms2 = body->getLinearVelocity().length2(); + body->predictIntegratedTransform(timeStep, predictedTrans); + + btScalar sm2 = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2(); + btScalar smt = body->getCcdSquareMotionThreshold(); + printf("sm2=%f\n",sm2); + } +#else + //response between two dynamic objects without friction, assuming 0 penetration depth + btScalar appliedImpulse = 0.f; + btScalar depth = 0.f; + appliedImpulse = resolveSingleCollision(body,sweepResults.m_hitCollisionObject,sweepResults.m_hitPointWorld,sweepResults.m_hitNormalWorld,getSolverInfo(), depth); + + +#endif + + continue; } } } + body->proceedToTransform( predictedTrans); } } diff --git a/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuContactResult.cpp b/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuContactResult.cpp index a71095380..bd71373cf 100644 --- a/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuContactResult.cpp +++ b/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuContactResult.cpp @@ -102,9 +102,14 @@ bool ManifoldResultAddContactPoint(const btVector3& normalOnBInWorld, #ifdef DEBUG_SPU_COLLISION_DETECTION spu_printf("SPU: contactTreshold %f\n",contactTreshold); #endif //DEBUG_SPU_COLLISION_DETECTION - if (depth > manifoldPtr->getContactBreakingThreshold()) + //if (depth > manifoldPtr->getContactBreakingThreshold()) + // return false; + + if (depth > manifoldPtr->getContactProcessingThreshold()) return false; + + btVector3 pointA; btVector3 localA; btVector3 localB; @@ -156,6 +161,7 @@ bool ManifoldResultAddContactPoint(const btVector3& normalOnBInWorld, (*gContactAddedCallback)(newPt,m_body0,m_partId0,m_index0,m_body1,m_partId1,m_index1); } */ + manifoldPtr->addManifoldPoint(newPt); return true; diff --git a/src/BulletMultiThreaded/btParallelConstraintSolver.cpp b/src/BulletMultiThreaded/btParallelConstraintSolver.cpp index 77e7d3105..447905c1b 100644 --- a/src/BulletMultiThreaded/btParallelConstraintSolver.cpp +++ b/src/BulletMultiThreaded/btParallelConstraintSolver.cpp @@ -1138,6 +1138,9 @@ btScalar btParallelConstraintSolver::solveGroup(btCollisionObject** bodies1,int pfxSetBroadphaseFlag(pair,0); int contactId = m-offsetContactManifolds; + //likely the contact pool is not contiguous, make sure to allocate large enough contact pool + btAssert(contactId>=0); + btAssert(contactIdgetInternalManifoldPool()->getUsedCount()); pfxSetContactId(pair,contactId); pfxSetNumConstraints(pair,numPosPoints);//manifoldPtr[i]->getNumContacts()); diff --git a/src/LinearMath/btScalar.h b/src/LinearMath/btScalar.h index 6c0e50eb5..d36af1e84 100644 --- a/src/LinearMath/btScalar.h +++ b/src/LinearMath/btScalar.h @@ -25,8 +25,6 @@ subject to the following restrictions: #include #include //size_t for MSVC 6.0 -#include -#include #include /* SVN $Revision$ on $Date$ from http://bullet.googlecode.com*/