Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp')
-rw-r--r--extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp424
1 files changed, 325 insertions, 99 deletions
diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp b/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp
index 745694e2f70..ea2e0ad2a2b 100644
--- a/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp
+++ b/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp
@@ -29,6 +29,11 @@ subject to the following restrictions:
#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"
//for debug rendering
#include "BulletCollision/CollisionShapes/btBoxShape.h"
@@ -46,12 +51,7 @@ subject to the following restrictions:
#include "LinearMath/btIDebugDraw.h"
-
-//vehicle
-#include "BulletDynamics/Vehicle/btRaycastVehicle.h"
-#include "BulletDynamics/Vehicle/btVehicleRaycaster.h"
-#include "BulletDynamics/Vehicle/btWheelInfo.h"
-#include "LinearMath/btIDebugDraw.h"
+#include "BulletDynamics/Dynamics/btActionInterface.h"
#include "LinearMath/btQuickprof.h"
#include "LinearMath/btMotionState.h"
@@ -110,7 +110,6 @@ void btDiscreteDynamicsWorld::saveKinematicState(btScalar timeStep)
btRigidBody* body = btRigidBody::upcast(colObj);
if (body)
{
- btTransform predictedTrans;
if (body->getActivationState() != ISLAND_SLEEPING)
{
if (body->isKinematicObject())
@@ -125,6 +124,7 @@ void btDiscreteDynamicsWorld::saveKinematicState(btScalar timeStep)
void btDiscreteDynamicsWorld::debugDrawWorld()
{
+ BT_PROFILE("debugDrawWorld");
if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawContactPoints)
{
@@ -144,13 +144,30 @@ void btDiscreteDynamicsWorld::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;
- //todo: iterate over awake simulation islands!
for ( i=0;i<m_collisionObjects.size();i++)
{
btCollisionObject* colObj = m_collisionObjects[i];
@@ -179,7 +196,7 @@ void btDiscreteDynamicsWorld::debugDrawWorld()
}
if (m_debugDrawer && (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawAabb))
{
- btPoint3 minAabb,maxAabb;
+ btVector3 minAabb,maxAabb;
btVector3 colorvec(1,0,0);
colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb);
m_debugDrawer->drawAabb(minAabb,maxAabb,colorvec);
@@ -187,32 +204,11 @@ void btDiscreteDynamicsWorld::debugDrawWorld()
}
- for ( i=0;i<this->m_vehicles.size();i++)
+ if (getDebugDrawer() && getDebugDrawer()->getDebugMode())
{
- for (int v=0;v<m_vehicles[i]->getNumWheels();v++)
+ for (i=0;i<m_actions.size();i++)
{
- btVector3 wheelColor(0,255,255);
- if (m_vehicles[i]->getWheelInfo(v).m_raycastInfo.m_isInContact)
- {
- wheelColor.setValue(0,0,255);
- } else
- {
- wheelColor.setValue(255,0,255);
- }
-
- btVector3 wheelPosWS = m_vehicles[i]->getWheelInfo(v).m_worldTransform.getOrigin();
-
- btVector3 axle = btVector3(
- m_vehicles[i]->getWheelInfo(v).m_worldTransform.getBasis()[0][m_vehicles[i]->getRightAxis()],
- m_vehicles[i]->getWheelInfo(v).m_worldTransform.getBasis()[1][m_vehicles[i]->getRightAxis()],
- m_vehicles[i]->getWheelInfo(v).m_worldTransform.getBasis()[2][m_vehicles[i]->getRightAxis()]);
-
-
- //m_vehicles[i]->getWheelInfo(v).m_raycastInfo.m_wheelAxleWS
- //debug wheels (cylinders)
- m_debugDrawer->drawLine(wheelPosWS,wheelPosWS+axle,wheelColor);
- m_debugDrawer->drawLine(wheelPosWS,m_vehicles[i]->getWheelInfo(v).m_raycastInfo.m_contactPointWS,wheelColor);
-
+ m_actions[i]->debugDraw(m_debugDrawer);
}
}
}
@@ -220,7 +216,7 @@ void btDiscreteDynamicsWorld::debugDrawWorld()
void btDiscreteDynamicsWorld::clearForces()
{
- //todo: iterate over awake simulation islands!
+ ///@todo: iterate over awake simulation islands!
for ( int i=0;i<m_collisionObjects.size();i++)
{
btCollisionObject* colObj = m_collisionObjects[i];
@@ -236,7 +232,7 @@ void btDiscreteDynamicsWorld::clearForces()
///apply gravity, call this once per timestep
void btDiscreteDynamicsWorld::applyGravity()
{
- //todo: iterate over awake simulation islands!
+ ///@todo: iterate over awake simulation islands!
for ( int i=0;i<m_collisionObjects.size();i++)
{
btCollisionObject* colObj = m_collisionObjects[i];
@@ -250,9 +246,29 @@ void btDiscreteDynamicsWorld::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
+ ///@todo: add 'dirty' flag
+ //if (body->getActivationState() != ISLAND_SLEEPING)
+ {
+ btTransform interpolatedTransform;
+ btTransformUtil::integrateTransform(body->getInterpolationWorldTransform(),
+ body->getInterpolationLinearVelocity(),body->getInterpolationAngularVelocity(),m_localTime*body->getHitFraction(),interpolatedTransform);
+ body->getMotionState()->setWorldTransform(interpolatedTransform);
+ }
+ }
+}
+
void btDiscreteDynamicsWorld::synchronizeMotionStates()
{
+ BT_PROFILE("synchronizeMotionStates");
{
//todo: iterate over awake simulation islands!
for ( int i=0;i<m_collisionObjects.size();i++)
@@ -260,22 +276,11 @@ void btDiscreteDynamicsWorld::synchronizeMotionStates()
btCollisionObject* colObj = m_collisionObjects[i];
btRigidBody* body = btRigidBody::upcast(colObj);
- if (body && body->getMotionState() && !body->isStaticOrKinematicObject())
- {
- //we need to call the update at least once, even for sleeping objects
- //otherwise the 'graphics' transform never updates properly
- //so todo: add 'dirty' flag
- //if (body->getActivationState() != ISLAND_SLEEPING)
- {
- btTransform interpolatedTransform;
- btTransformUtil::integrateTransform(body->getInterpolationWorldTransform(),
- body->getInterpolationLinearVelocity(),body->getInterpolationAngularVelocity(),m_localTime*body->getHitFraction(),interpolatedTransform);
- body->getMotionState()->setWorldTransform(interpolatedTransform);
- }
- }
+ if (body)
+ synchronizeSingleMotionState(body);
}
}
-
+/*
if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawWireframe)
{
for ( int i=0;i<this->m_vehicles.size();i++)
@@ -287,6 +292,8 @@ void btDiscreteDynamicsWorld::synchronizeMotionStates()
}
}
}
+ */
+
}
@@ -327,7 +334,8 @@ int btDiscreteDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps,
//process some debugging flags
if (getDebugDrawer())
{
- gDisableDeactivation = (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_NoDeactivation) != 0;
+ btIDebugDraw* debugDrawer = getDebugDrawer ();
+ gDisableDeactivation = (debugDrawer->getDebugMode() & btIDebugDraw::DBG_NoDeactivation) != 0;
}
if (numSimulationSubSteps)
{
@@ -391,9 +399,8 @@ void btDiscreteDynamicsWorld::internalSingleStepSimulation(btScalar timeStep)
integrateTransforms(timeStep);
///update vehicle simulation
- updateVehicles(timeStep);
-
-
+ updateActions(timeStep);
+
updateActivationState( timeStep );
if(0 != m_internalTickCallback) {
@@ -423,13 +430,6 @@ btVector3 btDiscreteDynamicsWorld::getGravity () const
void btDiscreteDynamicsWorld::removeRigidBody(btRigidBody* body)
{
- //remove all constraints too
- while (body->getNumConstraintRefs())
- {
- btTypedConstraint* constraint = body->getConstraintRef(0);
- removeConstraint(constraint);
- }
-
removeCollisionObject(body);
}
@@ -464,17 +464,17 @@ void btDiscreteDynamicsWorld::addRigidBody(btRigidBody* body, short group, short
}
-void btDiscreteDynamicsWorld::updateVehicles(btScalar timeStep)
+void btDiscreteDynamicsWorld::updateActions(btScalar timeStep)
{
- BT_PROFILE("updateVehicles");
+ BT_PROFILE("updateActions");
- for ( int i=0;i<m_vehicles.size();i++)
+ for ( int i=0;i<m_actions.size();i++)
{
- btRaycastVehicle* vehicle = m_vehicles[i];
- vehicle->updateVehicle( timeStep);
+ m_actions[i]->updateAction( this, timeStep);
}
}
-
+
+
void btDiscreteDynamicsWorld::updateActivationState(btScalar timeStep)
{
BT_PROFILE("updateActivationState");
@@ -529,16 +529,38 @@ void btDiscreteDynamicsWorld::removeConstraint(btTypedConstraint* constraint)
constraint->getRigidBodyB().removeConstraintRef(constraint);
}
-void btDiscreteDynamicsWorld::addVehicle(btRaycastVehicle* vehicle)
+void btDiscreteDynamicsWorld::addAction(btActionInterface* action)
+{
+ m_actions.push_back(action);
+}
+
+void btDiscreteDynamicsWorld::removeAction(btActionInterface* action)
+{
+ m_actions.remove(action);
+}
+
+
+void btDiscreteDynamicsWorld::addVehicle(btActionInterface* vehicle)
+{
+ addAction(vehicle);
+}
+
+void btDiscreteDynamicsWorld::removeVehicle(btActionInterface* vehicle)
+{
+ removeAction(vehicle);
+}
+
+void btDiscreteDynamicsWorld::addCharacter(btActionInterface* character)
{
- m_vehicles.push_back(vehicle);
+ addAction(character);
}
-void btDiscreteDynamicsWorld::removeVehicle(btRaycastVehicle* vehicle)
+void btDiscreteDynamicsWorld::removeCharacter(btActionInterface* character)
{
- m_vehicles.remove(vehicle);
+ removeAction(character);
}
+
SIMD_FORCE_INLINE int btGetConstraintIslandId(const btTypedConstraint* lhs)
{
int islandId;
@@ -611,8 +633,11 @@ void btDiscreteDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo)
{
if (islandId<0)
{
- ///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_stackAlloc,m_dispatcher);
+ if (numManifolds + m_numConstraints)
+ {
+ ///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_stackAlloc,m_dispatcher);
+ }
} else
{
//also add all non-contact constraints/joints for this island
@@ -658,7 +683,7 @@ void btDiscreteDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo)
sortedConstraints[i] = m_constraints[i];
}
-// assert(0);
+// btAssert(0);
@@ -671,7 +696,7 @@ void btDiscreteDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo)
m_constraintSolver->prepareSolve(getCollisionWorld()->getNumCollisionObjects(), getCollisionWorld()->getDispatcher()->getNumManifolds());
/// solve all the constraints for this island
- m_islandManager->buildAndProcessIslands(getCollisionWorld()->getDispatcher(),getCollisionWorld()->getCollisionObjectArray(),&solverCallback);
+ m_islandManager->buildAndProcessIslands(getCollisionWorld()->getDispatcher(),getCollisionWorld(),&solverCallback);
m_constraintSolver->allSolved(solverInfo, m_debugDrawer, m_stackAlloc);
}
@@ -722,21 +747,27 @@ class btClosestNotMeConvexResultCallback : public btCollisionWorld::ClosestConve
btCollisionObject* m_me;
btScalar m_allowedPenetration;
btOverlappingPairCache* m_pairCache;
+ btDispatcher* m_dispatcher;
public:
- btClosestNotMeConvexResultCallback (btCollisionObject* me,const btVector3& fromA,const btVector3& toA,btOverlappingPairCache* pairCache) :
+ btClosestNotMeConvexResultCallback (btCollisionObject* me,const btVector3& fromA,const btVector3& toA,btOverlappingPairCache* pairCache,btDispatcher* dispatcher) :
btCollisionWorld::ClosestConvexResultCallback(fromA,toA),
m_allowedPenetration(0.0f),
m_me(me),
- m_pairCache(pairCache)
+ m_pairCache(pairCache),
+ m_dispatcher(dispatcher)
{
}
virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult& convexResult,bool normalInWorldSpace)
{
if (convexResult.m_hitCollisionObject == m_me)
- return 1.0;
+ return 1.0f;
+
+ //ignore result if there is no contact response
+ if(!convexResult.m_hitCollisionObject->hasContactResponse())
+ return 1.0f;
btVector3 linVelA,linVelB;
linVelA = m_convexToWorld-m_convexFromWorld;
@@ -757,23 +788,29 @@ public:
return false;
///don't do CCD when the collision filters are not matching
- if (!btCollisionWorld::ClosestConvexResultCallback::needsCollision(proxy0))
+ if (!ClosestConvexResultCallback::needsCollision(proxy0))
return false;
- ///don't do CCD when there are already contact points (touching contact/penetration)
- btAlignedObjectArray<btPersistentManifold*> manifoldArray;
- btBroadphasePair* collisionPair = m_pairCache->findPair(m_me->getBroadphaseHandle(),proxy0);
- if (collisionPair)
+ btCollisionObject* otherObj = (btCollisionObject*) proxy0->m_clientObject;
+
+ //call needsResponse, see http://code.google.com/p/bullet/issues/detail?id=179
+ if (m_dispatcher->needsResponse(m_me,otherObj))
{
- if (collisionPair->m_algorithm)
+ ///don't do CCD when there are already contact points (touching contact/penetration)
+ btAlignedObjectArray<btPersistentManifold*> manifoldArray;
+ btBroadphasePair* collisionPair = m_pairCache->findPair(m_me->getBroadphaseHandle(),proxy0);
+ if (collisionPair)
{
- manifoldArray.resize(0);
- collisionPair->m_algorithm->getAllContactManifolds(manifoldArray);
- for (int j=0;j<manifoldArray.size();j++)
+ if (collisionPair->m_algorithm)
{
- btPersistentManifold* manifold = manifoldArray[j];
- if (manifold->getNumContacts()>0)
- return false;
+ manifoldArray.resize(0);
+ collisionPair->m_algorithm->getAllContactManifolds(manifoldArray);
+ for (int j=0;j<manifoldArray.size();j++)
+ {
+ btPersistentManifold* manifold = manifoldArray[j];
+ if (manifold->getNumContacts()>0)
+ return false;
+ }
}
}
}
@@ -811,9 +848,13 @@ void btDiscreteDynamicsWorld::integrateTransforms(btScalar timeStep)
{
gNumClampedCcdMotions++;
- btClosestNotMeConvexResultCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache());
+ btClosestNotMeConvexResultCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache(),getDispatcher());
btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
btSphereShape tmpSphere(body->getCcdSweptSphereRadius());//btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
+
+ sweepResults.m_collisionFilterGroup = body->getBroadphaseProxy()->m_collisionFilterGroup;
+ sweepResults.m_collisionFilterMask = body->getBroadphaseProxy()->m_collisionFilterMask;
+
convexSweepTest(&tmpSphere,body->getWorldTransform(),predictedTrans,sweepResults);
if (sweepResults.hasHit() && (sweepResults.m_closestHitFraction < 1.f))
{
@@ -833,6 +874,8 @@ void btDiscreteDynamicsWorld::integrateTransforms(btScalar timeStep)
+
+
void btDiscreteDynamicsWorld::predictUnconstraintMotion(btScalar timeStep)
{
BT_PROFILE("predictUnconstraintMotion");
@@ -844,14 +887,12 @@ void btDiscreteDynamicsWorld::predictUnconstraintMotion(btScalar timeStep)
{
if (!body->isStaticOrKinematicObject())
{
- if (body->isActive())
- {
- body->integrateVelocities( timeStep);
- //damping
- body->applyDamping(timeStep);
+
+ body->integrateVelocities( timeStep);
+ //damping
+ body->applyDamping(timeStep);
- body->predictIntegratedTransform(timeStep,body->getInterpolationWorldTransform());
- }
+ body->predictIntegratedTransform(timeStep,body->getInterpolationWorldTransform());
}
}
}
@@ -1103,7 +1144,7 @@ void btDiscreteDynamicsWorld::debugDrawObject(const btTransform& worldTransform,
{
btConcaveShape* concaveMesh = (btConcaveShape*) shape;
- //todo pass camera, for some culling
+ ///@todo pass camera, for some culling? no -> we are not a graphics lib
btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30));
btVector3 aabbMin(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30));
@@ -1132,7 +1173,7 @@ void btDiscreteDynamicsWorld::debugDrawObject(const btTransform& worldTransform,
int i;
for (i=0;i<polyshape->getNumEdges();i++)
{
- btPoint3 a,b;
+ btVector3 a,b;
polyshape->getEdge(i,a,b);
btVector3 wa = worldTransform * a;
btVector3 wb = worldTransform * b;
@@ -1148,6 +1189,189 @@ void btDiscreteDynamicsWorld::debugDrawObject(const btTransform& worldTransform,
}
+void btDiscreteDynamicsWorld::debugDrawConstraint(btTypedConstraint* constraint)
+{
+ bool drawFrames = (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawConstraints) != 0;
+ bool drawLimits = (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawConstraintLimits) != 0;
+ btScalar dbgDrawSize = constraint->getDbgDrawSize();
+ if(dbgDrawSize <= btScalar(0.f))
+ {
+ return;
+ }
+
+ switch(constraint->getConstraintType())
+ {
+ case POINT2POINT_CONSTRAINT_TYPE:
+ {
+ btPoint2PointConstraint* p2pC = (btPoint2PointConstraint*)constraint;
+ btTransform tr;
+ tr.setIdentity();
+ btVector3 pivot = p2pC->getPivotInA();
+ pivot = p2pC->getRigidBodyA().getCenterOfMassTransform() * pivot;
+ tr.setOrigin(pivot);
+ getDebugDrawer()->drawTransform(tr, dbgDrawSize);
+ // that ideally should draw the same frame
+ pivot = p2pC->getPivotInB();
+ pivot = p2pC->getRigidBodyB().getCenterOfMassTransform() * pivot;
+ tr.setOrigin(pivot);
+ if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
+ }
+ break;
+ case HINGE_CONSTRAINT_TYPE:
+ {
+ btHingeConstraint* pHinge = (btHingeConstraint*)constraint;
+ btTransform tr = pHinge->getRigidBodyA().getCenterOfMassTransform() * pHinge->getAFrame();
+ if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
+ tr = pHinge->getRigidBodyB().getCenterOfMassTransform() * pHinge->getBFrame();
+ if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
+ btScalar minAng = pHinge->getLowerLimit();
+ btScalar maxAng = pHinge->getUpperLimit();
+ if(minAng == maxAng)
+ {
+ break;
+ }
+ bool drawSect = true;
+ if(minAng > maxAng)
+ {
+ minAng = btScalar(0.f);
+ maxAng = SIMD_2_PI;
+ drawSect = false;
+ }
+ if(drawLimits)
+ {
+ btVector3& center = tr.getOrigin();
+ btVector3 normal = tr.getBasis().getColumn(2);
+ btVector3 axis = tr.getBasis().getColumn(0);
+ getDebugDrawer()->drawArc(center, normal, axis, dbgDrawSize, dbgDrawSize, minAng, maxAng, btVector3(0,0,0), drawSect);
+ }
+ }
+ break;
+ case CONETWIST_CONSTRAINT_TYPE:
+ {
+ btConeTwistConstraint* pCT = (btConeTwistConstraint*)constraint;
+ btTransform tr = pCT->getRigidBodyA().getCenterOfMassTransform() * pCT->getAFrame();
+ if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
+ tr = pCT->getRigidBodyB().getCenterOfMassTransform() * pCT->getBFrame();
+ if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
+ if(drawLimits)
+ {
+ //const btScalar length = btScalar(5);
+ const btScalar length = dbgDrawSize;
+ static int nSegments = 8*4;
+ btScalar fAngleInRadians = btScalar(2.*3.1415926) * (btScalar)(nSegments-1)/btScalar(nSegments);
+ btVector3 pPrev = pCT->GetPointForAngle(fAngleInRadians, length);
+ pPrev = tr * pPrev;
+ for (int i=0; i<nSegments; i++)
+ {
+ fAngleInRadians = btScalar(2.*3.1415926) * (btScalar)i/btScalar(nSegments);
+ btVector3 pCur = pCT->GetPointForAngle(fAngleInRadians, length);
+ pCur = tr * pCur;
+ getDebugDrawer()->drawLine(pPrev, pCur, btVector3(0,0,0));
+
+ if (i%(nSegments/8) == 0)
+ getDebugDrawer()->drawLine(tr.getOrigin(), pCur, btVector3(0,0,0));
+
+ pPrev = pCur;
+ }
+ btScalar tws = pCT->getTwistSpan();
+ btScalar twa = pCT->getTwistAngle();
+ bool useFrameB = (pCT->getRigidBodyB().getInvMass() > btScalar(0.f));
+ if(useFrameB)
+ {
+ tr = pCT->getRigidBodyB().getCenterOfMassTransform() * pCT->getBFrame();
+ }
+ else
+ {
+ tr = pCT->getRigidBodyA().getCenterOfMassTransform() * pCT->getAFrame();
+ }
+ btVector3 pivot = tr.getOrigin();
+ btVector3 normal = tr.getBasis().getColumn(0);
+ btVector3 axis1 = tr.getBasis().getColumn(1);
+ getDebugDrawer()->drawArc(pivot, normal, axis1, dbgDrawSize, dbgDrawSize, -twa-tws, -twa+tws, btVector3(0,0,0), true);
+
+ }
+ }
+ break;
+ case D6_CONSTRAINT_TYPE:
+ {
+ btGeneric6DofConstraint* p6DOF = (btGeneric6DofConstraint*)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:
+ {
+ btSliderConstraint* pSlider = (btSliderConstraint*)constraint;
+ btTransform tr = pSlider->getCalculatedTransformA();
+ if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
+ tr = pSlider->getCalculatedTransformB();
+ if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
+ if(drawLimits)
+ {
+ btTransform tr = pSlider->getCalculatedTransformA();
+ btVector3 li_min = tr * btVector3(pSlider->getLowerLinLimit(), 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));
+ btVector3 normal = tr.getBasis().getColumn(0);
+ btVector3 axis = tr.getBasis().getColumn(1);
+ btScalar a_min = pSlider->getLowerAngLimit();
+ btScalar a_max = pSlider->getUpperAngLimit();
+ const btVector3& center = pSlider->getCalculatedTransformB().getOrigin();
+ getDebugDrawer()->drawArc(center, normal, axis, dbgDrawSize, dbgDrawSize, a_min, a_max, btVector3(0,0,0), true);
+ }
+ }
+ break;
+ default :
+ break;
+ }
+ return;
+} // btDiscreteDynamicsWorld::debugDrawConstraint()
+
+
+
+
+
void btDiscreteDynamicsWorld::setConstraintSolver(btConstraintSolver* solver)
{
if (m_ownsConstraintSolver)
@@ -1176,3 +1400,5 @@ const btTypedConstraint* btDiscreteDynamicsWorld::getConstraint(int index) const
{
return m_constraints[index];
}
+
+