Changeset View
Changeset View
Standalone View
Standalone View
extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp
| /* | /* | ||||
| Bullet Continuous Collision Detection and Physics Library | Bullet Continuous Collision Detection and Physics Library | ||||
| Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org | Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org | ||||
| This software is provided 'as-is', without any express or implied warranty. | 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. | 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, | Permission is granted to anyone to use this software for any purpose, | ||||
| including commercial applications, and to alter it and redistribute it freely, | including commercial applications, and to alter it and redistribute it freely, | ||||
| subject to the following restrictions: | 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. | 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. | 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. | 3. This notice may not be removed or altered from any source distribution. | ||||
| */ | */ | ||||
| Show All 12 Lines | |||||
| #include "BulletDynamics/Dynamics/btRigidBody.h" | #include "BulletDynamics/Dynamics/btRigidBody.h" | ||||
| #include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h" | #include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h" | ||||
| #include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h" | #include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h" | ||||
| #include "BulletDynamics/ConstraintSolver/btTypedConstraint.h" | #include "BulletDynamics/ConstraintSolver/btTypedConstraint.h" | ||||
| #include "BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h" | #include "BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h" | ||||
| #include "BulletDynamics/ConstraintSolver/btHingeConstraint.h" | #include "BulletDynamics/ConstraintSolver/btHingeConstraint.h" | ||||
| #include "BulletDynamics/ConstraintSolver/btConeTwistConstraint.h" | #include "BulletDynamics/ConstraintSolver/btConeTwistConstraint.h" | ||||
| #include "BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h" | #include "BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h" | ||||
| #include "BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.h" | |||||
| #include "BulletDynamics/ConstraintSolver/btSliderConstraint.h" | #include "BulletDynamics/ConstraintSolver/btSliderConstraint.h" | ||||
| #include "BulletDynamics/ConstraintSolver/btContactConstraint.h" | #include "BulletDynamics/ConstraintSolver/btContactConstraint.h" | ||||
| #include "LinearMath/btIDebugDraw.h" | #include "LinearMath/btIDebugDraw.h" | ||||
| #include "BulletCollision/CollisionShapes/btSphereShape.h" | #include "BulletCollision/CollisionShapes/btSphereShape.h" | ||||
| #include "BulletDynamics/Dynamics/btActionInterface.h" | #include "BulletDynamics/Dynamics/btActionInterface.h" | ||||
| #include "LinearMath/btQuickprof.h" | #include "LinearMath/btQuickprof.h" | ||||
| #include "LinearMath/btMotionState.h" | #include "LinearMath/btMotionState.h" | ||||
| #include "LinearMath/btSerializer.h" | #include "LinearMath/btSerializer.h" | ||||
| #if 0 | #if 0 | ||||
| btAlignedObjectArray<btVector3> debugContacts; | btAlignedObjectArray<btVector3> debugContacts; | ||||
| btAlignedObjectArray<btVector3> debugNormals; | btAlignedObjectArray<btVector3> debugNormals; | ||||
| int startHit=2; | int startHit=2; | ||||
| int firstHit=startHit; | int firstHit=startHit; | ||||
| #endif | #endif | ||||
| SIMD_FORCE_INLINE int btGetConstraintIslandId(const btTypedConstraint* lhs) | SIMD_FORCE_INLINE int btGetConstraintIslandId(const btTypedConstraint* lhs) | ||||
| { | { | ||||
| int islandId; | int islandId; | ||||
| const btCollisionObject& rcolObj0 = lhs->getRigidBodyA(); | const btCollisionObject& rcolObj0 = lhs->getRigidBodyA(); | ||||
| const btCollisionObject& rcolObj1 = lhs->getRigidBodyB(); | const btCollisionObject& rcolObj1 = lhs->getRigidBodyB(); | ||||
| islandId= rcolObj0.getIslandTag()>=0?rcolObj0.getIslandTag():rcolObj1.getIslandTag(); | islandId= rcolObj0.getIslandTag()>=0?rcolObj0.getIslandTag():rcolObj1.getIslandTag(); | ||||
| return islandId; | return islandId; | ||||
| } | } | ||||
| Show All 13 Lines | |||||
| struct InplaceSolverIslandCallback : public btSimulationIslandManager::IslandCallback | struct InplaceSolverIslandCallback : public btSimulationIslandManager::IslandCallback | ||||
| { | { | ||||
| btContactSolverInfo* m_solverInfo; | btContactSolverInfo* m_solverInfo; | ||||
| btConstraintSolver* m_solver; | btConstraintSolver* m_solver; | ||||
| btTypedConstraint** m_sortedConstraints; | btTypedConstraint** m_sortedConstraints; | ||||
| int m_numConstraints; | int m_numConstraints; | ||||
| btIDebugDraw* m_debugDrawer; | btIDebugDraw* m_debugDrawer; | ||||
| btDispatcher* m_dispatcher; | btDispatcher* m_dispatcher; | ||||
| btAlignedObjectArray<btCollisionObject*> m_bodies; | btAlignedObjectArray<btCollisionObject*> m_bodies; | ||||
| btAlignedObjectArray<btPersistentManifold*> m_manifolds; | btAlignedObjectArray<btPersistentManifold*> m_manifolds; | ||||
| btAlignedObjectArray<btTypedConstraint*> m_constraints; | btAlignedObjectArray<btTypedConstraint*> m_constraints; | ||||
| InplaceSolverIslandCallback( | InplaceSolverIslandCallback( | ||||
| btConstraintSolver* solver, | btConstraintSolver* solver, | ||||
| btStackAlloc* stackAlloc, | btStackAlloc* stackAlloc, | ||||
| Show All 22 Lines | SIMD_FORCE_INLINE void setup ( btContactSolverInfo* solverInfo, btTypedConstraint** sortedConstraints, int numConstraints, btIDebugDraw* debugDrawer) | ||||
| m_sortedConstraints = sortedConstraints; | m_sortedConstraints = sortedConstraints; | ||||
| m_numConstraints = numConstraints; | m_numConstraints = numConstraints; | ||||
| m_debugDrawer = debugDrawer; | m_debugDrawer = debugDrawer; | ||||
| m_bodies.resize (0); | m_bodies.resize (0); | ||||
| m_manifolds.resize (0); | m_manifolds.resize (0); | ||||
| m_constraints.resize (0); | m_constraints.resize (0); | ||||
| } | } | ||||
| virtual void processIsland(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifolds,int numManifolds, int islandId) | virtual void processIsland(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifolds,int numManifolds, int islandId) | ||||
| { | { | ||||
| if (islandId<0) | if (islandId<0) | ||||
| { | { | ||||
| ///we don't split islands, so all constraints/contact manifolds/bodies are passed into the solver regardless the island id | ///we don't split islands, so all constraints/contact manifolds/bodies are passed into the solver regardless the island id | ||||
| m_solver->solveGroup( bodies,numBodies,manifolds, numManifolds,&m_sortedConstraints[0],m_numConstraints,*m_solverInfo,m_debugDrawer,m_dispatcher); | m_solver->solveGroup( bodies,numBodies,manifolds, numManifolds,&m_sortedConstraints[0],m_numConstraints,*m_solverInfo,m_debugDrawer,m_dispatcher); | ||||
| } else | } else | ||||
| { | { | ||||
| //also add all non-contact constraints/joints for this island | //also add all non-contact constraints/joints for this island | ||||
| btTypedConstraint** startConstraint = 0; | btTypedConstraint** startConstraint = 0; | ||||
| int numCurConstraints = 0; | int numCurConstraints = 0; | ||||
| int i; | int i; | ||||
| //find the first constraint for this island | //find the first constraint for this island | ||||
| for (i=0;i<m_numConstraints;i++) | for (i=0;i<m_numConstraints;i++) | ||||
| { | { | ||||
| if (btGetConstraintIslandId(m_sortedConstraints[i]) == islandId) | if (btGetConstraintIslandId(m_sortedConstraints[i]) == islandId) | ||||
| { | { | ||||
| startConstraint = &m_sortedConstraints[i]; | startConstraint = &m_sortedConstraints[i]; | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| //count the number of constraints in this island | //count the number of constraints in this island | ||||
| for (;i<m_numConstraints;i++) | for (;i<m_numConstraints;i++) | ||||
| { | { | ||||
| if (btGetConstraintIslandId(m_sortedConstraints[i]) == islandId) | if (btGetConstraintIslandId(m_sortedConstraints[i]) == islandId) | ||||
| { | { | ||||
| numCurConstraints++; | numCurConstraints++; | ||||
| } | } | ||||
| } | } | ||||
| if (m_solverInfo->m_minimumSolverBatchSize<=1) | if (m_solverInfo->m_minimumSolverBatchSize<=1) | ||||
| { | { | ||||
| m_solver->solveGroup( bodies,numBodies,manifolds, numManifolds,startConstraint,numCurConstraints,*m_solverInfo,m_debugDrawer,m_dispatcher); | m_solver->solveGroup( bodies,numBodies,manifolds, numManifolds,startConstraint,numCurConstraints,*m_solverInfo,m_debugDrawer,m_dispatcher); | ||||
| } else | } else | ||||
| { | { | ||||
| for (i=0;i<numBodies;i++) | for (i=0;i<numBodies;i++) | ||||
| m_bodies.push_back(bodies[i]); | m_bodies.push_back(bodies[i]); | ||||
| for (i=0;i<numManifolds;i++) | for (i=0;i<numManifolds;i++) | ||||
| m_manifolds.push_back(manifolds[i]); | m_manifolds.push_back(manifolds[i]); | ||||
| for (i=0;i<numCurConstraints;i++) | for (i=0;i<numCurConstraints;i++) | ||||
| m_constraints.push_back(startConstraint[i]); | m_constraints.push_back(startConstraint[i]); | ||||
| if ((m_constraints.size()+m_manifolds.size())>m_solverInfo->m_minimumSolverBatchSize) | if ((m_constraints.size()+m_manifolds.size())>m_solverInfo->m_minimumSolverBatchSize) | ||||
| { | { | ||||
| processConstraints(); | processConstraints(); | ||||
| } else | } else | ||||
| { | { | ||||
| //printf("deferred\n"); | //printf("deferred\n"); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| void processConstraints() | void processConstraints() | ||||
| { | { | ||||
| btCollisionObject** bodies = m_bodies.size()? &m_bodies[0]:0; | btCollisionObject** bodies = m_bodies.size()? &m_bodies[0]:0; | ||||
| btPersistentManifold** manifold = m_manifolds.size()?&m_manifolds[0]:0; | btPersistentManifold** manifold = m_manifolds.size()?&m_manifolds[0]:0; | ||||
| btTypedConstraint** constraints = m_constraints.size()?&m_constraints[0]:0; | btTypedConstraint** constraints = m_constraints.size()?&m_constraints[0]:0; | ||||
| m_solver->solveGroup( bodies,m_bodies.size(),manifold, m_manifolds.size(),constraints, m_constraints.size() ,*m_solverInfo,m_debugDrawer,m_dispatcher); | m_solver->solveGroup( bodies,m_bodies.size(),manifold, m_manifolds.size(),constraints, m_constraints.size() ,*m_solverInfo,m_debugDrawer,m_dispatcher); | ||||
| m_bodies.resize(0); | m_bodies.resize(0); | ||||
| m_manifolds.resize(0); | m_manifolds.resize(0); | ||||
| m_constraints.resize(0); | m_constraints.resize(0); | ||||
| } | } | ||||
| }; | }; | ||||
| btDiscreteDynamicsWorld::btDiscreteDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver, btCollisionConfiguration* collisionConfiguration) | btDiscreteDynamicsWorld::btDiscreteDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver, btCollisionConfiguration* collisionConfiguration) | ||||
| :btDynamicsWorld(dispatcher,pairCache,collisionConfiguration), | :btDynamicsWorld(dispatcher,pairCache,collisionConfiguration), | ||||
| m_sortedConstraints (), | m_sortedConstraints (), | ||||
| m_solverIslandCallback ( NULL ), | m_solverIslandCallback ( NULL ), | ||||
| m_constraintSolver(constraintSolver), | m_constraintSolver(constraintSolver), | ||||
| m_gravity(0,-10,0), | m_gravity(0,-10,0), | ||||
| m_localTime(0), | m_localTime(0), | ||||
| m_fixedTimeStep(0), | |||||
| m_synchronizeAllMotionStates(false), | m_synchronizeAllMotionStates(false), | ||||
| m_applySpeculativeContactRestitution(false), | m_applySpeculativeContactRestitution(false), | ||||
| m_profileTimings(0), | m_profileTimings(0), | ||||
| m_fixedTimeStep(0), | |||||
| m_latencyMotionStateInterpolation(true) | m_latencyMotionStateInterpolation(true) | ||||
| { | { | ||||
| if (!m_constraintSolver) | if (!m_constraintSolver) | ||||
| { | { | ||||
| void* mem = btAlignedAlloc(sizeof(btSequentialImpulseConstraintSolver),16); | void* mem = btAlignedAlloc(sizeof(btSequentialImpulseConstraintSolver),16); | ||||
| m_constraintSolver = new (mem) btSequentialImpulseConstraintSolver; | m_constraintSolver = new (mem) btSequentialImpulseConstraintSolver; | ||||
| m_ownsConstraintSolver = true; | m_ownsConstraintSolver = true; | ||||
| ▲ Show 20 Lines • Show All 91 Lines • ▼ Show 20 Lines | if(drawConstraints) | ||||
| if (getDebugDrawer() && getDebugDrawer()->getDebugMode()) | if (getDebugDrawer() && getDebugDrawer()->getDebugMode()) | ||||
| { | { | ||||
| for (i=0;i<m_actions.size();i++) | for (i=0;i<m_actions.size();i++) | ||||
| { | { | ||||
| m_actions[i]->debugDraw(m_debugDrawer); | m_actions[i]->debugDraw(m_debugDrawer); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (getDebugDrawer()) | |||||
| getDebugDrawer()->flushLines(); | |||||
| } | } | ||||
| void btDiscreteDynamicsWorld::clearForces() | void btDiscreteDynamicsWorld::clearForces() | ||||
| { | { | ||||
| ///@todo: iterate over awake simulation islands! | ///@todo: iterate over awake simulation islands! | ||||
| for ( int i=0;i<m_nonStaticRigidBodies.size();i++) | for ( int i=0;i<m_nonStaticRigidBodies.size();i++) | ||||
| { | { | ||||
| btRigidBody* body = m_nonStaticRigidBodies[i]; | btRigidBody* body = m_nonStaticRigidBodies[i]; | ||||
| //need to check if next line is ok | //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 | //it might break backward compatibility (people applying forces on sleeping objects get never cleared and accumulate on wake-up | ||||
| body->clearForces(); | body->clearForces(); | ||||
| } | } | ||||
| } | } | ||||
| ///apply gravity, call this once per timestep | ///apply gravity, call this once per timestep | ||||
| void btDiscreteDynamicsWorld::applyGravity() | void btDiscreteDynamicsWorld::applyGravity() | ||||
| { | { | ||||
| ///@todo: iterate over awake simulation islands! | ///@todo: iterate over awake simulation islands! | ||||
| for ( int i=0;i<m_nonStaticRigidBodies.size();i++) | for ( int i=0;i<m_nonStaticRigidBodies.size();i++) | ||||
| { | { | ||||
| btRigidBody* body = m_nonStaticRigidBodies[i]; | btRigidBody* body = m_nonStaticRigidBodies[i]; | ||||
| ▲ Show 20 Lines • Show All 99 Lines • ▼ Show 20 Lines | if (numSimulationSubSteps) | ||||
| //clamp the number of substeps, to prevent simulation grinding spiralling down to a halt | //clamp the number of substeps, to prevent simulation grinding spiralling down to a halt | ||||
| int clampedSimulationSteps = (numSimulationSubSteps > maxSubSteps)? maxSubSteps : numSimulationSubSteps; | int clampedSimulationSteps = (numSimulationSubSteps > maxSubSteps)? maxSubSteps : numSimulationSubSteps; | ||||
| saveKinematicState(fixedTimeStep*clampedSimulationSteps); | saveKinematicState(fixedTimeStep*clampedSimulationSteps); | ||||
| applyGravity(); | applyGravity(); | ||||
| for (int i=0;i<clampedSimulationSteps;i++) | for (int i=0;i<clampedSimulationSteps;i++) | ||||
| { | { | ||||
| internalSingleStepSimulation(fixedTimeStep); | internalSingleStepSimulation(fixedTimeStep); | ||||
| synchronizeMotionStates(); | synchronizeMotionStates(); | ||||
| } | } | ||||
| } else | } else | ||||
| { | { | ||||
| synchronizeMotionStates(); | synchronizeMotionStates(); | ||||
| } | } | ||||
| clearForces(); | clearForces(); | ||||
| #ifndef BT_NO_PROFILE | #ifndef BT_NO_PROFILE | ||||
| CProfileManager::Increment_Frame_Counter(); | CProfileManager::Increment_Frame_Counter(); | ||||
| #endif //BT_NO_PROFILE | #endif //BT_NO_PROFILE | ||||
| return numSimulationSubSteps; | return numSimulationSubSteps; | ||||
| } | } | ||||
| void btDiscreteDynamicsWorld::internalSingleStepSimulation(btScalar timeStep) | void btDiscreteDynamicsWorld::internalSingleStepSimulation(btScalar timeStep) | ||||
| { | { | ||||
| BT_PROFILE("internalSingleStepSimulation"); | BT_PROFILE("internalSingleStepSimulation"); | ||||
| if(0 != m_internalPreTickCallback) { | if(0 != m_internalPreTickCallback) { | ||||
| (*m_internalPreTickCallback)(this, timeStep); | (*m_internalPreTickCallback)(this, timeStep); | ||||
| } | } | ||||
| ///apply gravity, predict motion | ///apply gravity, predict motion | ||||
| predictUnconstraintMotion(timeStep); | predictUnconstraintMotion(timeStep); | ||||
| btDispatcherInfo& dispatchInfo = getDispatchInfo(); | btDispatcherInfo& dispatchInfo = getDispatchInfo(); | ||||
| dispatchInfo.m_timeStep = timeStep; | dispatchInfo.m_timeStep = timeStep; | ||||
| dispatchInfo.m_stepCount = 0; | dispatchInfo.m_stepCount = 0; | ||||
| dispatchInfo.m_debugDraw = getDebugDrawer(); | dispatchInfo.m_debugDraw = getDebugDrawer(); | ||||
| createPredictiveContacts(timeStep); | createPredictiveContacts(timeStep); | ||||
| ///perform collision detection | ///perform collision detection | ||||
| performDiscreteCollisionDetection(); | performDiscreteCollisionDetection(); | ||||
| calculateSimulationIslands(); | calculateSimulationIslands(); | ||||
| getSolverInfo().m_timeStep = timeStep; | getSolverInfo().m_timeStep = timeStep; | ||||
| ///solve contact and other joint constraints | ///solve contact and other joint constraints | ||||
| solveConstraints(getSolverInfo()); | solveConstraints(getSolverInfo()); | ||||
| ///CallbackTriggers(); | ///CallbackTriggers(); | ||||
| ///integrate transforms | ///integrate transforms | ||||
| integrateTransforms(timeStep); | integrateTransforms(timeStep); | ||||
| ///update vehicle simulation | ///update vehicle simulation | ||||
| updateActions(timeStep); | updateActions(timeStep); | ||||
| updateActivationState( timeStep ); | updateActivationState( timeStep ); | ||||
| if(0 != m_internalTickCallback) { | if(0 != m_internalTickCallback) { | ||||
| (*m_internalTickCallback)(this, timeStep); | (*m_internalTickCallback)(this, timeStep); | ||||
| } | } | ||||
| } | } | ||||
| void btDiscreteDynamicsWorld::setGravity(const btVector3& gravity) | void btDiscreteDynamicsWorld::setGravity(const btVector3& gravity) | ||||
| { | { | ||||
| m_gravity = gravity; | m_gravity = gravity; | ||||
| for ( int i=0;i<m_nonStaticRigidBodies.size();i++) | for ( int i=0;i<m_nonStaticRigidBodies.size();i++) | ||||
| { | { | ||||
| btRigidBody* body = m_nonStaticRigidBodies[i]; | btRigidBody* body = m_nonStaticRigidBodies[i]; | ||||
| ▲ Show 20 Lines • Show All 75 Lines • ▼ Show 20 Lines | if (body->getCollisionShape()) | ||||
| addCollisionObject(body,group,mask); | addCollisionObject(body,group,mask); | ||||
| } | } | ||||
| } | } | ||||
| void btDiscreteDynamicsWorld::updateActions(btScalar timeStep) | void btDiscreteDynamicsWorld::updateActions(btScalar timeStep) | ||||
| { | { | ||||
| BT_PROFILE("updateActions"); | BT_PROFILE("updateActions"); | ||||
| for ( int i=0;i<m_actions.size();i++) | for ( int i=0;i<m_actions.size();i++) | ||||
| { | { | ||||
| m_actions[i]->updateAction( this, timeStep); | m_actions[i]->updateAction( this, timeStep); | ||||
| } | } | ||||
| } | } | ||||
| void btDiscreteDynamicsWorld::updateActivationState(btScalar timeStep) | void btDiscreteDynamicsWorld::updateActivationState(btScalar timeStep) | ||||
| { | { | ||||
| BT_PROFILE("updateActivationState"); | BT_PROFILE("updateActivationState"); | ||||
| for ( int i=0;i<m_nonStaticRigidBodies.size();i++) | for ( int i=0;i<m_nonStaticRigidBodies.size();i++) | ||||
| { | { | ||||
| btRigidBody* body = m_nonStaticRigidBodies[i]; | btRigidBody* body = m_nonStaticRigidBodies[i]; | ||||
| if (body) | if (body) | ||||
| { | { | ||||
| body->updateDeactivation(timeStep); | body->updateDeactivation(timeStep); | ||||
| if (body->wantsSleeping()) | if (body->wantsSleeping()) | ||||
| { | { | ||||
| if (body->isStaticOrKinematicObject()) | if (body->isStaticOrKinematicObject()) | ||||
| { | { | ||||
| body->setActivationState(ISLAND_SLEEPING); | body->setActivationState(ISLAND_SLEEPING); | ||||
| } else | } else | ||||
| { | { | ||||
| if (body->getActivationState() == ACTIVE_TAG) | if (body->getActivationState() == ACTIVE_TAG) | ||||
| body->setActivationState( WANTS_DEACTIVATION ); | body->setActivationState( WANTS_DEACTIVATION ); | ||||
| if (body->getActivationState() == ISLAND_SLEEPING) | if (body->getActivationState() == ISLAND_SLEEPING) | ||||
| { | { | ||||
| body->setAngularVelocity(btVector3(0,0,0)); | body->setAngularVelocity(btVector3(0,0,0)); | ||||
| body->setLinearVelocity(btVector3(0,0,0)); | body->setLinearVelocity(btVector3(0,0,0)); | ||||
| } | } | ||||
| } | } | ||||
| } else | } else | ||||
| { | { | ||||
| if (body->getActivationState() != DISABLE_DEACTIVATION) | if (body->getActivationState() != DISABLE_DEACTIVATION) | ||||
| body->setActivationState( ACTIVE_TAG ); | body->setActivationState( ACTIVE_TAG ); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| void btDiscreteDynamicsWorld::addConstraint(btTypedConstraint* constraint,bool disableCollisionsBetweenLinkedBodies) | void btDiscreteDynamicsWorld::addConstraint(btTypedConstraint* constraint,bool disableCollisionsBetweenLinkedBodies) | ||||
| { | { | ||||
| m_constraints.push_back(constraint); | m_constraints.push_back(constraint); | ||||
| //Make sure the two bodies of a type constraint are different (possibly add this to the btTypedConstraint constructor?) | |||||
| btAssert(&constraint->getRigidBodyA()!=&constraint->getRigidBodyB()); | |||||
| if (disableCollisionsBetweenLinkedBodies) | if (disableCollisionsBetweenLinkedBodies) | ||||
| { | { | ||||
| constraint->getRigidBodyA().addConstraintRef(constraint); | constraint->getRigidBodyA().addConstraintRef(constraint); | ||||
| constraint->getRigidBodyB().addConstraintRef(constraint); | constraint->getRigidBodyB().addConstraintRef(constraint); | ||||
| } | } | ||||
| } | } | ||||
| void btDiscreteDynamicsWorld::removeConstraint(btTypedConstraint* constraint) | void btDiscreteDynamicsWorld::removeConstraint(btTypedConstraint* constraint) | ||||
| Show All 35 Lines | |||||
| } | } | ||||
| void btDiscreteDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo) | void btDiscreteDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo) | ||||
| { | { | ||||
| BT_PROFILE("solveConstraints"); | BT_PROFILE("solveConstraints"); | ||||
| m_sortedConstraints.resize( m_constraints.size()); | m_sortedConstraints.resize( m_constraints.size()); | ||||
| int i; | int i; | ||||
| for (i=0;i<getNumConstraints();i++) | for (i=0;i<getNumConstraints();i++) | ||||
| { | { | ||||
| m_sortedConstraints[i] = m_constraints[i]; | m_sortedConstraints[i] = m_constraints[i]; | ||||
| } | } | ||||
| // btAssert(0); | // btAssert(0); | ||||
| m_sortedConstraints.quickSort(btSortConstraintOnIslandPredicate()); | m_sortedConstraints.quickSort(btSortConstraintOnIslandPredicate()); | ||||
| btTypedConstraint** constraintsPtr = getNumConstraints() ? &m_sortedConstraints[0] : 0; | btTypedConstraint** constraintsPtr = getNumConstraints() ? &m_sortedConstraints[0] : 0; | ||||
| m_solverIslandCallback->setup(&solverInfo,constraintsPtr,m_sortedConstraints.size(),getDebugDrawer()); | m_solverIslandCallback->setup(&solverInfo,constraintsPtr,m_sortedConstraints.size(),getDebugDrawer()); | ||||
| m_constraintSolver->prepareSolve(getCollisionWorld()->getNumCollisionObjects(), getCollisionWorld()->getDispatcher()->getNumManifolds()); | m_constraintSolver->prepareSolve(getCollisionWorld()->getNumCollisionObjects(), getCollisionWorld()->getDispatcher()->getNumManifolds()); | ||||
| /// solve all the constraints for this island | /// solve all the constraints for this island | ||||
| m_islandManager->buildAndProcessIslands(getCollisionWorld()->getDispatcher(),getCollisionWorld(),m_solverIslandCallback); | m_islandManager->buildAndProcessIslands(getCollisionWorld()->getDispatcher(),getCollisionWorld(),m_solverIslandCallback); | ||||
| m_solverIslandCallback->processConstraints(); | m_solverIslandCallback->processConstraints(); | ||||
| m_constraintSolver->allSolved(solverInfo, m_debugDrawer); | m_constraintSolver->allSolved(solverInfo, m_debugDrawer); | ||||
| } | } | ||||
| void btDiscreteDynamicsWorld::calculateSimulationIslands() | void btDiscreteDynamicsWorld::calculateSimulationIslands() | ||||
| { | { | ||||
| BT_PROFILE("calculateSimulationIslands"); | BT_PROFILE("calculateSimulationIslands"); | ||||
| getSimulationIslandManager()->updateActivationState(getCollisionWorld(),getCollisionWorld()->getDispatcher()); | getSimulationIslandManager()->updateActivationState(getCollisionWorld(),getCollisionWorld()->getDispatcher()); | ||||
| { | { | ||||
| //merge islands based on speculative contact manifolds too | //merge islands based on speculative contact manifolds too | ||||
| for (int i=0;i<this->m_predictiveManifolds.size();i++) | for (int i=0;i<this->m_predictiveManifolds.size();i++) | ||||
| { | { | ||||
| btPersistentManifold* manifold = m_predictiveManifolds[i]; | btPersistentManifold* manifold = m_predictiveManifolds[i]; | ||||
| const btCollisionObject* colObj0 = manifold->getBody0(); | const btCollisionObject* colObj0 = manifold->getBody0(); | ||||
| const btCollisionObject* colObj1 = manifold->getBody1(); | const btCollisionObject* colObj1 = manifold->getBody1(); | ||||
| if (((colObj0) && (!(colObj0)->isStaticOrKinematicObject())) && | if (((colObj0) && (!(colObj0)->isStaticOrKinematicObject())) && | ||||
| ((colObj1) && (!(colObj1)->isStaticOrKinematicObject()))) | ((colObj1) && (!(colObj1)->isStaticOrKinematicObject()))) | ||||
| { | { | ||||
| getSimulationIslandManager()->getUnionFind().unite((colObj0)->getIslandTag(),(colObj1)->getIslandTag()); | getSimulationIslandManager()->getUnionFind().unite((colObj0)->getIslandTag(),(colObj1)->getIslandTag()); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| { | { | ||||
| int i; | int i; | ||||
| int numConstraints = int(m_constraints.size()); | int numConstraints = int(m_constraints.size()); | ||||
| for (i=0;i< numConstraints ; i++ ) | for (i=0;i< numConstraints ; i++ ) | ||||
| { | { | ||||
| btTypedConstraint* constraint = m_constraints[i]; | btTypedConstraint* constraint = m_constraints[i]; | ||||
| if (constraint->isEnabled()) | if (constraint->isEnabled()) | ||||
| { | { | ||||
| const btRigidBody* colObj0 = &constraint->getRigidBodyA(); | const btRigidBody* colObj0 = &constraint->getRigidBodyA(); | ||||
| const btRigidBody* colObj1 = &constraint->getRigidBodyB(); | const btRigidBody* colObj1 = &constraint->getRigidBodyB(); | ||||
| if (((colObj0) && (!(colObj0)->isStaticOrKinematicObject())) && | if (((colObj0) && (!(colObj0)->isStaticOrKinematicObject())) && | ||||
| ((colObj1) && (!(colObj1)->isStaticOrKinematicObject()))) | ((colObj1) && (!(colObj1)->isStaticOrKinematicObject()))) | ||||
| { | { | ||||
| getSimulationIslandManager()->getUnionFind().unite((colObj0)->getIslandTag(),(colObj1)->getIslandTag()); | getSimulationIslandManager()->getUnionFind().unite((colObj0)->getIslandTag(),(colObj1)->getIslandTag()); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| //Store the island id in each body | //Store the island id in each body | ||||
| getSimulationIslandManager()->storeIslandActivationState(getCollisionWorld()); | getSimulationIslandManager()->storeIslandActivationState(getCollisionWorld()); | ||||
| } | } | ||||
| class btClosestNotMeConvexResultCallback : public btCollisionWorld::ClosestConvexResultCallback | class btClosestNotMeConvexResultCallback : public btCollisionWorld::ClosestConvexResultCallback | ||||
| { | { | ||||
| public: | public: | ||||
| btCollisionObject* m_me; | btCollisionObject* m_me; | ||||
| btScalar m_allowedPenetration; | btScalar m_allowedPenetration; | ||||
| btOverlappingPairCache* m_pairCache; | btOverlappingPairCache* m_pairCache; | ||||
| btDispatcher* m_dispatcher; | btDispatcher* m_dispatcher; | ||||
| public: | public: | ||||
| btClosestNotMeConvexResultCallback (btCollisionObject* me,const btVector3& fromA,const btVector3& toA,btOverlappingPairCache* pairCache,btDispatcher* dispatcher) : | btClosestNotMeConvexResultCallback (btCollisionObject* me,const btVector3& fromA,const btVector3& toA,btOverlappingPairCache* pairCache,btDispatcher* dispatcher) : | ||||
| btCollisionWorld::ClosestConvexResultCallback(fromA,toA), | btCollisionWorld::ClosestConvexResultCallback(fromA,toA), | ||||
| m_me(me), | m_me(me), | ||||
| m_allowedPenetration(0.0f), | m_allowedPenetration(0.0f), | ||||
| m_pairCache(pairCache), | m_pairCache(pairCache), | ||||
| m_dispatcher(dispatcher) | m_dispatcher(dispatcher) | ||||
| { | { | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 63 Lines • ▼ Show 20 Lines | |||||
| ///internal debugging variable. this value shouldn't be too high | ///internal debugging variable. this value shouldn't be too high | ||||
| int gNumClampedCcdMotions=0; | int gNumClampedCcdMotions=0; | ||||
| void btDiscreteDynamicsWorld::createPredictiveContacts(btScalar timeStep) | void btDiscreteDynamicsWorld::createPredictiveContacts(btScalar timeStep) | ||||
| { | { | ||||
| BT_PROFILE("createPredictiveContacts"); | BT_PROFILE("createPredictiveContacts"); | ||||
| { | { | ||||
| BT_PROFILE("release predictive contact manifolds"); | BT_PROFILE("release predictive contact manifolds"); | ||||
| for (int i=0;i<m_predictiveManifolds.size();i++) | for (int i=0;i<m_predictiveManifolds.size();i++) | ||||
| { | { | ||||
| btPersistentManifold* manifold = m_predictiveManifolds[i]; | btPersistentManifold* manifold = m_predictiveManifolds[i]; | ||||
| this->m_dispatcher1->releaseManifold(manifold); | this->m_dispatcher1->releaseManifold(manifold); | ||||
| } | } | ||||
| m_predictiveManifolds.clear(); | m_predictiveManifolds.clear(); | ||||
| } | } | ||||
| btTransform predictedTrans; | btTransform predictedTrans; | ||||
| for ( int i=0;i<m_nonStaticRigidBodies.size();i++) | for ( int i=0;i<m_nonStaticRigidBodies.size();i++) | ||||
| { | { | ||||
| btRigidBody* body = m_nonStaticRigidBodies[i]; | btRigidBody* body = m_nonStaticRigidBodies[i]; | ||||
| body->setHitFraction(1.f); | body->setHitFraction(1.f); | ||||
| if (body->isActive() && (!body->isStaticOrKinematicObject())) | if (body->isActive() && (!body->isStaticOrKinematicObject())) | ||||
| { | { | ||||
| body->predictIntegratedTransform(timeStep, predictedTrans); | body->predictIntegratedTransform(timeStep, predictedTrans); | ||||
| btScalar squareMotion = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2(); | btScalar squareMotion = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2(); | ||||
| if (getDispatchInfo().m_useContinuous && body->getCcdSquareMotionThreshold() && body->getCcdSquareMotionThreshold() < squareMotion) | if (getDispatchInfo().m_useContinuous && body->getCcdSquareMotionThreshold() && body->getCcdSquareMotionThreshold() < squareMotion) | ||||
| { | { | ||||
| BT_PROFILE("predictive convexSweepTest"); | BT_PROFILE("predictive convexSweepTest"); | ||||
| if (body->getCollisionShape()->isConvex()) | if (body->getCollisionShape()->isConvex()) | ||||
| { | { | ||||
| gNumClampedCcdMotions++; | gNumClampedCcdMotions++; | ||||
| #ifdef PREDICTIVE_CONTACT_USE_STATIC_ONLY | #ifdef PREDICTIVE_CONTACT_USE_STATIC_ONLY | ||||
| class StaticOnlyCallback : public btClosestNotMeConvexResultCallback | class StaticOnlyCallback : public btClosestNotMeConvexResultCallback | ||||
| { | { | ||||
| public: | public: | ||||
| StaticOnlyCallback (btCollisionObject* me,const btVector3& fromA,const btVector3& toA,btOverlappingPairCache* pairCache,btDispatcher* dispatcher) : | StaticOnlyCallback (btCollisionObject* me,const btVector3& fromA,const btVector3& toA,btOverlappingPairCache* pairCache,btDispatcher* dispatcher) : | ||||
| btClosestNotMeConvexResultCallback(me,fromA,toA,pairCache,dispatcher) | btClosestNotMeConvexResultCallback(me,fromA,toA,pairCache,dispatcher) | ||||
| { | { | ||||
| } | } | ||||
| virtual bool needsCollision(btBroadphaseProxy* proxy0) const | virtual bool needsCollision(btBroadphaseProxy* proxy0) const | ||||
| { | { | ||||
| btCollisionObject* otherObj = (btCollisionObject*) proxy0->m_clientObject; | btCollisionObject* otherObj = (btCollisionObject*) proxy0->m_clientObject; | ||||
| if (!otherObj->isStaticOrKinematicObject()) | if (!otherObj->isStaticOrKinematicObject()) | ||||
| Show All 13 Lines | #endif | ||||
| sweepResults.m_collisionFilterGroup = body->getBroadphaseProxy()->m_collisionFilterGroup; | sweepResults.m_collisionFilterGroup = body->getBroadphaseProxy()->m_collisionFilterGroup; | ||||
| sweepResults.m_collisionFilterMask = body->getBroadphaseProxy()->m_collisionFilterMask; | sweepResults.m_collisionFilterMask = body->getBroadphaseProxy()->m_collisionFilterMask; | ||||
| btTransform modifiedPredictedTrans = predictedTrans; | btTransform modifiedPredictedTrans = predictedTrans; | ||||
| modifiedPredictedTrans.setBasis(body->getWorldTransform().getBasis()); | modifiedPredictedTrans.setBasis(body->getWorldTransform().getBasis()); | ||||
| convexSweepTest(&tmpSphere,body->getWorldTransform(),modifiedPredictedTrans,sweepResults); | convexSweepTest(&tmpSphere,body->getWorldTransform(),modifiedPredictedTrans,sweepResults); | ||||
| if (sweepResults.hasHit() && (sweepResults.m_closestHitFraction < 1.f)) | if (sweepResults.hasHit() && (sweepResults.m_closestHitFraction < 1.f)) | ||||
| { | { | ||||
| btVector3 distVec = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin())*sweepResults.m_closestHitFraction; | btVector3 distVec = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin())*sweepResults.m_closestHitFraction; | ||||
| btScalar distance = distVec.dot(-sweepResults.m_hitNormalWorld); | btScalar distance = distVec.dot(-sweepResults.m_hitNormalWorld); | ||||
| btPersistentManifold* manifold = m_dispatcher1->getNewManifold(body,sweepResults.m_hitCollisionObject); | btPersistentManifold* manifold = m_dispatcher1->getNewManifold(body,sweepResults.m_hitCollisionObject); | ||||
| m_predictiveManifolds.push_back(manifold); | m_predictiveManifolds.push_back(manifold); | ||||
| btVector3 worldPointB = body->getWorldTransform().getOrigin()+distVec; | btVector3 worldPointB = body->getWorldTransform().getOrigin()+distVec; | ||||
| btVector3 localPointB = sweepResults.m_hitCollisionObject->getWorldTransform().inverse()*worldPointB; | btVector3 localPointB = sweepResults.m_hitCollisionObject->getWorldTransform().inverse()*worldPointB; | ||||
| btManifoldPoint newPoint(btVector3(0,0,0), localPointB,sweepResults.m_hitNormalWorld,distance); | btManifoldPoint newPoint(btVector3(0,0,0), localPointB,sweepResults.m_hitNormalWorld,distance); | ||||
| bool isPredictive = true; | bool isPredictive = true; | ||||
| int index = manifold->addManifoldPoint(newPoint, isPredictive); | int index = manifold->addManifoldPoint(newPoint, isPredictive); | ||||
| btManifoldPoint& pt = manifold->getContactPoint(index); | btManifoldPoint& pt = manifold->getContactPoint(index); | ||||
| Show All 16 Lines | void btDiscreteDynamicsWorld::integrateTransforms(btScalar timeStep) | ||||
| { | { | ||||
| btRigidBody* body = m_nonStaticRigidBodies[i]; | btRigidBody* body = m_nonStaticRigidBodies[i]; | ||||
| body->setHitFraction(1.f); | body->setHitFraction(1.f); | ||||
| if (body->isActive() && (!body->isStaticOrKinematicObject())) | if (body->isActive() && (!body->isStaticOrKinematicObject())) | ||||
| { | { | ||||
| body->predictIntegratedTransform(timeStep, predictedTrans); | body->predictIntegratedTransform(timeStep, predictedTrans); | ||||
| btScalar squareMotion = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2(); | btScalar squareMotion = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2(); | ||||
| if (getDispatchInfo().m_useContinuous && body->getCcdSquareMotionThreshold() && body->getCcdSquareMotionThreshold() < squareMotion) | if (getDispatchInfo().m_useContinuous && body->getCcdSquareMotionThreshold() && body->getCcdSquareMotionThreshold() < squareMotion) | ||||
| { | { | ||||
| BT_PROFILE("CCD motion clamping"); | BT_PROFILE("CCD motion clamping"); | ||||
| if (body->getCollisionShape()->isConvex()) | if (body->getCollisionShape()->isConvex()) | ||||
| { | { | ||||
| gNumClampedCcdMotions++; | gNumClampedCcdMotions++; | ||||
| #ifdef USE_STATIC_ONLY | #ifdef USE_STATIC_ONLY | ||||
| class StaticOnlyCallback : public btClosestNotMeConvexResultCallback | class StaticOnlyCallback : public btClosestNotMeConvexResultCallback | ||||
| { | { | ||||
| public: | public: | ||||
| StaticOnlyCallback (btCollisionObject* me,const btVector3& fromA,const btVector3& toA,btOverlappingPairCache* pairCache,btDispatcher* dispatcher) : | StaticOnlyCallback (btCollisionObject* me,const btVector3& fromA,const btVector3& toA,btOverlappingPairCache* pairCache,btDispatcher* dispatcher) : | ||||
| btClosestNotMeConvexResultCallback(me,fromA,toA,pairCache,dispatcher) | btClosestNotMeConvexResultCallback(me,fromA,toA,pairCache,dispatcher) | ||||
| { | { | ||||
| } | } | ||||
| virtual bool needsCollision(btBroadphaseProxy* proxy0) const | virtual bool needsCollision(btBroadphaseProxy* proxy0) const | ||||
| { | { | ||||
| btCollisionObject* otherObj = (btCollisionObject*) proxy0->m_clientObject; | btCollisionObject* otherObj = (btCollisionObject*) proxy0->m_clientObject; | ||||
| if (!otherObj->isStaticOrKinematicObject()) | if (!otherObj->isStaticOrKinematicObject()) | ||||
| Show All 13 Lines | #endif | ||||
| sweepResults.m_collisionFilterGroup = body->getBroadphaseProxy()->m_collisionFilterGroup; | sweepResults.m_collisionFilterGroup = body->getBroadphaseProxy()->m_collisionFilterGroup; | ||||
| sweepResults.m_collisionFilterMask = body->getBroadphaseProxy()->m_collisionFilterMask; | sweepResults.m_collisionFilterMask = body->getBroadphaseProxy()->m_collisionFilterMask; | ||||
| btTransform modifiedPredictedTrans = predictedTrans; | btTransform modifiedPredictedTrans = predictedTrans; | ||||
| modifiedPredictedTrans.setBasis(body->getWorldTransform().getBasis()); | modifiedPredictedTrans.setBasis(body->getWorldTransform().getBasis()); | ||||
| convexSweepTest(&tmpSphere,body->getWorldTransform(),modifiedPredictedTrans,sweepResults); | convexSweepTest(&tmpSphere,body->getWorldTransform(),modifiedPredictedTrans,sweepResults); | ||||
| if (sweepResults.hasHit() && (sweepResults.m_closestHitFraction < 1.f)) | if (sweepResults.hasHit() && (sweepResults.m_closestHitFraction < 1.f)) | ||||
| { | { | ||||
| //printf("clamped integration to hit fraction = %f\n",fraction); | //printf("clamped integration to hit fraction = %f\n",fraction); | ||||
| body->setHitFraction(sweepResults.m_closestHitFraction); | body->setHitFraction(sweepResults.m_closestHitFraction); | ||||
| body->predictIntegratedTransform(timeStep*body->getHitFraction(), predictedTrans); | body->predictIntegratedTransform(timeStep*body->getHitFraction(), predictedTrans); | ||||
| body->setHitFraction(0.f); | body->setHitFraction(0.f); | ||||
| body->proceedToTransform( predictedTrans); | body->proceedToTransform( predictedTrans); | ||||
| #if 0 | #if 0 | ||||
| btVector3 linVel = body->getLinearVelocity(); | btVector3 linVel = body->getLinearVelocity(); | ||||
| btScalar maxSpeed = body->getCcdMotionThreshold()/getSolverInfo().m_timeStep; | btScalar maxSpeed = body->getCcdMotionThreshold()/getSolverInfo().m_timeStep; | ||||
| btScalar maxSpeedSqr = maxSpeed*maxSpeed; | btScalar maxSpeedSqr = maxSpeed*maxSpeed; | ||||
| if (linVel.length2()>maxSpeedSqr) | if (linVel.length2()>maxSpeedSqr) | ||||
| { | { | ||||
| linVel.normalize(); | linVel.normalize(); | ||||
| linVel*= maxSpeed; | linVel*= maxSpeed; | ||||
| body->setLinearVelocity(linVel); | body->setLinearVelocity(linVel); | ||||
| btScalar ms2 = body->getLinearVelocity().length2(); | btScalar ms2 = body->getLinearVelocity().length2(); | ||||
| body->predictIntegratedTransform(timeStep, predictedTrans); | body->predictIntegratedTransform(timeStep, predictedTrans); | ||||
| btScalar sm2 = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2(); | btScalar sm2 = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2(); | ||||
| btScalar smt = body->getCcdSquareMotionThreshold(); | btScalar smt = body->getCcdSquareMotionThreshold(); | ||||
| printf("sm2=%f\n",sm2); | printf("sm2=%f\n",sm2); | ||||
| } | } | ||||
| #else | #else | ||||
| //don't apply the collision response right now, it will happen next frame | //don't apply the collision response right now, it will happen next frame | ||||
| //if you really need to, you can uncomment next 3 lines. Note that is uses zero restitution. | //if you really need to, you can uncomment next 3 lines. Note that is uses zero restitution. | ||||
| //btScalar appliedImpulse = 0.f; | //btScalar appliedImpulse = 0.f; | ||||
| //btScalar depth = 0.f; | //btScalar depth = 0.f; | ||||
| //appliedImpulse = resolveSingleCollision(body,(btCollisionObject*)sweepResults.m_hitCollisionObject,sweepResults.m_hitPointWorld,sweepResults.m_hitNormalWorld,getSolverInfo(), depth); | //appliedImpulse = resolveSingleCollision(body,(btCollisionObject*)sweepResults.m_hitCollisionObject,sweepResults.m_hitPointWorld,sweepResults.m_hitNormalWorld,getSolverInfo(), depth); | ||||
| #endif | #endif | ||||
| continue; | continue; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| body->proceedToTransform( predictedTrans); | body->proceedToTransform( predictedTrans); | ||||
| } | } | ||||
| } | } | ||||
| ///this should probably be switched on by default, but it is not well tested yet | ///this should probably be switched on by default, but it is not well tested yet | ||||
| if (m_applySpeculativeContactRestitution) | if (m_applySpeculativeContactRestitution) | ||||
| { | { | ||||
| BT_PROFILE("apply speculative contact restitution"); | BT_PROFILE("apply speculative contact restitution"); | ||||
| for (int i=0;i<m_predictiveManifolds.size();i++) | for (int i=0;i<m_predictiveManifolds.size();i++) | ||||
| { | { | ||||
| btPersistentManifold* manifold = m_predictiveManifolds[i]; | btPersistentManifold* manifold = m_predictiveManifolds[i]; | ||||
| btRigidBody* body0 = btRigidBody::upcast((btCollisionObject*)manifold->getBody0()); | btRigidBody* body0 = btRigidBody::upcast((btCollisionObject*)manifold->getBody0()); | ||||
| btRigidBody* body1 = btRigidBody::upcast((btCollisionObject*)manifold->getBody1()); | btRigidBody* body1 = btRigidBody::upcast((btCollisionObject*)manifold->getBody1()); | ||||
| for (int p=0;p<manifold->getNumContacts();p++) | for (int p=0;p<manifold->getNumContacts();p++) | ||||
| { | { | ||||
| const btManifoldPoint& pt = manifold->getContactPoint(p); | const btManifoldPoint& pt = manifold->getContactPoint(p); | ||||
| btScalar combinedRestitution = btManifoldResult::calculateCombinedRestitution(body0, body1); | btScalar combinedRestitution = btManifoldResult::calculateCombinedRestitution(body0, body1); | ||||
| if (combinedRestitution>0 && pt.m_appliedImpulse != 0.f) | if (combinedRestitution>0 && pt.m_appliedImpulse != 0.f) | ||||
| //if (pt.getDistance()>0 && combinedRestitution>0 && pt.m_appliedImpulse != 0.f) | //if (pt.getDistance()>0 && combinedRestitution>0 && pt.m_appliedImpulse != 0.f) | ||||
| { | { | ||||
| btVector3 imp = -pt.m_normalWorldOnB * pt.m_appliedImpulse* combinedRestitution; | btVector3 imp = -pt.m_normalWorldOnB * pt.m_appliedImpulse* combinedRestitution; | ||||
| const btVector3& pos1 = pt.getPositionWorldOnA(); | const btVector3& pos1 = pt.getPositionWorldOnA(); | ||||
| const btVector3& pos2 = pt.getPositionWorldOnB(); | const btVector3& pos2 = pt.getPositionWorldOnB(); | ||||
| btVector3 rel_pos0 = pos1 - body0->getWorldTransform().getOrigin(); | btVector3 rel_pos0 = pos1 - body0->getWorldTransform().getOrigin(); | ||||
| btVector3 rel_pos1 = pos2 - body1->getWorldTransform().getOrigin(); | btVector3 rel_pos1 = pos2 - body1->getWorldTransform().getOrigin(); | ||||
| if (body0) | if (body0) | ||||
| body0->applyImpulse(imp,rel_pos0); | body0->applyImpulse(imp,rel_pos0); | ||||
| if (body1) | if (body1) | ||||
| body1->applyImpulse(-imp,rel_pos1); | body1->applyImpulse(-imp,rel_pos1); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| void btDiscreteDynamicsWorld::predictUnconstraintMotion(btScalar timeStep) | void btDiscreteDynamicsWorld::predictUnconstraintMotion(btScalar timeStep) | ||||
| Show All 22 Lines | #ifndef BT_NO_PROFILE | ||||
| CProfileManager::Reset(); | CProfileManager::Reset(); | ||||
| #endif //BT_NO_PROFILE | #endif //BT_NO_PROFILE | ||||
| } | } | ||||
| void btDiscreteDynamicsWorld::debugDrawConstraint(btTypedConstraint* constraint) | void btDiscreteDynamicsWorld::debugDrawConstraint(btTypedConstraint* constraint) | ||||
| { | { | ||||
| bool drawFrames = (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawConstraints) != 0; | bool drawFrames = (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawConstraints) != 0; | ||||
| bool drawLimits = (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawConstraintLimits) != 0; | bool drawLimits = (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawConstraintLimits) != 0; | ||||
| btScalar dbgDrawSize = constraint->getDbgDrawSize(); | btScalar dbgDrawSize = constraint->getDbgDrawSize(); | ||||
| if(dbgDrawSize <= btScalar(0.f)) | if(dbgDrawSize <= btScalar(0.f)) | ||||
| { | { | ||||
| return; | return; | ||||
| } | } | ||||
| switch(constraint->getConstraintType()) | switch(constraint->getConstraintType()) | ||||
| { | { | ||||
| case POINT2POINT_CONSTRAINT_TYPE: | case POINT2POINT_CONSTRAINT_TYPE: | ||||
| { | { | ||||
| btPoint2PointConstraint* p2pC = (btPoint2PointConstraint*)constraint; | btPoint2PointConstraint* p2pC = (btPoint2PointConstraint*)constraint; | ||||
| btTransform tr; | btTransform tr; | ||||
| tr.setIdentity(); | tr.setIdentity(); | ||||
| btVector3 pivot = p2pC->getPivotInA(); | btVector3 pivot = p2pC->getPivotInA(); | ||||
| pivot = p2pC->getRigidBodyA().getCenterOfMassTransform() * pivot; | pivot = p2pC->getRigidBodyA().getCenterOfMassTransform() * pivot; | ||||
| tr.setOrigin(pivot); | tr.setOrigin(pivot); | ||||
| getDebugDrawer()->drawTransform(tr, dbgDrawSize); | getDebugDrawer()->drawTransform(tr, dbgDrawSize); | ||||
| // that ideally should draw the same frame | // that ideally should draw the same frame | ||||
| pivot = p2pC->getPivotInB(); | pivot = p2pC->getPivotInB(); | ||||
| pivot = p2pC->getRigidBodyB().getCenterOfMassTransform() * pivot; | pivot = p2pC->getRigidBodyB().getCenterOfMassTransform() * pivot; | ||||
| tr.setOrigin(pivot); | tr.setOrigin(pivot); | ||||
| if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize); | if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize); | ||||
| } | } | ||||
| break; | break; | ||||
| case HINGE_CONSTRAINT_TYPE: | case HINGE_CONSTRAINT_TYPE: | ||||
| { | { | ||||
| btHingeConstraint* pHinge = (btHingeConstraint*)constraint; | btHingeConstraint* pHinge = (btHingeConstraint*)constraint; | ||||
| btTransform tr = pHinge->getRigidBodyA().getCenterOfMassTransform() * pHinge->getAFrame(); | btTransform tr = pHinge->getRigidBodyA().getCenterOfMassTransform() * pHinge->getAFrame(); | ||||
| if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize); | if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize); | ||||
| tr = pHinge->getRigidBodyB().getCenterOfMassTransform() * pHinge->getBFrame(); | tr = pHinge->getRigidBodyB().getCenterOfMassTransform() * pHinge->getBFrame(); | ||||
| if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize); | if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize); | ||||
| btScalar minAng = pHinge->getLowerLimit(); | btScalar minAng = pHinge->getLowerLimit(); | ||||
| btScalar maxAng = pHinge->getUpperLimit(); | btScalar maxAng = pHinge->getUpperLimit(); | ||||
| if(minAng == maxAng) | if(minAng == maxAng) | ||||
| { | { | ||||
| break; | break; | ||||
| } | } | ||||
| bool drawSect = true; | bool drawSect = true; | ||||
| if(minAng > maxAng) | if(!pHinge->hasLimit()) | ||||
| { | { | ||||
| minAng = btScalar(0.f); | minAng = btScalar(0.f); | ||||
| maxAng = SIMD_2_PI; | maxAng = SIMD_2_PI; | ||||
| drawSect = false; | drawSect = false; | ||||
| } | } | ||||
| if(drawLimits) | if(drawLimits) | ||||
| { | { | ||||
| btVector3& center = tr.getOrigin(); | btVector3& center = tr.getOrigin(); | ||||
| btVector3 normal = tr.getBasis().getColumn(2); | btVector3 normal = tr.getBasis().getColumn(2); | ||||
| btVector3 axis = tr.getBasis().getColumn(0); | btVector3 axis = tr.getBasis().getColumn(0); | ||||
| getDebugDrawer()->drawArc(center, normal, axis, dbgDrawSize, dbgDrawSize, minAng, maxAng, btVector3(0,0,0), drawSect); | getDebugDrawer()->drawArc(center, normal, axis, dbgDrawSize, dbgDrawSize, minAng, maxAng, btVector3(0,0,0), drawSect); | ||||
| } | } | ||||
| } | } | ||||
| break; | break; | ||||
| Show All 18 Lines | case CONETWIST_CONSTRAINT_TYPE: | ||||
| btVector3 pCur = pCT->GetPointForAngle(fAngleInRadians, length); | btVector3 pCur = pCT->GetPointForAngle(fAngleInRadians, length); | ||||
| pCur = tr * pCur; | pCur = tr * pCur; | ||||
| getDebugDrawer()->drawLine(pPrev, pCur, btVector3(0,0,0)); | getDebugDrawer()->drawLine(pPrev, pCur, btVector3(0,0,0)); | ||||
| if (i%(nSegments/8) == 0) | if (i%(nSegments/8) == 0) | ||||
| getDebugDrawer()->drawLine(tr.getOrigin(), pCur, btVector3(0,0,0)); | getDebugDrawer()->drawLine(tr.getOrigin(), pCur, btVector3(0,0,0)); | ||||
| pPrev = pCur; | pPrev = pCur; | ||||
| } | } | ||||
| btScalar tws = pCT->getTwistSpan(); | btScalar tws = pCT->getTwistSpan(); | ||||
| btScalar twa = pCT->getTwistAngle(); | btScalar twa = pCT->getTwistAngle(); | ||||
| bool useFrameB = (pCT->getRigidBodyB().getInvMass() > btScalar(0.f)); | bool useFrameB = (pCT->getRigidBodyB().getInvMass() > btScalar(0.f)); | ||||
| if(useFrameB) | if(useFrameB) | ||||
| { | { | ||||
| tr = pCT->getRigidBodyB().getCenterOfMassTransform() * pCT->getBFrame(); | tr = pCT->getRigidBodyB().getCenterOfMassTransform() * pCT->getBFrame(); | ||||
| } | } | ||||
| else | else | ||||
| Show All 11 Lines | switch(constraint->getConstraintType()) | ||||
| case D6_SPRING_CONSTRAINT_TYPE: | case D6_SPRING_CONSTRAINT_TYPE: | ||||
| case D6_CONSTRAINT_TYPE: | case D6_CONSTRAINT_TYPE: | ||||
| { | { | ||||
| btGeneric6DofConstraint* p6DOF = (btGeneric6DofConstraint*)constraint; | btGeneric6DofConstraint* p6DOF = (btGeneric6DofConstraint*)constraint; | ||||
| btTransform tr = p6DOF->getCalculatedTransformA(); | btTransform tr = p6DOF->getCalculatedTransformA(); | ||||
| if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize); | if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize); | ||||
| tr = p6DOF->getCalculatedTransformB(); | tr = p6DOF->getCalculatedTransformB(); | ||||
| if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize); | if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize); | ||||
| if(drawLimits) | if(drawLimits) | ||||
| { | { | ||||
| tr = p6DOF->getCalculatedTransformA(); | tr = p6DOF->getCalculatedTransformA(); | ||||
| const btVector3& center = p6DOF->getCalculatedTransformB().getOrigin(); | const btVector3& center = p6DOF->getCalculatedTransformB().getOrigin(); | ||||
| btVector3 up = tr.getBasis().getColumn(2); | btVector3 up = tr.getBasis().getColumn(2); | ||||
| btVector3 axis = tr.getBasis().getColumn(0); | btVector3 axis = tr.getBasis().getColumn(0); | ||||
| btScalar minTh = p6DOF->getRotationalLimitMotor(1)->m_loLimit; | btScalar minTh = p6DOF->getRotationalLimitMotor(1)->m_loLimit; | ||||
| btScalar maxTh = p6DOF->getRotationalLimitMotor(1)->m_hiLimit; | btScalar maxTh = p6DOF->getRotationalLimitMotor(1)->m_hiLimit; | ||||
| btScalar minPs = p6DOF->getRotationalLimitMotor(2)->m_loLimit; | btScalar minPs = p6DOF->getRotationalLimitMotor(2)->m_loLimit; | ||||
| Show All 24 Lines | case D6_CONSTRAINT_TYPE: | ||||
| } | } | ||||
| tr = p6DOF->getCalculatedTransformA(); | tr = p6DOF->getCalculatedTransformA(); | ||||
| btVector3 bbMin = p6DOF->getTranslationalLimitMotor()->m_lowerLimit; | btVector3 bbMin = p6DOF->getTranslationalLimitMotor()->m_lowerLimit; | ||||
| btVector3 bbMax = p6DOF->getTranslationalLimitMotor()->m_upperLimit; | btVector3 bbMax = p6DOF->getTranslationalLimitMotor()->m_upperLimit; | ||||
| getDebugDrawer()->drawBox(bbMin, bbMax, tr, btVector3(0,0,0)); | getDebugDrawer()->drawBox(bbMin, bbMax, tr, btVector3(0,0,0)); | ||||
| } | } | ||||
| } | } | ||||
| break; | break; | ||||
| ///note: the code for D6_SPRING_2_CONSTRAINT_TYPE is identical to D6_CONSTRAINT_TYPE, the D6_CONSTRAINT_TYPE+D6_SPRING_CONSTRAINT_TYPE will likely become obsolete/deprecated at some stage | |||||
| case D6_SPRING_2_CONSTRAINT_TYPE: | |||||
| { | |||||
| { | |||||
| btGeneric6DofSpring2Constraint* p6DOF = (btGeneric6DofSpring2Constraint*)constraint; | |||||
| btTransform tr = p6DOF->getCalculatedTransformA(); | |||||
| if (drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize); | |||||
| tr = p6DOF->getCalculatedTransformB(); | |||||
| if (drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize); | |||||
| if (drawLimits) | |||||
| { | |||||
| tr = p6DOF->getCalculatedTransformA(); | |||||
| const btVector3& center = p6DOF->getCalculatedTransformB().getOrigin(); | |||||
| btVector3 up = tr.getBasis().getColumn(2); | |||||
| btVector3 axis = tr.getBasis().getColumn(0); | |||||
| btScalar minTh = p6DOF->getRotationalLimitMotor(1)->m_loLimit; | |||||
| btScalar maxTh = p6DOF->getRotationalLimitMotor(1)->m_hiLimit; | |||||
| btScalar minPs = p6DOF->getRotationalLimitMotor(2)->m_loLimit; | |||||
| btScalar maxPs = p6DOF->getRotationalLimitMotor(2)->m_hiLimit; | |||||
| getDebugDrawer()->drawSpherePatch(center, up, axis, dbgDrawSize * btScalar(.9f), minTh, maxTh, minPs, maxPs, btVector3(0, 0, 0)); | |||||
| axis = tr.getBasis().getColumn(1); | |||||
| btScalar ay = p6DOF->getAngle(1); | |||||
| btScalar az = p6DOF->getAngle(2); | |||||
| btScalar cy = btCos(ay); | |||||
| btScalar sy = btSin(ay); | |||||
| btScalar cz = btCos(az); | |||||
| btScalar sz = btSin(az); | |||||
| btVector3 ref; | |||||
| ref[0] = cy*cz*axis[0] + cy*sz*axis[1] - sy*axis[2]; | |||||
| ref[1] = -sz*axis[0] + cz*axis[1]; | |||||
| ref[2] = cz*sy*axis[0] + sz*sy*axis[1] + cy*axis[2]; | |||||
| tr = p6DOF->getCalculatedTransformB(); | |||||
| btVector3 normal = -tr.getBasis().getColumn(0); | |||||
| btScalar minFi = p6DOF->getRotationalLimitMotor(0)->m_loLimit; | |||||
| btScalar maxFi = p6DOF->getRotationalLimitMotor(0)->m_hiLimit; | |||||
| if (minFi > maxFi) | |||||
| { | |||||
| getDebugDrawer()->drawArc(center, normal, ref, dbgDrawSize, dbgDrawSize, -SIMD_PI, SIMD_PI, btVector3(0, 0, 0), false); | |||||
| } | |||||
| else if (minFi < maxFi) | |||||
| { | |||||
| getDebugDrawer()->drawArc(center, normal, ref, dbgDrawSize, dbgDrawSize, minFi, maxFi, btVector3(0, 0, 0), true); | |||||
| } | |||||
| tr = p6DOF->getCalculatedTransformA(); | |||||
| btVector3 bbMin = p6DOF->getTranslationalLimitMotor()->m_lowerLimit; | |||||
| btVector3 bbMax = p6DOF->getTranslationalLimitMotor()->m_upperLimit; | |||||
| getDebugDrawer()->drawBox(bbMin, bbMax, tr, btVector3(0, 0, 0)); | |||||
| } | |||||
| } | |||||
| break; | |||||
| } | |||||
| case SLIDER_CONSTRAINT_TYPE: | case SLIDER_CONSTRAINT_TYPE: | ||||
| { | { | ||||
| btSliderConstraint* pSlider = (btSliderConstraint*)constraint; | btSliderConstraint* pSlider = (btSliderConstraint*)constraint; | ||||
| btTransform tr = pSlider->getCalculatedTransformA(); | btTransform tr = pSlider->getCalculatedTransformA(); | ||||
| if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize); | if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize); | ||||
| tr = pSlider->getCalculatedTransformB(); | tr = pSlider->getCalculatedTransformB(); | ||||
| if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize); | if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize); | ||||
| if(drawLimits) | if(drawLimits) | ||||
| { | { | ||||
| btTransform tr = pSlider->getUseLinearReferenceFrameA() ? pSlider->getCalculatedTransformA() : pSlider->getCalculatedTransformB(); | btTransform tr = pSlider->getUseLinearReferenceFrameA() ? pSlider->getCalculatedTransformA() : pSlider->getCalculatedTransformB(); | ||||
| btVector3 li_min = tr * btVector3(pSlider->getLowerLinLimit(), 0.f, 0.f); | btVector3 li_min = tr * btVector3(pSlider->getLowerLinLimit(), 0.f, 0.f); | ||||
| btVector3 li_max = tr * btVector3(pSlider->getUpperLinLimit(), 0.f, 0.f); | btVector3 li_max = tr * btVector3(pSlider->getUpperLinLimit(), 0.f, 0.f); | ||||
| getDebugDrawer()->drawLine(li_min, li_max, btVector3(0, 0, 0)); | getDebugDrawer()->drawLine(li_min, li_max, btVector3(0, 0, 0)); | ||||
| btVector3 normal = tr.getBasis().getColumn(0); | btVector3 normal = tr.getBasis().getColumn(0); | ||||
| btVector3 axis = tr.getBasis().getColumn(1); | btVector3 axis = tr.getBasis().getColumn(1); | ||||
| btScalar a_min = pSlider->getLowerAngLimit(); | btScalar a_min = pSlider->getLowerAngLimit(); | ||||
| btScalar a_max = pSlider->getUpperAngLimit(); | btScalar a_max = pSlider->getUpperAngLimit(); | ||||
| const btVector3& center = pSlider->getCalculatedTransformB().getOrigin(); | const btVector3& center = pSlider->getCalculatedTransformB().getOrigin(); | ||||
| getDebugDrawer()->drawArc(center, normal, axis, dbgDrawSize, dbgDrawSize, a_min, a_max, btVector3(0,0,0), true); | getDebugDrawer()->drawArc(center, normal, axis, dbgDrawSize, dbgDrawSize, a_min, a_max, btVector3(0,0,0), true); | ||||
| } | } | ||||
| } | } | ||||
| break; | break; | ||||
| default : | default : | ||||
| break; | break; | ||||
| } | } | ||||
| return; | return; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 83 Lines • ▼ Show 20 Lines | #endif//BT_USE_DOUBLE_PRECISION | ||||
| worldInfo->m_solverInfo.m_maxErrorReduction = getSolverInfo().m_maxErrorReduction; | worldInfo->m_solverInfo.m_maxErrorReduction = getSolverInfo().m_maxErrorReduction; | ||||
| worldInfo->m_solverInfo.m_sor = getSolverInfo().m_sor; | worldInfo->m_solverInfo.m_sor = getSolverInfo().m_sor; | ||||
| worldInfo->m_solverInfo.m_erp = getSolverInfo().m_erp; | worldInfo->m_solverInfo.m_erp = getSolverInfo().m_erp; | ||||
| worldInfo->m_solverInfo.m_erp2 = getSolverInfo().m_erp2; | worldInfo->m_solverInfo.m_erp2 = getSolverInfo().m_erp2; | ||||
| worldInfo->m_solverInfo.m_globalCfm = getSolverInfo().m_globalCfm; | worldInfo->m_solverInfo.m_globalCfm = getSolverInfo().m_globalCfm; | ||||
| worldInfo->m_solverInfo.m_splitImpulsePenetrationThreshold = getSolverInfo().m_splitImpulsePenetrationThreshold; | worldInfo->m_solverInfo.m_splitImpulsePenetrationThreshold = getSolverInfo().m_splitImpulsePenetrationThreshold; | ||||
| worldInfo->m_solverInfo.m_splitImpulseTurnErp = getSolverInfo().m_splitImpulseTurnErp; | worldInfo->m_solverInfo.m_splitImpulseTurnErp = getSolverInfo().m_splitImpulseTurnErp; | ||||
| worldInfo->m_solverInfo.m_linearSlop = getSolverInfo().m_linearSlop; | worldInfo->m_solverInfo.m_linearSlop = getSolverInfo().m_linearSlop; | ||||
| worldInfo->m_solverInfo.m_warmstartingFactor = getSolverInfo().m_warmstartingFactor; | worldInfo->m_solverInfo.m_warmstartingFactor = getSolverInfo().m_warmstartingFactor; | ||||
| worldInfo->m_solverInfo.m_maxGyroscopicForce = getSolverInfo().m_maxGyroscopicForce; | worldInfo->m_solverInfo.m_maxGyroscopicForce = getSolverInfo().m_maxGyroscopicForce; | ||||
| worldInfo->m_solverInfo.m_singleAxisRollingFrictionThreshold = getSolverInfo().m_singleAxisRollingFrictionThreshold; | worldInfo->m_solverInfo.m_singleAxisRollingFrictionThreshold = getSolverInfo().m_singleAxisRollingFrictionThreshold; | ||||
| worldInfo->m_solverInfo.m_numIterations = getSolverInfo().m_numIterations; | worldInfo->m_solverInfo.m_numIterations = getSolverInfo().m_numIterations; | ||||
| worldInfo->m_solverInfo.m_solverMode = getSolverInfo().m_solverMode; | worldInfo->m_solverInfo.m_solverMode = getSolverInfo().m_solverMode; | ||||
| worldInfo->m_solverInfo.m_restingContactRestitutionThreshold = getSolverInfo().m_restingContactRestitutionThreshold; | worldInfo->m_solverInfo.m_restingContactRestitutionThreshold = getSolverInfo().m_restingContactRestitutionThreshold; | ||||
| worldInfo->m_solverInfo.m_minimumSolverBatchSize = getSolverInfo().m_minimumSolverBatchSize; | worldInfo->m_solverInfo.m_minimumSolverBatchSize = getSolverInfo().m_minimumSolverBatchSize; | ||||
| worldInfo->m_solverInfo.m_splitImpulse = getSolverInfo().m_splitImpulse; | worldInfo->m_solverInfo.m_splitImpulse = getSolverInfo().m_splitImpulse; | ||||
| #ifdef BT_USE_DOUBLE_PRECISION | #ifdef BT_USE_DOUBLE_PRECISION | ||||
| const char* structType = "btDynamicsWorldDoubleData"; | const char* structType = "btDynamicsWorldDoubleData"; | ||||
| #else//BT_USE_DOUBLE_PRECISION | #else//BT_USE_DOUBLE_PRECISION | ||||
| const char* structType = "btDynamicsWorldFloatData"; | const char* structType = "btDynamicsWorldFloatData"; | ||||
| #endif//BT_USE_DOUBLE_PRECISION | #endif//BT_USE_DOUBLE_PRECISION | ||||
| serializer->finalizeChunk(chunk,structType,BT_DYNAMICSWORLD_CODE,worldInfo); | serializer->finalizeChunk(chunk,structType,BT_DYNAMICSWORLD_CODE,worldInfo); | ||||
| } | } | ||||
| void btDiscreteDynamicsWorld::serialize(btSerializer* serializer) | void btDiscreteDynamicsWorld::serialize(btSerializer* serializer) | ||||
| { | { | ||||
| serializer->startSerialization(); | serializer->startSerialization(); | ||||
| serializeDynamicsWorldInfo(serializer); | serializeDynamicsWorldInfo(serializer); | ||||
| serializeRigidBodies(serializer); | |||||
| serializeCollisionObjects(serializer); | serializeCollisionObjects(serializer); | ||||
| serializeRigidBodies(serializer); | |||||
| serializer->finishSerialization(); | serializer->finishSerialization(); | ||||
| } | } | ||||