diff options
author | Alon Zakai <alonzakai@gmail.com> | 2011-04-21 17:55:35 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2011-04-21 17:55:35 -0700 |
commit | 887ce3dde89410d012a708c3ec454f679b2e5b1e (patch) | |
tree | daeadbc86bf721a5d4fff109a1d87a4c69215905 /tests/bullet/src/BulletDynamics/Dynamics | |
parent | b3f4022e35b34002f44aacde554cc8b3ea927500 (diff) |
update bullet test to compile from source
Diffstat (limited to 'tests/bullet/src/BulletDynamics/Dynamics')
11 files changed, 3854 insertions, 0 deletions
diff --git a/tests/bullet/src/BulletDynamics/Dynamics/Bullet-C-API.cpp b/tests/bullet/src/BulletDynamics/Dynamics/Bullet-C-API.cpp new file mode 100644 index 00000000..bd8e2748 --- /dev/null +++ b/tests/bullet/src/BulletDynamics/Dynamics/Bullet-C-API.cpp @@ -0,0 +1,405 @@ +/* +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. +*/ + +/* + Draft high-level generic physics C-API. For low-level access, use the physics SDK native API's. + Work in progress, functionality will be added on demand. + + If possible, use the richer Bullet C++ API, by including <src/btBulletDynamicsCommon.h> +*/ + +#include "Bullet-C-Api.h" +#include "btBulletDynamicsCommon.h" +#include "LinearMath/btAlignedAllocator.h" + + + +#include "LinearMath/btVector3.h" +#include "LinearMath/btScalar.h" +#include "LinearMath/btMatrix3x3.h" +#include "LinearMath/btTransform.h" +#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" +#include "BulletCollision/CollisionShapes/btTriangleShape.h" + +#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h" +#include "BulletCollision/NarrowPhaseCollision/btPointCollector.h" +#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" +#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkEpa2.h" +#include "BulletCollision/CollisionShapes/btMinkowskiSumShape.h" +#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h" +#include "BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h" +#include "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h" + + +/* + Create and Delete a Physics SDK +*/ + +struct btPhysicsSdk +{ + +// btDispatcher* m_dispatcher; +// btOverlappingPairCache* m_pairCache; +// btConstraintSolver* m_constraintSolver + + btVector3 m_worldAabbMin; + btVector3 m_worldAabbMax; + + + //todo: version, hardware/optimization settings etc? + btPhysicsSdk() + :m_worldAabbMin(-1000,-1000,-1000), + m_worldAabbMax(1000,1000,1000) + { + + } + + +}; + +plPhysicsSdkHandle plNewBulletSdk() +{ + void* mem = btAlignedAlloc(sizeof(btPhysicsSdk),16); + return (plPhysicsSdkHandle)new (mem)btPhysicsSdk; +} + +void plDeletePhysicsSdk(plPhysicsSdkHandle physicsSdk) +{ + btPhysicsSdk* phys = reinterpret_cast<btPhysicsSdk*>(physicsSdk); + btAlignedFree(phys); +} + + +/* Dynamics World */ +plDynamicsWorldHandle plCreateDynamicsWorld(plPhysicsSdkHandle physicsSdkHandle) +{ + btPhysicsSdk* physicsSdk = reinterpret_cast<btPhysicsSdk*>(physicsSdkHandle); + void* mem = btAlignedAlloc(sizeof(btDefaultCollisionConfiguration),16); + btDefaultCollisionConfiguration* collisionConfiguration = new (mem)btDefaultCollisionConfiguration(); + mem = btAlignedAlloc(sizeof(btCollisionDispatcher),16); + btDispatcher* dispatcher = new (mem)btCollisionDispatcher(collisionConfiguration); + mem = btAlignedAlloc(sizeof(btAxisSweep3),16); + btBroadphaseInterface* pairCache = new (mem)btAxisSweep3(physicsSdk->m_worldAabbMin,physicsSdk->m_worldAabbMax); + mem = btAlignedAlloc(sizeof(btSequentialImpulseConstraintSolver),16); + btConstraintSolver* constraintSolver = new(mem) btSequentialImpulseConstraintSolver(); + + mem = btAlignedAlloc(sizeof(btDiscreteDynamicsWorld),16); + return (plDynamicsWorldHandle) new (mem)btDiscreteDynamicsWorld(dispatcher,pairCache,constraintSolver,collisionConfiguration); +} +void plDeleteDynamicsWorld(plDynamicsWorldHandle world) +{ + //todo: also clean up the other allocations, axisSweep, pairCache,dispatcher,constraintSolver,collisionConfiguration + btDynamicsWorld* dynamicsWorld = reinterpret_cast< btDynamicsWorld* >(world); + btAlignedFree(dynamicsWorld); +} + +void plStepSimulation(plDynamicsWorldHandle world, plReal timeStep) +{ + btDynamicsWorld* dynamicsWorld = reinterpret_cast< btDynamicsWorld* >(world); + btAssert(dynamicsWorld); + dynamicsWorld->stepSimulation(timeStep); +} + +void plAddRigidBody(plDynamicsWorldHandle world, plRigidBodyHandle object) +{ + btDynamicsWorld* dynamicsWorld = reinterpret_cast< btDynamicsWorld* >(world); + btAssert(dynamicsWorld); + btRigidBody* body = reinterpret_cast< btRigidBody* >(object); + btAssert(body); + + dynamicsWorld->addRigidBody(body); +} + +void plRemoveRigidBody(plDynamicsWorldHandle world, plRigidBodyHandle object) +{ + btDynamicsWorld* dynamicsWorld = reinterpret_cast< btDynamicsWorld* >(world); + btAssert(dynamicsWorld); + btRigidBody* body = reinterpret_cast< btRigidBody* >(object); + btAssert(body); + + dynamicsWorld->removeRigidBody(body); +} + +/* Rigid Body */ + +plRigidBodyHandle plCreateRigidBody( void* user_data, float mass, plCollisionShapeHandle cshape ) +{ + btTransform trans; + trans.setIdentity(); + btVector3 localInertia(0,0,0); + btCollisionShape* shape = reinterpret_cast<btCollisionShape*>( cshape); + btAssert(shape); + if (mass) + { + shape->calculateLocalInertia(mass,localInertia); + } + void* mem = btAlignedAlloc(sizeof(btRigidBody),16); + btRigidBody::btRigidBodyConstructionInfo rbci(mass, 0,shape,localInertia); + btRigidBody* body = new (mem)btRigidBody(rbci); + body->setWorldTransform(trans); + body->setUserPointer(user_data); + return (plRigidBodyHandle) body; +} + +void plDeleteRigidBody(plRigidBodyHandle cbody) +{ + btRigidBody* body = reinterpret_cast< btRigidBody* >(cbody); + btAssert(body); + btAlignedFree( body); +} + + +/* Collision Shape definition */ + +plCollisionShapeHandle plNewSphereShape(plReal radius) +{ + void* mem = btAlignedAlloc(sizeof(btSphereShape),16); + return (plCollisionShapeHandle) new (mem)btSphereShape(radius); + +} + +plCollisionShapeHandle plNewBoxShape(plReal x, plReal y, plReal z) +{ + void* mem = btAlignedAlloc(sizeof(btBoxShape),16); + return (plCollisionShapeHandle) new (mem)btBoxShape(btVector3(x,y,z)); +} + +plCollisionShapeHandle plNewCapsuleShape(plReal radius, plReal height) +{ + //capsule is convex hull of 2 spheres, so use btMultiSphereShape + + const int numSpheres = 2; + btVector3 positions[numSpheres] = {btVector3(0,height,0),btVector3(0,-height,0)}; + btScalar radi[numSpheres] = {radius,radius}; + void* mem = btAlignedAlloc(sizeof(btMultiSphereShape),16); + return (plCollisionShapeHandle) new (mem)btMultiSphereShape(positions,radi,numSpheres); +} +plCollisionShapeHandle plNewConeShape(plReal radius, plReal height) +{ + void* mem = btAlignedAlloc(sizeof(btConeShape),16); + return (plCollisionShapeHandle) new (mem)btConeShape(radius,height); +} + +plCollisionShapeHandle plNewCylinderShape(plReal radius, plReal height) +{ + void* mem = btAlignedAlloc(sizeof(btCylinderShape),16); + return (plCollisionShapeHandle) new (mem)btCylinderShape(btVector3(radius,height,radius)); +} + +/* Convex Meshes */ +plCollisionShapeHandle plNewConvexHullShape() +{ + void* mem = btAlignedAlloc(sizeof(btConvexHullShape),16); + return (plCollisionShapeHandle) new (mem)btConvexHullShape(); +} + + +/* Concave static triangle meshes */ +plMeshInterfaceHandle plNewMeshInterface() +{ + return 0; +} + +plCollisionShapeHandle plNewCompoundShape() +{ + void* mem = btAlignedAlloc(sizeof(btCompoundShape),16); + return (plCollisionShapeHandle) new (mem)btCompoundShape(); +} + +void plAddChildShape(plCollisionShapeHandle compoundShapeHandle,plCollisionShapeHandle childShapeHandle, plVector3 childPos,plQuaternion childOrn) +{ + btCollisionShape* colShape = reinterpret_cast<btCollisionShape*>(compoundShapeHandle); + btAssert(colShape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE); + btCompoundShape* compoundShape = reinterpret_cast<btCompoundShape*>(colShape); + btCollisionShape* childShape = reinterpret_cast<btCollisionShape*>(childShapeHandle); + btTransform localTrans; + localTrans.setIdentity(); + localTrans.setOrigin(btVector3(childPos[0],childPos[1],childPos[2])); + localTrans.setRotation(btQuaternion(childOrn[0],childOrn[1],childOrn[2],childOrn[3])); + compoundShape->addChildShape(localTrans,childShape); +} + +void plSetEuler(plReal yaw,plReal pitch,plReal roll, plQuaternion orient) +{ + btQuaternion orn; + orn.setEuler(yaw,pitch,roll); + orient[0] = orn.getX(); + orient[1] = orn.getY(); + orient[2] = orn.getZ(); + orient[3] = orn.getW(); + +} + + +// extern void plAddTriangle(plMeshInterfaceHandle meshHandle, plVector3 v0,plVector3 v1,plVector3 v2); +// extern plCollisionShapeHandle plNewStaticTriangleMeshShape(plMeshInterfaceHandle); + + +void plAddVertex(plCollisionShapeHandle cshape, plReal x,plReal y,plReal z) +{ + btCollisionShape* colShape = reinterpret_cast<btCollisionShape*>( cshape); + (void)colShape; + btAssert(colShape->getShapeType()==CONVEX_HULL_SHAPE_PROXYTYPE); + btConvexHullShape* convexHullShape = reinterpret_cast<btConvexHullShape*>( cshape); + convexHullShape->addPoint(btVector3(x,y,z)); + +} + +void plDeleteShape(plCollisionShapeHandle cshape) +{ + btCollisionShape* shape = reinterpret_cast<btCollisionShape*>( cshape); + btAssert(shape); + btAlignedFree(shape); +} +void plSetScaling(plCollisionShapeHandle cshape, plVector3 cscaling) +{ + btCollisionShape* shape = reinterpret_cast<btCollisionShape*>( cshape); + btAssert(shape); + btVector3 scaling(cscaling[0],cscaling[1],cscaling[2]); + shape->setLocalScaling(scaling); +} + + + +void plSetPosition(plRigidBodyHandle object, const plVector3 position) +{ + btRigidBody* body = reinterpret_cast< btRigidBody* >(object); + btAssert(body); + btVector3 pos(position[0],position[1],position[2]); + btTransform worldTrans = body->getWorldTransform(); + worldTrans.setOrigin(pos); + body->setWorldTransform(worldTrans); +} + +void plSetOrientation(plRigidBodyHandle object, const plQuaternion orientation) +{ + btRigidBody* body = reinterpret_cast< btRigidBody* >(object); + btAssert(body); + btQuaternion orn(orientation[0],orientation[1],orientation[2],orientation[3]); + btTransform worldTrans = body->getWorldTransform(); + worldTrans.setRotation(orn); + body->setWorldTransform(worldTrans); +} + +void plSetOpenGLMatrix(plRigidBodyHandle object, plReal* matrix) +{ + btRigidBody* body = reinterpret_cast< btRigidBody* >(object); + btAssert(body); + btTransform& worldTrans = body->getWorldTransform(); + worldTrans.setFromOpenGLMatrix(matrix); +} + +void plGetOpenGLMatrix(plRigidBodyHandle object, plReal* matrix) +{ + btRigidBody* body = reinterpret_cast< btRigidBody* >(object); + btAssert(body); + body->getWorldTransform().getOpenGLMatrix(matrix); + +} + +void plGetPosition(plRigidBodyHandle object,plVector3 position) +{ + btRigidBody* body = reinterpret_cast< btRigidBody* >(object); + btAssert(body); + const btVector3& pos = body->getWorldTransform().getOrigin(); + position[0] = pos.getX(); + position[1] = pos.getY(); + position[2] = pos.getZ(); +} + +void plGetOrientation(plRigidBodyHandle object,plQuaternion orientation) +{ + btRigidBody* body = reinterpret_cast< btRigidBody* >(object); + btAssert(body); + const btQuaternion& orn = body->getWorldTransform().getRotation(); + orientation[0] = orn.getX(); + orientation[1] = orn.getY(); + orientation[2] = orn.getZ(); + orientation[3] = orn.getW(); +} + + + +//plRigidBodyHandle plRayCast(plDynamicsWorldHandle world, const plVector3 rayStart, const plVector3 rayEnd, plVector3 hitpoint, plVector3 normal); + +// extern plRigidBodyHandle plObjectCast(plDynamicsWorldHandle world, const plVector3 rayStart, const plVector3 rayEnd, plVector3 hitpoint, plVector3 normal); + +double plNearestPoints(float p1[3], float p2[3], float p3[3], float q1[3], float q2[3], float q3[3], float *pa, float *pb, float normal[3]) +{ + btVector3 vp(p1[0], p1[1], p1[2]); + btTriangleShape trishapeA(vp, + btVector3(p2[0], p2[1], p2[2]), + btVector3(p3[0], p3[1], p3[2])); + trishapeA.setMargin(0.000001f); + btVector3 vq(q1[0], q1[1], q1[2]); + btTriangleShape trishapeB(vq, + btVector3(q2[0], q2[1], q2[2]), + btVector3(q3[0], q3[1], q3[2])); + trishapeB.setMargin(0.000001f); + + // btVoronoiSimplexSolver sGjkSimplexSolver; + // btGjkEpaPenetrationDepthSolver penSolverPtr; + + static btSimplexSolverInterface sGjkSimplexSolver; + sGjkSimplexSolver.reset(); + + static btGjkEpaPenetrationDepthSolver Solver0; + static btMinkowskiPenetrationDepthSolver Solver1; + + btConvexPenetrationDepthSolver* Solver = NULL; + + Solver = &Solver1; + + btGjkPairDetector convexConvex(&trishapeA ,&trishapeB,&sGjkSimplexSolver,Solver); + + convexConvex.m_catchDegeneracies = 1; + + // btGjkPairDetector convexConvex(&trishapeA ,&trishapeB,&sGjkSimplexSolver,0); + + btPointCollector gjkOutput; + btGjkPairDetector::ClosestPointInput input; + + + btTransform tr; + tr.setIdentity(); + + input.m_transformA = tr; + input.m_transformB = tr; + + convexConvex.getClosestPoints(input, gjkOutput, 0); + + + if (gjkOutput.m_hasResult) + { + + pb[0] = pa[0] = gjkOutput.m_pointInWorld[0]; + pb[1] = pa[1] = gjkOutput.m_pointInWorld[1]; + pb[2] = pa[2] = gjkOutput.m_pointInWorld[2]; + + pb[0]+= gjkOutput.m_normalOnBInWorld[0] * gjkOutput.m_distance; + pb[1]+= gjkOutput.m_normalOnBInWorld[1] * gjkOutput.m_distance; + pb[2]+= gjkOutput.m_normalOnBInWorld[2] * gjkOutput.m_distance; + + normal[0] = gjkOutput.m_normalOnBInWorld[0]; + normal[1] = gjkOutput.m_normalOnBInWorld[1]; + normal[2] = gjkOutput.m_normalOnBInWorld[2]; + + return gjkOutput.m_distance; + } + return -1.0f; +} + diff --git a/tests/bullet/src/BulletDynamics/Dynamics/btActionInterface.h b/tests/bullet/src/BulletDynamics/Dynamics/btActionInterface.h new file mode 100644 index 00000000..e1fea3a4 --- /dev/null +++ b/tests/bullet/src/BulletDynamics/Dynamics/btActionInterface.h @@ -0,0 +1,46 @@ +/* +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. +*/ + +#ifndef _BT_ACTION_INTERFACE_H +#define _BT_ACTION_INTERFACE_H + +class btIDebugDraw; +class btCollisionWorld; + +#include "LinearMath/btScalar.h" +#include "btRigidBody.h" + +///Basic interface to allow actions such as vehicles and characters to be updated inside a btDynamicsWorld +class btActionInterface +{ +protected: + + static btRigidBody& getFixedBody(); + + +public: + + virtual ~btActionInterface() + { + } + + virtual void updateAction( btCollisionWorld* collisionWorld, btScalar deltaTimeStep)=0; + + virtual void debugDraw(btIDebugDraw* debugDrawer) = 0; + +}; + +#endif //_BT_ACTION_INTERFACE_H + diff --git a/tests/bullet/src/BulletDynamics/Dynamics/btContinuousDynamicsWorld.cpp b/tests/bullet/src/BulletDynamics/Dynamics/btContinuousDynamicsWorld.cpp new file mode 100644 index 00000000..23501c44 --- /dev/null +++ b/tests/bullet/src/BulletDynamics/Dynamics/btContinuousDynamicsWorld.cpp @@ -0,0 +1,196 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2007 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 "btContinuousDynamicsWorld.h" +#include "LinearMath/btQuickprof.h" + +//collision detection +#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" +#include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h" +#include "BulletCollision/CollisionShapes/btCollisionShape.h" +#include "BulletCollision/CollisionDispatch/btSimulationIslandManager.h" + +//rigidbody & constraints +#include "BulletDynamics/Dynamics/btRigidBody.h" +#include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h" +#include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h" +#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h" + + + +#include <stdio.h> + +btContinuousDynamicsWorld::btContinuousDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration) +:btDiscreteDynamicsWorld(dispatcher,pairCache,constraintSolver,collisionConfiguration) +{ +} + +btContinuousDynamicsWorld::~btContinuousDynamicsWorld() +{ +} + + +void btContinuousDynamicsWorld::internalSingleStepSimulation( btScalar timeStep) +{ + + startProfiling(timeStep); + + if(0 != m_internalPreTickCallback) { + (*m_internalPreTickCallback)(this, timeStep); + } + + + ///update aabbs information + updateAabbs(); + //static int frame=0; +// printf("frame %d\n",frame++); + + ///apply gravity, predict motion + predictUnconstraintMotion(timeStep); + + btDispatcherInfo& dispatchInfo = getDispatchInfo(); + + dispatchInfo.m_timeStep = timeStep; + dispatchInfo.m_stepCount = 0; + dispatchInfo.m_debugDraw = getDebugDrawer(); + + ///perform collision detection + performDiscreteCollisionDetection(); + + calculateSimulationIslands(); + + + getSolverInfo().m_timeStep = timeStep; + + + + ///solve contact and other joint constraints + solveConstraints(getSolverInfo()); + + ///CallbackTriggers(); + calculateTimeOfImpacts(timeStep); + + btScalar toi = dispatchInfo.m_timeOfImpact; +// if (toi < 1.f) +// printf("toi = %f\n",toi); + if (toi < 0.f) + printf("toi = %f\n",toi); + + + ///integrate transforms + integrateTransforms(timeStep * toi); + + ///update vehicle simulation + updateActions(timeStep); + + updateActivationState( timeStep ); + + if(0 != m_internalTickCallback) { + (*m_internalTickCallback)(this, timeStep); + } +} + +void btContinuousDynamicsWorld::calculateTimeOfImpacts(btScalar timeStep) +{ + ///these should be 'temporal' aabbs! + updateTemporalAabbs(timeStep); + + ///'toi' is the global smallest time of impact. However, we just calculate the time of impact for each object individually. + ///so we handle the case moving versus static properly, and we cheat for moving versus moving + btScalar toi = 1.f; + + + btDispatcherInfo& dispatchInfo = getDispatchInfo(); + dispatchInfo.m_timeStep = timeStep; + dispatchInfo.m_timeOfImpact = 1.f; + dispatchInfo.m_stepCount = 0; + dispatchInfo.m_dispatchFunc = btDispatcherInfo::DISPATCH_CONTINUOUS; + + ///calculate time of impact for overlapping pairs + + + btDispatcher* dispatcher = getDispatcher(); + if (dispatcher) + dispatcher->dispatchAllCollisionPairs(m_broadphasePairCache->getOverlappingPairCache(),dispatchInfo,m_dispatcher1); + + toi = dispatchInfo.m_timeOfImpact; + + dispatchInfo.m_dispatchFunc = btDispatcherInfo::DISPATCH_DISCRETE; + +} + +void btContinuousDynamicsWorld::updateTemporalAabbs(btScalar timeStep) +{ + + btVector3 temporalAabbMin,temporalAabbMax; + + for ( int i=0;i<m_collisionObjects.size();i++) + { + btCollisionObject* colObj = m_collisionObjects[i]; + + btRigidBody* body = btRigidBody::upcast(colObj); + if (body) + { + body->getCollisionShape()->getAabb(m_collisionObjects[i]->getWorldTransform(),temporalAabbMin,temporalAabbMax); + const btVector3& linvel = body->getLinearVelocity(); + + //make the AABB temporal + btScalar temporalAabbMaxx = temporalAabbMax.getX(); + btScalar temporalAabbMaxy = temporalAabbMax.getY(); + btScalar temporalAabbMaxz = temporalAabbMax.getZ(); + btScalar temporalAabbMinx = temporalAabbMin.getX(); + btScalar temporalAabbMiny = temporalAabbMin.getY(); + btScalar temporalAabbMinz = temporalAabbMin.getZ(); + + // add linear motion + btVector3 linMotion = linvel*timeStep; + + if (linMotion.x() > 0.f) + temporalAabbMaxx += linMotion.x(); + else + temporalAabbMinx += linMotion.x(); + if (linMotion.y() > 0.f) + temporalAabbMaxy += linMotion.y(); + else + temporalAabbMiny += linMotion.y(); + if (linMotion.z() > 0.f) + temporalAabbMaxz += linMotion.z(); + else + temporalAabbMinz += linMotion.z(); + + //add conservative angular motion + btScalar angularMotion(0);// = angvel.length() * GetAngularMotionDisc() * timeStep; + btVector3 angularMotion3d(angularMotion,angularMotion,angularMotion); + temporalAabbMin = btVector3(temporalAabbMinx,temporalAabbMiny,temporalAabbMinz); + temporalAabbMax = btVector3(temporalAabbMaxx,temporalAabbMaxy,temporalAabbMaxz); + + temporalAabbMin -= angularMotion3d; + temporalAabbMax += angularMotion3d; + + m_broadphasePairCache->setAabb(body->getBroadphaseHandle(),temporalAabbMin,temporalAabbMax,m_dispatcher1); + } + } + + //update aabb (of all moved objects) + + m_broadphasePairCache->calculateOverlappingPairs(m_dispatcher1); + + + +} + + + diff --git a/tests/bullet/src/BulletDynamics/Dynamics/btContinuousDynamicsWorld.h b/tests/bullet/src/BulletDynamics/Dynamics/btContinuousDynamicsWorld.h new file mode 100644 index 00000000..61c8dea0 --- /dev/null +++ b/tests/bullet/src/BulletDynamics/Dynamics/btContinuousDynamicsWorld.h @@ -0,0 +1,46 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2007 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. +*/ + +#ifndef BT_CONTINUOUS_DYNAMICS_WORLD_H +#define BT_CONTINUOUS_DYNAMICS_WORLD_H + +#include "btDiscreteDynamicsWorld.h" + +///btContinuousDynamicsWorld adds optional (per object) continuous collision detection for fast moving objects to the btDiscreteDynamicsWorld. +///This copes with fast moving objects that otherwise would tunnel/miss collisions. +///Under construction, don't use yet! Please use btDiscreteDynamicsWorld instead. +class btContinuousDynamicsWorld : public btDiscreteDynamicsWorld +{ + + void updateTemporalAabbs(btScalar timeStep); + + public: + + btContinuousDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration); + virtual ~btContinuousDynamicsWorld(); + + ///time stepping with calculation of time of impact for selected fast moving objects + virtual void internalSingleStepSimulation( btScalar timeStep); + + virtual void calculateTimeOfImpacts(btScalar timeStep); + + virtual btDynamicsWorldType getWorldType() const + { + return BT_CONTINUOUS_DYNAMICS_WORLD; + } + +}; + +#endif //BT_CONTINUOUS_DYNAMICS_WORLD_H diff --git a/tests/bullet/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp b/tests/bullet/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp new file mode 100644 index 00000000..b08dcf0b --- /dev/null +++ b/tests/bullet/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp @@ -0,0 +1,1348 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +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 "btDiscreteDynamicsWorld.h" + +//collision detection +#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" +#include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h" +#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h" +#include "BulletCollision/CollisionShapes/btCollisionShape.h" +#include "BulletCollision/CollisionDispatch/btSimulationIslandManager.h" +#include "LinearMath/btTransformUtil.h" +#include "LinearMath/btQuickprof.h" + +//rigidbody & constraints +#include "BulletDynamics/Dynamics/btRigidBody.h" +#include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h" +#include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h" +#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h" +#include "BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h" +#include "BulletDynamics/ConstraintSolver/btHingeConstraint.h" +#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" + + +#include "BulletDynamics/Dynamics/btActionInterface.h" +#include "LinearMath/btQuickprof.h" +#include "LinearMath/btMotionState.h" + +#include "LinearMath/btSerializer.h" + +#if 0 +btAlignedObjectArray<btVector3> debugContacts; +btAlignedObjectArray<btVector3> debugNormals; +int startHit=2; +int firstHit=startHit; +#endif + + + +btDiscreteDynamicsWorld::btDiscreteDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver, btCollisionConfiguration* collisionConfiguration) +:btDynamicsWorld(dispatcher,pairCache,collisionConfiguration), +m_constraintSolver(constraintSolver), +m_gravity(0,-10,0), +m_localTime(0), +m_synchronizeAllMotionStates(false), +m_profileTimings(0) +{ + if (!m_constraintSolver) + { + void* mem = btAlignedAlloc(sizeof(btSequentialImpulseConstraintSolver),16); + m_constraintSolver = new (mem) btSequentialImpulseConstraintSolver; + m_ownsConstraintSolver = true; + } else + { + m_ownsConstraintSolver = false; + } + + { + void* mem = btAlignedAlloc(sizeof(btSimulationIslandManager),16); + m_islandManager = new (mem) btSimulationIslandManager(); + } + + m_ownsIslandManager = true; +} + + +btDiscreteDynamicsWorld::~btDiscreteDynamicsWorld() +{ + //only delete it when we created it + if (m_ownsIslandManager) + { + m_islandManager->~btSimulationIslandManager(); + btAlignedFree( m_islandManager); + } + if (m_ownsConstraintSolver) + { + + m_constraintSolver->~btConstraintSolver(); + btAlignedFree(m_constraintSolver); + } +} + +void btDiscreteDynamicsWorld::saveKinematicState(btScalar timeStep) +{ +///would like to iterate over m_nonStaticRigidBodies, but unfortunately old API allows +///to switch status _after_ adding kinematic objects to the world +///fix it for Bullet 3.x release + for (int i=0;i<m_collisionObjects.size();i++) + { + btCollisionObject* colObj = m_collisionObjects[i]; + btRigidBody* body = btRigidBody::upcast(colObj); + if (body && body->getActivationState() != ISLAND_SLEEPING) + { + if (body->isKinematicObject()) + { + //to calculate velocities next frame + body->saveKinematicState(timeStep); + } + } + } + +} + +void btDiscreteDynamicsWorld::debugDrawWorld() +{ + BT_PROFILE("debugDrawWorld"); + + btCollisionWorld::debugDrawWorld(); + + bool drawConstraints = false; + if (getDebugDrawer()) + { + int mode = getDebugDrawer()->getDebugMode(); + if(mode & (btIDebugDraw::DBG_DrawConstraints | btIDebugDraw::DBG_DrawConstraintLimits)) + { + drawConstraints = true; + } + } + if(drawConstraints) + { + for(int i = getNumConstraints()-1; i>=0 ;i--) + { + btTypedConstraint* constraint = getConstraint(i); + debugDrawConstraint(constraint); + } + } + + + + if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe | btIDebugDraw::DBG_DrawAabb)) + { + int i; + + if (getDebugDrawer() && getDebugDrawer()->getDebugMode()) + { + for (i=0;i<m_actions.size();i++) + { + m_actions[i]->debugDraw(m_debugDrawer); + } + } + } +} + +void btDiscreteDynamicsWorld::clearForces() +{ + ///@todo: iterate over awake simulation islands! + for ( int i=0;i<m_nonStaticRigidBodies.size();i++) + { + btRigidBody* body = m_nonStaticRigidBodies[i]; + //need to check if next line is ok + //it might break backward compatibility (people applying forces on sleeping objects get never cleared and accumulate on wake-up + body->clearForces(); + } +} + +///apply gravity, call this once per timestep +void btDiscreteDynamicsWorld::applyGravity() +{ + ///@todo: iterate over awake simulation islands! + for ( int i=0;i<m_nonStaticRigidBodies.size();i++) + { + btRigidBody* body = m_nonStaticRigidBodies[i]; + if (body->isActive()) + { + body->applyGravity(); + } + } +} + + +void btDiscreteDynamicsWorld::synchronizeSingleMotionState(btRigidBody* body) +{ + btAssert(body); + + if (body->getMotionState() && !body->isStaticOrKinematicObject()) + { + //we need to call the update at least once, even for sleeping objects + //otherwise the 'graphics' transform never updates properly |