Index: code/trunk/src/bullet/BulletDynamics/Dynamics/Bullet-C-API.cpp
===================================================================
--- code/trunk/src/bullet/BulletDynamics/Dynamics/Bullet-C-API.cpp	(revision 2662)
+++ code/trunk/src/bullet/BulletDynamics/Dynamics/Bullet-C-API.cpp	(revision 2882)
@@ -111,5 +111,5 @@
 {
 	btDynamicsWorld* dynamicsWorld = reinterpret_cast< btDynamicsWorld* >(world);
-	assert(dynamicsWorld);
+	btAssert(dynamicsWorld);
 	dynamicsWorld->stepSimulation(timeStep);
 }
@@ -118,7 +118,7 @@
 {
 	btDynamicsWorld* dynamicsWorld = reinterpret_cast< btDynamicsWorld* >(world);
-	assert(dynamicsWorld);
-	btRigidBody* body = reinterpret_cast< btRigidBody* >(object);
-	assert(body);
+	btAssert(dynamicsWorld);
+	btRigidBody* body = reinterpret_cast< btRigidBody* >(object);
+	btAssert(body);
 
 	dynamicsWorld->addRigidBody(body);
@@ -128,7 +128,7 @@
 {
 	btDynamicsWorld* dynamicsWorld = reinterpret_cast< btDynamicsWorld* >(world);
-	assert(dynamicsWorld);
-	btRigidBody* body = reinterpret_cast< btRigidBody* >(object);
-	assert(body);
+	btAssert(dynamicsWorld);
+	btRigidBody* body = reinterpret_cast< btRigidBody* >(object);
+	btAssert(body);
 
 	dynamicsWorld->removeRigidBody(body);
@@ -143,5 +143,5 @@
 	btVector3 localInertia(0,0,0);
 	btCollisionShape* shape = reinterpret_cast<btCollisionShape*>( cshape);
-	assert(shape);
+	btAssert(shape);
 	if (mass)
 	{
@@ -159,5 +159,5 @@
 {
 	btRigidBody* body = reinterpret_cast< btRigidBody* >(cbody);
-	assert(body);
+	btAssert(body);
 	btAlignedFree( body);
 }
@@ -263,5 +263,5 @@
 {
 	btCollisionShape* shape = reinterpret_cast<btCollisionShape*>( cshape);
-	assert(shape);
+	btAssert(shape);
 	btAlignedFree(shape);
 }
@@ -269,5 +269,5 @@
 {
 	btCollisionShape* shape = reinterpret_cast<btCollisionShape*>( cshape);
-	assert(shape);
+	btAssert(shape);
 	btVector3 scaling(cscaling[0],cscaling[1],cscaling[2]);
 	shape->setLocalScaling(scaling);	
Index: code/trunk/src/bullet/BulletDynamics/Dynamics/btActionInterface.h
===================================================================
--- code/trunk/src/bullet/BulletDynamics/Dynamics/btActionInterface.h	(revision 2882)
+++ code/trunk/src/bullet/BulletDynamics/Dynamics/btActionInterface.h	(revision 2882)
@@ -0,0 +1,39 @@
+/*
+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"
+
+///Basic interface to allow actions such as vehicles and characters to be updated inside a btDynamicsWorld
+class btActionInterface
+{
+	public:
+
+	virtual ~btActionInterface()
+	{
+	}
+
+	virtual void updateAction( btCollisionWorld* collisionWorld, btScalar deltaTimeStep)=0;
+
+	virtual void debugDraw(btIDebugDraw* debugDrawer) = 0;
+
+};
+
+#endif //_BT_ACTION_INTERFACE_H
Index: code/trunk/src/bullet/BulletDynamics/Dynamics/btContinuousDynamicsWorld.cpp
===================================================================
--- code/trunk/src/bullet/BulletDynamics/Dynamics/btContinuousDynamicsWorld.cpp	(revision 2662)
+++ code/trunk/src/bullet/BulletDynamics/Dynamics/btContinuousDynamicsWorld.cpp	(revision 2882)
@@ -91,6 +91,5 @@
 
 	///update vehicle simulation
-	updateVehicles(timeStep);
-
+	updateActions(timeStep);
 
 	updateActivationState( timeStep );
Index: code/trunk/src/bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp
===================================================================
--- code/trunk/src/bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp	(revision 2662)
+++ code/trunk/src/bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp	(revision 2882)
@@ -30,4 +30,9 @@
 #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
@@ -47,13 +52,5 @@
 
 
-
-//vehicle
-#include "BulletDynamics/Vehicle/btRaycastVehicle.h"
-#include "BulletDynamics/Vehicle/btVehicleRaycaster.h"
-#include "BulletDynamics/Vehicle/btWheelInfo.h"
-//character
-#include "BulletDynamics/Character/btCharacterControllerInterface.h"
-
-#include "LinearMath/btIDebugDraw.h"
+#include "BulletDynamics/Dynamics/btActionInterface.h"
 #include "LinearMath/btQuickprof.h"
 #include "LinearMath/btMotionState.h"
@@ -114,5 +111,4 @@
 		if (body)
 		{
-				btTransform predictedTrans;
 				if (body->getActivationState() != ISLAND_SLEEPING)
 				{
@@ -149,4 +145,22 @@
 		}
 	}
+	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);
+		}
+	}
+
 
 
@@ -191,30 +205,9 @@
 		}
 	
-		for (  i=0;i<this->m_vehicles.size();i++)
-		{
-			for (int v=0;v<m_vehicles[i]->getNumWheels();v++)
-			{
-				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);
-
+		if (getDebugDrawer() && getDebugDrawer()->getDebugMode())
+		{
+			for (i=0;i<m_actions.size();i++)
+			{
+				m_actions[i]->debugDraw(m_debugDrawer);
 			}
 		}
@@ -288,5 +281,5 @@
 		}
 	}
-
+/*
 	if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawWireframe)
 	{
@@ -300,4 +293,6 @@
 		}
 	}
+	*/
+
 
 }
@@ -340,5 +335,6 @@
 	if (getDebugDrawer())
 	{
-		gDisableDeactivation = (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_NoDeactivation) != 0;
+		btIDebugDraw* debugDrawer = getDebugDrawer ();
+		gDisableDeactivation = (debugDrawer->getDebugMode() & btIDebugDraw::DBG_NoDeactivation) != 0;
 	}
 	if (numSimulationSubSteps)
@@ -404,8 +400,6 @@
 
 	///update vehicle simulation
-	updateVehicles(timeStep);
-	
-	updateCharacters(timeStep);
-
+	updateActions(timeStep);
+	
 	updateActivationState( timeStep );
 
@@ -471,27 +465,13 @@
 
 
-void	btDiscreteDynamicsWorld::updateVehicles(btScalar timeStep)
-{
-	BT_PROFILE("updateVehicles");
-	
-	for ( int i=0;i<m_vehicles.size();i++)
-	{
-		btRaycastVehicle* vehicle = m_vehicles[i];
-		vehicle->updateVehicle( timeStep);
-	}
-}
-
-void	btDiscreteDynamicsWorld::updateCharacters(btScalar timeStep)
-{
-	BT_PROFILE("updateCharacters");
-	
-	for ( int i=0;i<m_characters.size();i++)
-	{
-		btCharacterControllerInterface* character = m_characters[i];
-		character->preStep (this);
-		character->playerStep (this,timeStep);
-	}
-}
-
+void	btDiscreteDynamicsWorld::updateActions(btScalar timeStep)
+{
+	BT_PROFILE("updateActions");
+	
+	for ( int i=0;i<m_actions.size();i++)
+	{
+		m_actions[i]->updateAction( this, timeStep);
+	}
+}
 	
 	
@@ -550,22 +530,33 @@
 }
 
-void	btDiscreteDynamicsWorld::addVehicle(btRaycastVehicle* vehicle)
-{
-	m_vehicles.push_back(vehicle);
-}
-
-void	btDiscreteDynamicsWorld::removeVehicle(btRaycastVehicle* vehicle)
-{
-	m_vehicles.remove(vehicle);
-}
-
-void	btDiscreteDynamicsWorld::addCharacter(btCharacterControllerInterface* character)
-{
-	m_characters.push_back(character);
-}
-
-void	btDiscreteDynamicsWorld::removeCharacter(btCharacterControllerInterface* character)
-{
-	m_characters.remove(character);
+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)
+{
+	addAction(character);
+}
+
+void	btDiscreteDynamicsWorld::removeCharacter(btActionInterface* character)
+{
+	removeAction(character);
 }
 
@@ -643,6 +634,9 @@
 			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
 			{
@@ -690,5 +684,5 @@
 	}
 
-//	assert(0);
+//	btAssert(0);
 		
 	
@@ -754,12 +748,14 @@
 	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)
 	{
 	}
@@ -796,18 +792,24 @@
 			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)
-		{
-			if (collisionPair->m_algorithm)
-			{
-				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;
+		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))
+		{
+			///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)
+			{
+				if (collisionPair->m_algorithm)
+				{
+					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;
+					}
 				}
 			}
@@ -847,5 +849,5 @@
 						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());
@@ -1188,4 +1190,187 @@
 
 
+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)
 {
@@ -1216,2 +1401,4 @@
 	return m_constraints[index];
 }
+
+
Index: code/trunk/src/bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h
===================================================================
--- code/trunk/src/bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h	(revision 2662)
+++ code/trunk/src/bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h	(revision 2882)
@@ -24,8 +24,6 @@
 class btSimulationIslandManager;
 class btTypedConstraint;
+class btActionInterface;
 
-
-class btRaycastVehicle;
-class btCharacterControllerInterface;
 class btIDebugDraw;
 #include "LinearMath/btAlignedObjectArray.h"
@@ -53,10 +51,6 @@
 	bool	m_ownsConstraintSolver;
 
+	btAlignedObjectArray<btActionInterface*>	m_actions;
 	
-	btAlignedObjectArray<btRaycastVehicle*>	m_vehicles;
-	
-	btAlignedObjectArray<btCharacterControllerInterface*> m_characters;
-	
-
 	int	m_profileTimings;
 
@@ -71,7 +65,5 @@
 	void	updateActivationState(btScalar timeStep);
 
-	void	updateVehicles(btScalar timeStep);
-
-	void	updateCharacters(btScalar timeStep);
+	void	updateActions(btScalar timeStep);
 
 	void	startProfiling(btScalar timeStep);
@@ -106,13 +98,8 @@
 	virtual void	removeConstraint(btTypedConstraint* constraint);
 
-	virtual void	addVehicle(btRaycastVehicle* vehicle);
+	virtual void	addAction(btActionInterface*);
 
-	virtual void	removeVehicle(btRaycastVehicle* vehicle);
+	virtual void	removeAction(btActionInterface*);
 	
-	virtual void	addCharacter(btCharacterControllerInterface* character);
-
-	virtual void	removeCharacter(btCharacterControllerInterface* character);
-		
-
 	btSimulationIslandManager*	getSimulationIslandManager()
 	{
@@ -131,4 +118,5 @@
 
 	virtual void	setGravity(const btVector3& gravity);
+
 	virtual btVector3 getGravity () const;
 
@@ -140,4 +128,6 @@
 
 	void	debugDrawObject(const btTransform& worldTransform, const btCollisionShape* shape, const btVector3& color);
+
+	void	debugDrawConstraint(btTypedConstraint* constraint);
 
 	virtual void	debugDrawWorld();
@@ -170,4 +160,19 @@
 	}
 
+	///obsolete, use updateActions instead
+	virtual void updateVehicles(btScalar timeStep)
+	{
+		updateActions(timeStep);
+	}
+
+	///obsolete, use addAction instead
+	virtual void	addVehicle(btActionInterface* vehicle);
+	///obsolete, use removeAction instead
+	virtual void	removeVehicle(btActionInterface* vehicle);
+	///obsolete, use addAction instead
+	virtual void	addCharacter(btActionInterface* character);
+	///obsolete, use removeAction instead
+	virtual void	removeCharacter(btActionInterface* character);
+
 };
 
Index: code/trunk/src/bullet/BulletDynamics/Dynamics/btDynamicsWorld.h
===================================================================
--- code/trunk/src/bullet/BulletDynamics/Dynamics/btDynamicsWorld.h	(revision 2662)
+++ code/trunk/src/bullet/BulletDynamics/Dynamics/btDynamicsWorld.h	(revision 2882)
@@ -21,8 +21,8 @@
 
 class btTypedConstraint;
-class btRaycastVehicle;
+class btActionInterface;
 class btConstraintSolver;
 class btDynamicsWorld;
-class btCharacterControllerInterface;
+
 
 /// Type for the callback for each tick
@@ -73,12 +73,7 @@
 		virtual void	removeConstraint(btTypedConstraint* constraint) {(void)constraint;}
 
-		virtual void	addVehicle(btRaycastVehicle* vehicle) {(void)vehicle;}
+		virtual void	addAction(btActionInterface* action) = 0;
 
-		virtual void	removeVehicle(btRaycastVehicle* vehicle) {(void)vehicle;}
-
-		virtual void	addCharacter(btCharacterControllerInterface* character) {(void)character;}
-
-		virtual void	removeCharacter(btCharacterControllerInterface* character) {(void)character;}
-
+		virtual void	removeAction(btActionInterface* action) = 0;
 
 		//once a rigidbody is added to the dynamics world, it will get this gravity assigned
@@ -130,4 +125,14 @@
 
 
+		///obsolete, use addAction instead.
+		virtual void	addVehicle(btActionInterface* vehicle) {(void)vehicle;}
+		///obsolete, use removeAction instead
+		virtual void	removeVehicle(btActionInterface* vehicle) {(void)vehicle;}
+		///obsolete, use addAction instead.
+		virtual void	addCharacter(btActionInterface* character) {(void)character;}
+		///obsolete, use removeAction instead
+		virtual void	removeCharacter(btActionInterface* character) {(void)character;}
+
+
 };
 
Index: code/trunk/src/bullet/BulletDynamics/Dynamics/btRigidBody.cpp
===================================================================
--- code/trunk/src/bullet/BulletDynamics/Dynamics/btRigidBody.cpp	(revision 2662)
+++ code/trunk/src/bullet/BulletDynamics/Dynamics/btRigidBody.cpp	(revision 2882)
@@ -47,4 +47,5 @@
 	m_angularFactor = btScalar(1.);
 	m_gravity.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
+	m_gravity_acceleration.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
 	m_totalForce.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
 	m_totalTorque.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0)),
@@ -125,4 +126,5 @@
 		m_gravity = acceleration * (btScalar(1.0) / m_inverseMass);
 	}
+	m_gravity_acceleration = acceleration;
 }
 
Index: code/trunk/src/bullet/BulletDynamics/Dynamics/btRigidBody.h
===================================================================
--- code/trunk/src/bullet/BulletDynamics/Dynamics/btRigidBody.h	(revision 2662)
+++ code/trunk/src/bullet/BulletDynamics/Dynamics/btRigidBody.h	(revision 2882)
@@ -49,4 +49,5 @@
 
 	btVector3		m_gravity;	
+	btVector3		m_gravity_acceleration;
 	btVector3		m_invInertiaLocal;
 	btVector3		m_totalForce;
@@ -182,5 +183,5 @@
 	const btVector3&	getGravity() const
 	{
-		return m_gravity;
+		return m_gravity_acceleration;
 	}
 
@@ -232,6 +233,16 @@
 		m_totalForce += force;
 	}
+
+	const btVector3& getTotalForce()
+	{
+		return m_totalForce;
+	};
+
+	const btVector3& getTotalTorque()
+	{
+		return m_totalTorque;
+	};
     
-	const btVector3& getInvInertiaDiagLocal()
+	const btVector3& getInvInertiaDiagLocal() const
 	{
 		return m_invInertiaLocal;
