Logo Search packages:      
Sourcecode: blender version File versions  Download package

CcdPhysicsEnvironment.cpp

/*
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.
*/




#include "CcdPhysicsEnvironment.h"
#include "CcdPhysicsController.h"

#include <algorithm>
#include "SimdTransform.h"
#include "Dynamics/RigidBody.h"
#include "BroadphaseCollision/BroadphaseInterface.h"
#include "BroadphaseCollision/SimpleBroadphase.h"
#include "BroadphaseCollision/AxisSweep3.h"

#include "CollisionDispatch/CollisionWorld.h"

#include "CollisionShapes/ConvexShape.h"
#include "CollisionShapes/ConeShape.h"



#include "BroadphaseCollision/Dispatcher.h"
#include "NarrowPhaseCollision/PersistentManifold.h"
#include "CollisionShapes/TriangleMeshShape.h"
#include "ConstraintSolver/OdeConstraintSolver.h"
#include "ConstraintSolver/SimpleConstraintSolver.h"


//profiling/timings
#include "quickprof.h"


#include "IDebugDraw.h"

#include "NarrowPhaseCollision/VoronoiSimplexSolver.h"
#include "NarrowPhaseCollision/SubSimplexConvexCast.h"
#include "NarrowPhaseCollision/GjkConvexCast.h"
#include "NarrowPhaseCollision/ContinuousConvexCollision.h"


#include "CollisionDispatch/CollisionDispatcher.h"
#include "PHY_IMotionState.h"

#include "CollisionDispatch/EmptyCollisionAlgorithm.h"
#include "CollisionDispatch/UnionFind.h"


#include "CollisionShapes/SphereShape.h"

bool useIslands = true;

#ifdef NEW_BULLET_VEHICLE_SUPPORT
#include "Vehicle/RaycastVehicle.h"
#include "Vehicle/VehicleRaycaster.h"

#include "Vehicle/WheelInfo.h"
#include "PHY_IVehicle.h"
RaycastVehicle::VehicleTuning gTuning;

#endif //NEW_BULLET_VEHICLE_SUPPORT
#include "AabbUtil2.h"

#include "ConstraintSolver/ConstraintSolver.h"
#include "ConstraintSolver/Point2PointConstraint.h"
#include "ConstraintSolver/HingeConstraint.h"


//#include "BroadphaseCollision/QueryDispatcher.h"
//#include "BroadphaseCollision/QueryBox.h"
//todo: change this to allow dynamic registration of types!

#ifdef WIN32
void DrawRasterizerLine(const float* from,const float* to,int color);
#endif


#include "ConstraintSolver/ContactConstraint.h"


#include <stdio.h>

#ifdef NEW_BULLET_VEHICLE_SUPPORT
class WrapperVehicle : public PHY_IVehicle
{

      RaycastVehicle*   m_vehicle;
      PHY_IPhysicsController* m_chassis;

public:

      WrapperVehicle(RaycastVehicle* vehicle,PHY_IPhysicsController* chassis)
            :m_vehicle(vehicle),
            m_chassis(chassis)
      {
      }

      RaycastVehicle*   GetVehicle()
      {
            return m_vehicle;
      }

      PHY_IPhysicsController* GetChassis()
      {
            return m_chassis;
      }

      virtual void      AddWheel(
            PHY_IMotionState* motionState,
            PHY__Vector3      connectionPoint,
            PHY__Vector3      downDirection,
            PHY__Vector3      axleDirection,
            float suspensionRestLength,
            float wheelRadius,
            bool hasSteering
            )
      {
            SimdVector3 connectionPointCS0(connectionPoint[0],connectionPoint[1],connectionPoint[2]);
            SimdVector3 wheelDirectionCS0(downDirection[0],downDirection[1],downDirection[2]);
            SimdVector3 wheelAxle(axleDirection[0],axleDirection[1],axleDirection[2]);


            WheelInfo& info = m_vehicle->AddWheel(connectionPointCS0,wheelDirectionCS0,wheelAxle,
                  suspensionRestLength,wheelRadius,gTuning,hasSteering);
            info.m_clientInfo = motionState;

      }

      void  SyncWheels()
      {
            int numWheels = GetNumWheels();
            int i;
            for (i=0;i<numWheels;i++)
            {
                  WheelInfo& info = m_vehicle->GetWheelInfo(i);
                  PHY_IMotionState* motionState = (PHY_IMotionState*)info.m_clientInfo ;
                  m_vehicle->UpdateWheelTransform(i);
                  SimdTransform trans = m_vehicle->GetWheelTransformWS(i);
                  SimdQuaternion orn = trans.getRotation();
                  const SimdVector3& pos = trans.getOrigin();
                  motionState->setWorldOrientation(orn.x(),orn.y(),orn.z(),orn[3]);
                  motionState->setWorldPosition(pos.x(),pos.y(),pos.z());

            }
      }

      virtual     int         GetNumWheels() const
      {
            return m_vehicle->GetNumWheels();
      }

      virtual void      GetWheelPosition(int wheelIndex,float& posX,float& posY,float& posZ) const
      {
            SimdTransform     trans = m_vehicle->GetWheelTransformWS(wheelIndex);
            posX = trans.getOrigin().x();
            posY = trans.getOrigin().y();
            posZ = trans.getOrigin().z();
      }
      virtual void      GetWheelOrientationQuaternion(int wheelIndex,float& quatX,float& quatY,float& quatZ,float& quatW) const
      {
            SimdTransform     trans = m_vehicle->GetWheelTransformWS(wheelIndex);
            SimdQuaternion quat = trans.getRotation();
            SimdMatrix3x3 orn2(quat);

            quatX = trans.getRotation().x();
            quatY = trans.getRotation().y();
            quatZ = trans.getRotation().z();
            quatW = trans.getRotation()[3];


            //printf("test");


      }

      virtual float     GetWheelRotation(int wheelIndex) const
      {
            float rotation = 0.f;

            if ((wheelIndex>=0) && (wheelIndex< m_vehicle->GetNumWheels()))
            {
                  WheelInfo& info = m_vehicle->GetWheelInfo(wheelIndex);
                  rotation = info.m_rotation;
            }
            return rotation;

      }



      virtual int GetUserConstraintId() const
      {
            return m_vehicle->GetUserConstraintId();
      }

      virtual int GetUserConstraintType() const
      {
            return m_vehicle->GetUserConstraintType();
      }

      virtual     void  SetSteeringValue(float steering,int wheelIndex)
      {
            m_vehicle->SetSteeringValue(steering,wheelIndex);
      }

      virtual     void  ApplyEngineForce(float force,int wheelIndex)
      {
            m_vehicle->ApplyEngineForce(force,wheelIndex);
      }

      virtual     void  ApplyBraking(float braking,int wheelIndex)
      {
            if ((wheelIndex>=0) && (wheelIndex< m_vehicle->GetNumWheels()))
            {
                  WheelInfo& info = m_vehicle->GetWheelInfo(wheelIndex);
                  info.m_brake = braking;
            }
      }

      virtual     void  SetWheelFriction(float friction,int wheelIndex)
      {
            if ((wheelIndex>=0) && (wheelIndex< m_vehicle->GetNumWheels()))
            {
                  WheelInfo& info = m_vehicle->GetWheelInfo(wheelIndex);
                  info.m_frictionSlip = friction;
            }

      }

      virtual     void  SetSuspensionStiffness(float suspensionStiffness,int wheelIndex)
      {
            if ((wheelIndex>=0) && (wheelIndex< m_vehicle->GetNumWheels()))
            {
                  WheelInfo& info = m_vehicle->GetWheelInfo(wheelIndex);
                  info.m_suspensionStiffness = suspensionStiffness;

            }
      }

      virtual     void  SetSuspensionDamping(float suspensionDamping,int wheelIndex)
      {
            if ((wheelIndex>=0) && (wheelIndex< m_vehicle->GetNumWheels()))
            {
                  WheelInfo& info = m_vehicle->GetWheelInfo(wheelIndex);
                  info.m_wheelsDampingRelaxation = suspensionDamping;
            }
      }

      virtual     void  SetSuspensionCompression(float suspensionCompression,int wheelIndex)
      {
            if ((wheelIndex>=0) && (wheelIndex< m_vehicle->GetNumWheels()))
            {
                  WheelInfo& info = m_vehicle->GetWheelInfo(wheelIndex);
                  info.m_wheelsDampingCompression = suspensionCompression;
            }
      }



      virtual     void  SetRollInfluence(float rollInfluence,int wheelIndex)
      {
            if ((wheelIndex>=0) && (wheelIndex< m_vehicle->GetNumWheels()))
            {
                  WheelInfo& info = m_vehicle->GetWheelInfo(wheelIndex);
                  info.m_rollInfluence = rollInfluence;
            }
      }



};
#endif //NEW_BULLET_VEHICLE_SUPPORT



static void DrawAabb(IDebugDraw* debugDrawer,const SimdVector3& from,const SimdVector3& to,const SimdVector3& color)
{
      SimdVector3 halfExtents = (to-from)* 0.5f;
      SimdVector3 center = (to+from) *0.5f;
      int i,j;

      SimdVector3 edgecoord(1.f,1.f,1.f),pa,pb;
      for (i=0;i<4;i++)
      {
            for (j=0;j<3;j++)
            {
                  pa = SimdVector3(edgecoord[0]*halfExtents[0], edgecoord[1]*halfExtents[1],          
                        edgecoord[2]*halfExtents[2]);
                  pa+=center;

                  int othercoord = j%3;
                  edgecoord[othercoord]*=-1.f;
                  pb = SimdVector3(edgecoord[0]*halfExtents[0], edgecoord[1]*halfExtents[1],    
                        edgecoord[2]*halfExtents[2]);
                  pb+=center;

                  debugDrawer->DrawLine(pa,pb,color);
            }
            edgecoord = SimdVector3(-1.f,-1.f,-1.f);
            if (i<3)
                  edgecoord[i]*=-1.f;
      }


}






CcdPhysicsEnvironment::CcdPhysicsEnvironment(CollisionDispatcher* dispatcher,BroadphaseInterface* broadphase)
:m_scalingPropagated(false),
m_numIterations(10),
m_numTimeSubSteps(1),
m_ccdMode(0),
m_solverType(-1),
m_profileTimings(0),
m_enableSatCollisionDetection(false)
{

      for (int i=0;i<PHY_NUM_RESPONSE;i++)
      {
            m_triggerCallbacks[i] = 0;
      }
      if (!dispatcher)
            dispatcher = new CollisionDispatcher();


      if(!broadphase)
      {

            //todo: calculate/let user specify this world sizes
            SimdVector3 worldMin(-10000,-10000,-10000);
            SimdVector3 worldMax(10000,10000,10000);

            broadphase = new AxisSweep3(worldMin,worldMax);

            //broadphase = new SimpleBroadphase();
      }


      setSolverType(1);//issues with quickstep and memory allocations

      m_collisionWorld = new CollisionWorld(dispatcher,broadphase);

      m_debugDrawer = 0;
      m_gravity = SimdVector3(0.f,-10.f,0.f);


}

void  CcdPhysicsEnvironment::addCcdPhysicsController(CcdPhysicsController* ctrl)
{
      RigidBody* body = ctrl->GetRigidBody();

      //this m_userPointer is just used for triggers, see CallbackTriggers
      body->m_userPointer = ctrl;

      body->setGravity( m_gravity );
      m_controllers.push_back(ctrl);

      m_collisionWorld->AddCollisionObject(body);

      assert(body->m_broadphaseHandle);

      BroadphaseInterface* scene =  GetBroadphase();


      CollisionShape* shapeinterface = ctrl->GetCollisionShape();

      assert(shapeinterface);

      const SimdTransform& t = ctrl->GetRigidBody()->getCenterOfMassTransform();


      SimdPoint3 minAabb,maxAabb;

      shapeinterface->GetAabb(t,minAabb,maxAabb);

      float timeStep = 0.02f;


      //extent it with the motion

      SimdVector3 linMotion = body->getLinearVelocity()*timeStep;

      float maxAabbx = maxAabb.getX();
      float maxAabby = maxAabb.getY();
      float maxAabbz = maxAabb.getZ();
      float minAabbx = minAabb.getX();
      float minAabby = minAabb.getY();
      float minAabbz = minAabb.getZ();

      if (linMotion.x() > 0.f)
            maxAabbx += linMotion.x(); 
      else
            minAabbx += linMotion.x();
      if (linMotion.y() > 0.f)
            maxAabby += linMotion.y(); 
      else
            minAabby += linMotion.y();
      if (linMotion.z() > 0.f)
            maxAabbz += linMotion.z(); 
      else
            minAabbz += linMotion.z();


      minAabb = SimdVector3(minAabbx,minAabby,minAabbz);
      maxAabb = SimdVector3(maxAabbx,maxAabby,maxAabbz);




}

void  CcdPhysicsEnvironment::removeCcdPhysicsController(CcdPhysicsController* ctrl)
{

      //also remove constraint

      {
            std::vector<TypedConstraint*>::iterator i;

            for (i=m_constraints.begin();
                  !(i==m_constraints.end()); i++)
            {
                  TypedConstraint* constraint = (*i);
                  if  ((&constraint->GetRigidBodyA() == ctrl->GetRigidBody() ||
                        (&constraint->GetRigidBodyB() == ctrl->GetRigidBody())))
                  {
                        removeConstraint(constraint->GetUserConstraintId());
                        //only 1 constraint per constroller
                        break;
                  }
            }
      }

      {
            std::vector<TypedConstraint*>::iterator i;

            for (i=m_constraints.begin();
                  !(i==m_constraints.end()); i++)
            {
                  TypedConstraint* constraint = (*i);
                  if  ((&constraint->GetRigidBodyA() == ctrl->GetRigidBody() ||
                        (&constraint->GetRigidBodyB() == ctrl->GetRigidBody())))
                  {
                        removeConstraint(constraint->GetUserConstraintId());
                        //only 1 constraint per constroller
                        break;
                  }
            }
      }


      m_collisionWorld->RemoveCollisionObject(ctrl->GetRigidBody());


      {
            std::vector<CcdPhysicsController*>::iterator i =
                  std::find(m_controllers.begin(), m_controllers.end(), ctrl);
            if (!(i == m_controllers.end()))
            {
                  std::swap(*i, m_controllers.back());
                  m_controllers.pop_back();
            }
      }

      //remove it from the triggers
      {
            std::vector<CcdPhysicsController*>::iterator i =
                  std::find(m_triggerControllers.begin(), m_triggerControllers.end(), ctrl);
            if (!(i == m_triggerControllers.end()))
            {
                  std::swap(*i, m_triggerControllers.back());
                  m_triggerControllers.pop_back();
            }
      }


}


void  CcdPhysicsEnvironment::beginFrame()
{

}


00504 bool  CcdPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep)
{
      //don't simulate without timesubsteps
      if (m_numTimeSubSteps<1)
            return true;

      //printf("proceedDeltaTime\n");
      

#ifdef USE_QUICKPROF
      //toggle Profiler
      if ( m_debugDrawer->GetDebugMode() & IDebugDraw::DBG_ProfileTimings)
      {
            if (!m_profileTimings)
            {
                  m_profileTimings = 1;
                  // To disable profiling, simply comment out the following line.
                  static int counter = 0;

                  char filename[128];
                  sprintf(filename,"quickprof_bullet_timings%i.csv",counter++);
                  Profiler::init(filename, Profiler::BLOCK_CYCLE_SECONDS);//BLOCK_TOTAL_MICROSECONDS

            }
      } else
      {
            if (m_profileTimings)
            {
                  m_profileTimings = 0;
                  Profiler::destroy();
            }
      }
#endif //USE_QUICKPROF



      if (!SimdFuzzyZero(timeStep))
      {
            
            {
                  //do the kinematic calculation here, over the full timestep
                  std::vector<CcdPhysicsController*>::iterator i;
                  for (i=m_controllers.begin();
                                    !(i==m_controllers.end()); i++)
                  {

                                    CcdPhysicsController* ctrl = *i;

                                    SimdTransform predictedTrans;
                                    RigidBody* body = ctrl->GetRigidBody();
                                    if (body->GetActivationState() != ISLAND_SLEEPING)
                                    {

                                          if (body->IsStatic())
                                          {
                                                //to calculate velocities next frame
                                                body->saveKinematicState(timeStep);
                                          }
                                    }
                  }
            }


            int i;
            float subTimeStep = timeStep / float(m_numTimeSubSteps);

            for (i=0;i<this->m_numTimeSubSteps;i++)
            {
                  proceedDeltaTimeOneStep(subTimeStep);
            }
      } else
      {
            //todo: interpolate
      }

      return true;
}













/// Perform an integration step of duration 'timeStep'.
00595 bool  CcdPhysicsEnvironment::proceedDeltaTimeOneStep(float timeStep)
{


      //printf("CcdPhysicsEnvironment::proceedDeltaTime\n");

      if (SimdFuzzyZero(timeStep))
            return true;

      if (m_debugDrawer)
      {
            gDisableDeactivation = (m_debugDrawer->GetDebugMode() & IDebugDraw::DBG_NoDeactivation);
      }


#ifdef USE_QUICKPROF
      Profiler::beginBlock("SyncMotionStates");
#endif //USE_QUICKPROF


      //this is needed because scaling is not known in advance, and scaling has to propagate to the shape
      if (!m_scalingPropagated)
      {
            SyncMotionStates(timeStep);
            m_scalingPropagated = true;
      }


#ifdef USE_QUICKPROF
      Profiler::endBlock("SyncMotionStates");

      Profiler::beginBlock("predictIntegratedTransform");
#endif //USE_QUICKPROF

      {
            //          std::vector<CcdPhysicsController*>::iterator i;



            int k;
            for (k=0;k<GetNumControllers();k++)
            {
                  CcdPhysicsController* ctrl = m_controllers[k];
                  //          SimdTransform predictedTrans;
                  RigidBody* body = ctrl->GetRigidBody();
                  if (body->IsActive())
                  {
                        if (!body->IsStatic())
                        {
                              body->applyForces( timeStep);
                              body->integrateVelocities( timeStep);
                              body->predictIntegratedTransform(timeStep,body->m_interpolationWorldTransform);
                        }
                  }

            }
      }

#ifdef USE_QUICKPROF
      Profiler::endBlock("predictIntegratedTransform");
#endif //USE_QUICKPROF

      BroadphaseInterface*    scene = GetBroadphase();


      //
      // collision detection (?)
      //


#ifdef USE_QUICKPROF
      Profiler::beginBlock("DispatchAllCollisionPairs");
#endif //USE_QUICKPROF


      int numsubstep = m_numIterations;


      DispatcherInfo dispatchInfo;
      dispatchInfo.m_timeStep = timeStep;
      dispatchInfo.m_stepCount = 0;
      dispatchInfo.m_enableSatConvex = m_enableSatCollisionDetection;

      scene->DispatchAllCollisionPairs(*GetDispatcher(),dispatchInfo);///numsubstep,g);


#ifdef USE_QUICKPROF
      Profiler::endBlock("DispatchAllCollisionPairs");
#endif //USE_QUICKPROF


      int numRigidBodies = m_controllers.size();

      m_collisionWorld->UpdateActivationState();

      {
            int i;
            int numConstraints = m_constraints.size();
            for (i=0;i< numConstraints ; i++ )
            {
                  TypedConstraint* constraint = m_constraints[i];

                  const RigidBody* colObj0 = &constraint->GetRigidBodyA();
                  const RigidBody* colObj1 = &constraint->GetRigidBodyB();
                  
                  if (((colObj0) && ((colObj0)->mergesSimulationIslands())) &&
                                    ((colObj1) && ((colObj1)->mergesSimulationIslands())))
                  {
                        if (colObj0->IsActive() || colObj1->IsActive())
                        {
                              GetDispatcher()->GetUnionFind().unite((colObj0)->m_islandTag1,
                                    (colObj1)->m_islandTag1);
                        }
                  }
            }
      }

      m_collisionWorld->StoreIslandActivationState();



      //contacts
#ifdef USE_QUICKPROF
      Profiler::beginBlock("SolveConstraint");
#endif //USE_QUICKPROF


      //solve the regular constraints (point 2 point, hinge, etc)

      for (int g=0;g<numsubstep;g++)
      {
            //
            // constraint solving
            //


            int i;
            int numConstraints = m_constraints.size();

            //point to point constraints
            for (i=0;i< numConstraints ; i++ )
            {
                  TypedConstraint* constraint = m_constraints[i];

                  constraint->BuildJacobian();
                  constraint->SolveConstraint( timeStep );

            }


      }

#ifdef USE_QUICKPROF
      Profiler::endBlock("SolveConstraint");
#endif //USE_QUICKPROF

      //solve the vehicles

#ifdef NEW_BULLET_VEHICLE_SUPPORT
      //vehicles
      int numVehicles = m_wrapperVehicles.size();
      for (int i=0;i<numVehicles;i++)
      {
            WrapperVehicle* wrapperVehicle = m_wrapperVehicles[i];
            RaycastVehicle* vehicle = wrapperVehicle->GetVehicle();
            vehicle->UpdateVehicle( timeStep);
      }
#endif //NEW_BULLET_VEHICLE_SUPPORT


      struct InplaceSolverIslandCallback : public CollisionDispatcher::IslandCallback
      {

            ContactSolverInfo& m_solverInfo;
            ConstraintSolver* m_solver;
            IDebugDraw* m_debugDrawer;

            InplaceSolverIslandCallback(
                  ContactSolverInfo& solverInfo,
                  ConstraintSolver* solver,
                  IDebugDraw* debugDrawer)
                  :m_solverInfo(solverInfo),
                  m_solver(solver),
                  m_debugDrawer(debugDrawer)
            {

            }

            virtual     void  ProcessIsland(PersistentManifold**  manifolds,int numManifolds)
            {
                  m_solver->SolveGroup( manifolds, numManifolds,m_solverInfo,m_debugDrawer);
            }

      };


      m_solverInfo.m_friction = 0.9f;
      m_solverInfo.m_numIterations = m_numIterations;
      m_solverInfo.m_timeStep = timeStep;
      m_solverInfo.m_restitution = 0.f;//m_restitution;

      InplaceSolverIslandCallback   solverCallback(
            m_solverInfo,
            m_solver,
            m_debugDrawer);

#ifdef USE_QUICKPROF
      Profiler::beginBlock("BuildAndProcessIslands");
#endif //USE_QUICKPROF

      /// solve all the contact points and contact friction
      GetDispatcher()->BuildAndProcessIslands(m_collisionWorld->GetCollisionObjectArray(),&solverCallback);

#ifdef USE_QUICKPROF
      Profiler::endBlock("BuildAndProcessIslands");

      Profiler::beginBlock("CallbackTriggers");
#endif //USE_QUICKPROF

      CallbackTriggers();

#ifdef USE_QUICKPROF
      Profiler::endBlock("CallbackTriggers");


      Profiler::beginBlock("proceedToTransform");

#endif //USE_QUICKPROF
      {



            {

                  
                  
                  UpdateAabbs(timeStep);


                  float toi = 1.f;



                  if (m_ccdMode == 3)
                  {
                        DispatcherInfo dispatchInfo;
                        dispatchInfo.m_timeStep = timeStep;
                        dispatchInfo.m_stepCount = 0;
                        dispatchInfo.m_dispatchFunc = DispatcherInfo::DISPATCH_CONTINUOUS;

                        scene->DispatchAllCollisionPairs( *GetDispatcher(),dispatchInfo);///numsubstep,g);
                        toi = dispatchInfo.m_timeOfImpact;

                  }

                  

                  //
                  // integrating solution
                  //

                  {
                        
                        std::vector<CcdPhysicsController*>::iterator i;

                        for (i=m_controllers.begin();
                              !(i==m_controllers.end()); i++)
                        {

                              CcdPhysicsController* ctrl = *i;

                              SimdTransform predictedTrans;
                              RigidBody* body = ctrl->GetRigidBody();
                              
                              if (body->IsActive())
                              {

                                    if (!body->IsStatic())
                                    {
                                          body->predictIntegratedTransform(timeStep*      toi, predictedTrans);
                                          body->proceedToTransform( predictedTrans);
                                    }

                              }
                        }

                  }





                  //
                  // disable sleeping physics objects
                  //

                  std::vector<CcdPhysicsController*> m_sleepingControllers;

                  std::vector<CcdPhysicsController*>::iterator i;

                  for (i=m_controllers.begin();
                        !(i==m_controllers.end()); i++)
                  {
                        CcdPhysicsController* ctrl = (*i);
                        RigidBody* body = ctrl->GetRigidBody();

                        ctrl->UpdateDeactivation(timeStep);


                        if (ctrl->wantsSleeping())
                        {
                              if (body->GetActivationState() == ACTIVE_TAG)
                                    body->SetActivationState( WANTS_DEACTIVATION );
                        } else
                        {
                              if (body->GetActivationState() != DISABLE_DEACTIVATION)
                                    body->SetActivationState( ACTIVE_TAG );
                        }

                        if (useIslands)
                        {
                              if (body->GetActivationState() == ISLAND_SLEEPING)
                              {
                                    m_sleepingControllers.push_back(ctrl);
                              }
                        } else
                        {
                              if (ctrl->wantsSleeping())
                              {
                                    m_sleepingControllers.push_back(ctrl);
                              }
                        }
                  }




            }


#ifdef USE_QUICKPROF
            Profiler::endBlock("proceedToTransform");

            Profiler::beginBlock("SyncMotionStates");
#endif //USE_QUICKPROF

            SyncMotionStates(timeStep);

#ifdef USE_QUICKPROF
            Profiler::endBlock("SyncMotionStates");

            Profiler::endProfilingCycle();
#endif //USE_QUICKPROF


#ifdef NEW_BULLET_VEHICLE_SUPPORT
            //sync wheels for vehicles
            int numVehicles = m_wrapperVehicles.size();
            for (int i=0;i<numVehicles;i++)
            {
                  WrapperVehicle* wrapperVehicle = m_wrapperVehicles[i];

                  wrapperVehicle->SyncWheels();
            }
#endif //NEW_BULLET_VEHICLE_SUPPORT
      }

      return true;
}

00965 void        CcdPhysicsEnvironment::setDebugMode(int debugMode)
{
      if (m_debugDrawer){
            m_debugDrawer->SetDebugMode(debugMode);
      }
}

00972 void        CcdPhysicsEnvironment::setNumIterations(int numIter)
{
      m_numIterations = numIter;
}
00976 void        CcdPhysicsEnvironment::setDeactivationTime(float dTime)
{
      gDeactivationTime = dTime;
}
00980 void        CcdPhysicsEnvironment::setDeactivationLinearTreshold(float linTresh)
{
      gLinearSleepingTreshold = linTresh;
}
00984 void        CcdPhysicsEnvironment::setDeactivationAngularTreshold(float angTresh) 
{
      gAngularSleepingTreshold = angTresh;
}
00988 void        CcdPhysicsEnvironment::setContactBreakingTreshold(float contactBreakingTreshold)
{
      gContactBreakingTreshold = contactBreakingTreshold;

}


00995 void        CcdPhysicsEnvironment::setCcdMode(int ccdMode)
{
      m_ccdMode = ccdMode;
}


01001 void        CcdPhysicsEnvironment::setSolverSorConstant(float sor)
{
      m_solverInfo.m_sor = sor;
}

01006 void        CcdPhysicsEnvironment::setSolverTau(float tau)
{
      m_solverInfo.m_tau = tau;
}
01010 void        CcdPhysicsEnvironment::setSolverDamping(float damping)
{
      m_solverInfo.m_damping = damping;
}


01016 void        CcdPhysicsEnvironment::setLinearAirDamping(float damping)
{
      gLinearAirDamping = damping;
}

01021 void        CcdPhysicsEnvironment::setUseEpa(bool epa)
{
      gUseEpa = epa;
}

01026 void        CcdPhysicsEnvironment::setSolverType(int solverType)
{

      switch (solverType)
      {
      case 1:
            {
                  if (m_solverType != solverType)
                  {

                        m_solver = new SimpleConstraintSolver();

                        break;
                  }
            }

      case 0:
      default:
            if (m_solverType != solverType)
            {
                  m_solver = new OdeConstraintSolver();

                  break;
            }

      };

      m_solverType = solverType ;
}





void  CcdPhysicsEnvironment::SyncMotionStates(float timeStep)
{
      std::vector<CcdPhysicsController*>::iterator i;

      //
      // synchronize the physics and graphics transformations
      //

      for (i=m_controllers.begin();
            !(i==m_controllers.end()); i++)
      {
            CcdPhysicsController* ctrl = (*i);
            ctrl->SynchronizeMotionStates(timeStep);

      }

}
void        CcdPhysicsEnvironment::setGravity(float x,float y,float z)
{
      m_gravity = SimdVector3(x,y,z);

      std::vector<CcdPhysicsController*>::iterator i;

      //todo: review this gravity stuff
      for (i=m_controllers.begin();
            !(i==m_controllers.end()); i++)
      {

            CcdPhysicsController* ctrl = (*i);
            ctrl->GetRigidBody()->setGravity(m_gravity);

      }
}


#ifdef NEW_BULLET_VEHICLE_SUPPORT

class DefaultVehicleRaycaster : public VehicleRaycaster
{
      CcdPhysicsEnvironment* m_physEnv;
      PHY_IPhysicsController* m_chassis;

public:
      DefaultVehicleRaycaster(CcdPhysicsEnvironment* physEnv,PHY_IPhysicsController* chassis):
        m_physEnv(physEnv),
              m_chassis(chassis)
        {
        }

        /*  struct VehicleRaycasterResult
        {
        VehicleRaycasterResult() :m_distFraction(-1.f){};
        SimdVector3     m_hitPointInWorld;
        SimdVector3     m_hitNormalInWorld;
        SimdScalar      m_distFraction;
        };
        */
        virtual void* CastRay(const SimdVector3& from,const SimdVector3& to, VehicleRaycasterResult& result)
        {


              float hit[3];
              float normal[3];

              PHY_IPhysicsController*     ignore = m_chassis;
              void* hitObject = m_physEnv->rayTest(ignore,from.x(),from.y(),from.z(),to.x(),to.y(),to.z(),hit[0],hit[1],hit[2],normal[0],normal[1],normal[2]);
              if (hitObject)
              {
                    result.m_hitPointInWorld[0] = hit[0];
                    result.m_hitPointInWorld[1] = hit[1];
                    result.m_hitPointInWorld[2] = hit[2];
                    result.m_hitNormalInWorld[0] = normal[0];
                    result.m_hitNormalInWorld[1] = normal[1];
                    result.m_hitNormalInWorld[2] = normal[2];
                    result.m_hitNormalInWorld.normalize();
                    //calc fraction? or put it in the interface?
                    //calc for now

                    result.m_distFraction = (result.m_hitPointInWorld-from).length() / (to-from).length();
                    //some safety for 'explosion' due to sudden penetration of the full 'ray'
                    /*              if (result.m_distFraction<0.1)
                    {
                    printf("Vehicle Raycast: avoided instability due to penetration. Consider moving the connection points deeper inside vehicle chassis");
                    result.m_distFraction = 1.f;
                    hitObject = 0;
                    }
                    */

                    /*              if (result.m_distFraction>1.)
                    {
                    printf("Vehicle Raycast: avoided instability 1Consider moving the connection points deeper inside vehicle chassis");                    
                    result.m_distFraction = 1.f;
                    hitObject = 0;
                    }
                    */



              }
              //?
              return hitObject;
        }
};
#endif //NEW_BULLET_VEHICLE_SUPPORT

static int gConstraintUid = 1;

int               CcdPhysicsEnvironment::createConstraint(class PHY_IPhysicsController* ctrl0,class PHY_IPhysicsController* ctrl1,PHY_ConstraintType type,
                                                                              float pivotX,float pivotY,float pivotZ,
                                                                              float axisX,float axisY,float axisZ)
{


      CcdPhysicsController* c0 = (CcdPhysicsController*)ctrl0;
      CcdPhysicsController* c1 = (CcdPhysicsController*)ctrl1;

      RigidBody* rb0 = c0 ? c0->GetRigidBody() : 0;
      RigidBody* rb1 = c1 ? c1->GetRigidBody() : 0;

      ASSERT(rb0);

      SimdVector3 pivotInA(pivotX,pivotY,pivotZ);
      SimdVector3 pivotInB = rb1 ? rb1->getCenterOfMassTransform().inverse()(rb0->getCenterOfMassTransform()(pivotInA)) : pivotInA;
      SimdVector3 axisInA(axisX,axisY,axisZ);
      SimdVector3 axisInB = rb1 ? 
            (rb1->getCenterOfMassTransform().getBasis().inverse()*(rb0->getCenterOfMassTransform().getBasis() * -axisInA)) : 
      rb0->getCenterOfMassTransform().getBasis() * -axisInA;

      bool angularOnly = false;

      switch (type)
      {
      case PHY_POINT2POINT_CONSTRAINT:
            {

                  Point2PointConstraint* p2p = 0;

                  if (rb1)
                  {
                        p2p = new Point2PointConstraint(*rb0,
                              *rb1,pivotInA,pivotInB);
                  } else
                  {
                        p2p = new Point2PointConstraint(*rb0,
                              pivotInA);
                  }

                  m_constraints.push_back(p2p);
                  p2p->SetUserConstraintId(gConstraintUid++);
                  p2p->SetUserConstraintType(type);
                  //64 bit systems can't cast pointer to int. could use size_t instead.
                  return p2p->GetUserConstraintId();

                  break;
            }

      case PHY_ANGULAR_CONSTRAINT:
            angularOnly = true;

      case PHY_LINEHINGE_CONSTRAINT:
            {
                  HingeConstraint* hinge = 0;

                  if (rb1)
                  {
                        hinge = new HingeConstraint(
                              *rb0,
                              *rb1,pivotInA,pivotInB,axisInA,axisInB);


                  } else
                  {
                        hinge = new HingeConstraint(*rb0,
                              pivotInA,axisInA);

                  }
                  hinge->setAngularOnly(angularOnly);

                  m_constraints.push_back(hinge);
                  hinge->SetUserConstraintId(gConstraintUid++);
                  hinge->SetUserConstraintType(type);
                  //64 bit systems can't cast pointer to int. could use size_t instead.
                  return hinge->GetUserConstraintId();
                  break;
            }
#ifdef NEW_BULLET_VEHICLE_SUPPORT

      case PHY_VEHICLE_CONSTRAINT:
            {
                  RaycastVehicle::VehicleTuning* tuning = new RaycastVehicle::VehicleTuning();
                  RigidBody* chassis = rb0;
                  DefaultVehicleRaycaster* raycaster = new DefaultVehicleRaycaster(this,ctrl0);
                  RaycastVehicle* vehicle = new RaycastVehicle(*tuning,chassis,raycaster);
                  WrapperVehicle* wrapperVehicle = new WrapperVehicle(vehicle,ctrl0);
                  m_wrapperVehicles.push_back(wrapperVehicle);
                  vehicle->SetUserConstraintId(gConstraintUid++);
                  vehicle->SetUserConstraintType(type);
                  return vehicle->GetUserConstraintId();

                  break;
            };
#endif //NEW_BULLET_VEHICLE_SUPPORT

      default:
            {
            }
      };

      //RigidBody& rbA,RigidBody& rbB, const SimdVector3& pivotInA,const SimdVector3& pivotInB

      return 0;

}

float       CcdPhysicsEnvironment::getAppliedImpulse(int    constraintid)
{
      std::vector<TypedConstraint*>::iterator i;

      for (i=m_constraints.begin();
            !(i==m_constraints.end()); i++)
      {
            TypedConstraint* constraint = (*i);
            if (constraint->GetUserConstraintId() == constraintid)
            {
                  return constraint->GetAppliedImpulse();
            }
      }
      return 0.f;
}
void        CcdPhysicsEnvironment::removeConstraint(int     constraintId)
{
      std::vector<TypedConstraint*>::iterator i;

      for (i=m_constraints.begin();
            !(i==m_constraints.end()); i++)
      {
            TypedConstraint* constraint = (*i);
            if (constraint->GetUserConstraintId() == constraintId)
            {
                  //activate objects
                  if (constraint->GetRigidBodyA().mergesSimulationIslands())
                        constraint->GetRigidBodyA().activate();
                  if (constraint->GetRigidBodyB().mergesSimulationIslands())
                        constraint->GetRigidBodyB().activate();

                  std::swap(*i, m_constraints.back());

                  
                  m_constraints.pop_back();
                  break;
            }
      }

}


      struct      FilterClosestRayResultCallback : public CollisionWorld::ClosestRayResultCallback
      {
            PHY_IPhysicsController* m_ignoreClient;

            FilterClosestRayResultCallback (PHY_IPhysicsController* ignoreClient,const SimdVector3& rayFrom,const SimdVector3& rayTo)
                  : CollisionWorld::ClosestRayResultCallback(rayFrom,rayTo),
                  m_ignoreClient(ignoreClient)
            {

            }

            virtual ~FilterClosestRayResultCallback()
            {
            }

            virtual     float AddSingleResult(const CollisionWorld::LocalRayResult& rayResult)
            {
                  CcdPhysicsController* curHit = static_cast<CcdPhysicsController*>(rayResult.m_collisionObject->m_userPointer);
                  //ignore client...
                  if (curHit != m_ignoreClient)
                  {           
                        //if valid
                        return ClosestRayResultCallback::AddSingleResult(rayResult);
                  }
                  return m_closestHitFraction;
            }

      };

PHY_IPhysicsController* CcdPhysicsEnvironment::rayTest(PHY_IPhysicsController* ignoreClient, float fromX,float fromY,float fromZ, float toX,float toY,float toZ, 
                                                                                 float& hitX,float& hitY,float& hitZ,float& normalX,float& normalY,float& normalZ)
{


      float minFraction = 1.f;

      SimdVector3 rayFrom(fromX,fromY,fromZ);
      SimdVector3 rayTo(toX,toY,toZ);

      
      if (m_debugDrawer->GetDebugMode() & IDebugDraw::DBG_DrawAabb)     
      {
            SimdVector3 color (1,0,0);
            m_debugDrawer->DrawLine(rayFrom,rayTo,color);
      }

      SimdVector3 hitPointWorld,normalWorld;

      //Either Ray Cast with or without filtering

      //CollisionWorld::ClosestRayResultCallback rayCallback(rayFrom,rayTo);
      FilterClosestRayResultCallback       rayCallback(ignoreClient,rayFrom,rayTo);


      PHY_IPhysicsController* nearestHit = 0;

      m_collisionWorld->RayTest(rayFrom,rayTo,rayCallback);
      if (rayCallback.HasHit())
      {
            nearestHit = static_cast<CcdPhysicsController*>(rayCallback.m_collisionObject->m_userPointer);
            hitX =      rayCallback.m_hitPointWorld.getX();
            hitY =      rayCallback.m_hitPointWorld.getY();
            hitZ =      rayCallback.m_hitPointWorld.getZ();
            if (rayCallback.m_hitNormalWorld.length2() > SIMD_EPSILON)
            {
                  rayCallback.m_hitNormalWorld.normalize();
            }

            normalX = rayCallback.m_hitNormalWorld.getX();
            normalY = rayCallback.m_hitNormalWorld.getY();
            normalZ = rayCallback.m_hitNormalWorld.getZ();
            
            if (m_debugDrawer->GetDebugMode() & IDebugDraw::DBG_DrawAabb)     
            {
                  SimdVector3 colorNormal(0,0,1);
                  m_debugDrawer->DrawLine(rayCallback.m_hitPointWorld,rayCallback.m_hitPointWorld+rayCallback.m_hitNormalWorld,colorNormal);
            
                  SimdVector3 color (0,1,0);
                  m_debugDrawer->DrawLine(rayFrom,rayCallback.m_hitPointWorld,color);
                  
            
            }


      }     


      return nearestHit;
}



int   CcdPhysicsEnvironment::getNumContactPoints()
{
      return 0;
}

void CcdPhysicsEnvironment::getContactPoint(int i,float& hitX,float& hitY,float& hitZ,float& normalX,float& normalY,float& normalZ)
{

}




BroadphaseInterface*    CcdPhysicsEnvironment::GetBroadphase()
{ 
      return m_collisionWorld->GetBroadphase(); 
}



const CollisionDispatcher* CcdPhysicsEnvironment::GetDispatcher() const
{
      return m_collisionWorld->GetDispatcher();
}

CollisionDispatcher* CcdPhysicsEnvironment::GetDispatcher()
{
      return m_collisionWorld->GetDispatcher();
}

CcdPhysicsEnvironment::~CcdPhysicsEnvironment()
{

#ifdef NEW_BULLET_VEHICLE_SUPPORT
      m_wrapperVehicles.clear();
#endif //NEW_BULLET_VEHICLE_SUPPORT

      //m_broadphase->DestroyScene();
      //delete broadphase ? release reference on broadphase ?

      //first delete scene, then dispatcher, because pairs have to release manifolds on the dispatcher
      //delete m_dispatcher;
      delete m_collisionWorld;

}


int   CcdPhysicsEnvironment::GetNumControllers()
{
      return m_controllers.size();
}


CcdPhysicsController* CcdPhysicsEnvironment::GetPhysicsController( int index)
{
      return m_controllers[index];
}


int   CcdPhysicsEnvironment::GetNumManifolds() const
{
      return GetDispatcher()->GetNumManifolds();
}

const PersistentManifold*     CcdPhysicsEnvironment::GetManifold(int index) const
{
      return GetDispatcher()->GetManifoldByIndexInternal(index);
}

TypedConstraint*  CcdPhysicsEnvironment::getConstraintById(int constraintId)
{
      int numConstraint = m_constraints.size();
      int i;
      for (i=0;i<numConstraint;i++)
      {
            TypedConstraint* constraint = m_constraints[i];
            if (constraint->GetUserConstraintId()==constraintId)
            {
                  return constraint;
            }
      }
      return 0;
}


void CcdPhysicsEnvironment::addSensor(PHY_IPhysicsController* ctrl)
{

      CcdPhysicsController* ctrl1 = (CcdPhysicsController* )ctrl;
      std::vector<CcdPhysicsController*>::iterator i =
            std::find(m_controllers.begin(), m_controllers.end(), ctrl);
      if ((i == m_controllers.end()))
      {
            addCcdPhysicsController(ctrl1);
      }

      requestCollisionCallback(ctrl);
      //printf("addSensor\n");
}

void CcdPhysicsEnvironment::removeCollisionCallback(PHY_IPhysicsController* ctrl)
{
      std::vector<CcdPhysicsController*>::iterator i =
            std::find(m_triggerControllers.begin(), m_triggerControllers.end(), ctrl);
      if (!(i == m_triggerControllers.end()))
      {
            std::swap(*i, m_triggerControllers.back());
            m_triggerControllers.pop_back();
      }
}


void CcdPhysicsEnvironment::removeSensor(PHY_IPhysicsController* ctrl)
{
      removeCollisionCallback(ctrl);
      //printf("removeSensor\n");
}
void CcdPhysicsEnvironment::addTouchCallback(int response_class, PHY_ResponseCallback callback, void *user)
{
      /*    printf("addTouchCallback\n(response class = %i)\n",response_class);

      //map PHY_ convention into SM_ convention
      switch (response_class)
      {
      case  PHY_FH_RESPONSE:
      printf("PHY_FH_RESPONSE\n");
      break;
      case PHY_SENSOR_RESPONSE:
      printf("PHY_SENSOR_RESPONSE\n");
      break;
      case PHY_CAMERA_RESPONSE:
      printf("PHY_CAMERA_RESPONSE\n");
      break;
      case PHY_OBJECT_RESPONSE:
      printf("PHY_OBJECT_RESPONSE\n");
      break;
      case PHY_STATIC_RESPONSE:
      printf("PHY_STATIC_RESPONSE\n");
      break;
      default:
      assert(0);
      return;
      }
      */

      m_triggerCallbacks[response_class] = callback;
      m_triggerCallbacksUserPtrs[response_class] = user;

}
void CcdPhysicsEnvironment::requestCollisionCallback(PHY_IPhysicsController* ctrl)
{
      CcdPhysicsController* ccdCtrl = static_cast<CcdPhysicsController*>(ctrl);

      //printf("requestCollisionCallback\n");
      m_triggerControllers.push_back(ccdCtrl);
}


void  CcdPhysicsEnvironment::CallbackTriggers()
{
      CcdPhysicsController* ctrl0=0,*ctrl1=0;

      if (m_triggerCallbacks[PHY_OBJECT_RESPONSE])
      {
            //walk over all overlapping pairs, and if one of the involved bodies is registered for trigger callback, perform callback
            int numManifolds = m_collisionWorld->GetDispatcher()->GetNumManifolds();
            for (int i=0;i<numManifolds;i++)
            {
                  PersistentManifold* manifold = m_collisionWorld->GetDispatcher()->GetManifoldByIndexInternal(i);
                  int numContacts = manifold->GetNumContacts();
                  if (numContacts)
                  {
                        RigidBody* obj0 = static_cast<RigidBody* >(manifold->GetBody0());
                        RigidBody* obj1 = static_cast<RigidBody* >(manifold->GetBody1());

                        //m_userPointer is set in 'addPhysicsController
                        CcdPhysicsController* ctrl0 = static_cast<CcdPhysicsController*>(obj0->m_userPointer);
                        CcdPhysicsController* ctrl1 = static_cast<CcdPhysicsController*>(obj1->m_userPointer);

                        std::vector<CcdPhysicsController*>::iterator i =
                              std::find(m_triggerControllers.begin(), m_triggerControllers.end(), ctrl0);
                        if (i == m_triggerControllers.end())
                        {
                              i = std::find(m_triggerControllers.begin(), m_triggerControllers.end(), ctrl1);
                        }

                        if (!(i == m_triggerControllers.end()))
                        {
                              m_triggerCallbacks[PHY_OBJECT_RESPONSE](m_triggerCallbacksUserPtrs[PHY_OBJECT_RESPONSE],
                                    ctrl0,ctrl1,0);
                        }
                  }
            }



      }

}






#ifdef NEW_BULLET_VEHICLE_SUPPORT

//complex constraint for vehicles
PHY_IVehicle*     CcdPhysicsEnvironment::getVehicleConstraint(int constraintId)
{
      int i;

      int numVehicles = m_wrapperVehicles.size();
      for (i=0;i<numVehicles;i++)
      {
            WrapperVehicle* wrapperVehicle = m_wrapperVehicles[i];
            if (wrapperVehicle->GetVehicle()->GetUserConstraintId() == constraintId)
                  return wrapperVehicle;
      }

      return 0;
}

#endif //NEW_BULLET_VEHICLE_SUPPORT



void  CcdPhysicsEnvironment::UpdateAabbs(float  timeStep)
{
      std::vector<CcdPhysicsController*>::iterator i;
      BroadphaseInterface* scene =  GetBroadphase();

      //
                  // update aabbs, only for moving objects (!)
                  //
                  for (i=m_controllers.begin();
                        !(i==m_controllers.end()); i++)
                  {
                        CcdPhysicsController* ctrl = (*i);
                        RigidBody* body = ctrl->GetRigidBody();


                        SimdPoint3 minAabb,maxAabb;
                        CollisionShape* shapeinterface = ctrl->GetCollisionShape();



                        shapeinterface->CalculateTemporalAabb(body->getCenterOfMassTransform(),
                              body->getLinearVelocity(),
                              //body->getAngularVelocity(),
                              SimdVector3(0.f,0.f,0.f),//no angular effect for now //body->getAngularVelocity(),
                              timeStep,minAabb,maxAabb);


                        SimdVector3 manifoldExtraExtents(gContactBreakingTreshold,gContactBreakingTreshold,gContactBreakingTreshold);
                        minAabb -= manifoldExtraExtents;
                        maxAabb += manifoldExtraExtents;

                        BroadphaseProxy* bp = body->m_broadphaseHandle;
                        if (bp)
                        {

                              SimdVector3 color (1,1,0);

                              if (m_debugDrawer)
                              {     
                                    //draw aabb
                                    switch (body->GetActivationState())
                                    {
                                    case ISLAND_SLEEPING:
                                          {
                                                color.setValue(1,1,1);
                                                break;
                                          }
                                    case WANTS_DEACTIVATION:
                                          {
                                                color.setValue(0,0,1);
                                                break;
                                          }
                                    case ACTIVE_TAG:
                                          {
                                                break;
                                          }
                                    case DISABLE_DEACTIVATION:
                                          {
                                                color.setValue(1,0,1);
                                          };

                                    };

                                    if (m_debugDrawer->GetDebugMode() & IDebugDraw::DBG_DrawAabb)
                                    {
                                          DrawAabb(m_debugDrawer,minAabb,maxAabb,color);
                                    }
                              }

                  
                              if ( (maxAabb-minAabb).length2() < 1e12f)
                              {
                                    scene->SetAabb(bp,minAabb,maxAabb);
                              } else
                              {
                                    //something went wrong, investigate
                                    //removeCcdPhysicsController(ctrl);
                                    body->SetActivationState(DISABLE_SIMULATION);

                                    static bool reportMe = true;
                                    if (reportMe)
                                    {
                                          reportMe = false;
                                          printf("Overflow in AABB, object removed from simulation \n");
                                          printf("If you can reproduce this, please email bugs@continuousphysics.com\n");
                                          printf("Please include above information, your Platform, version of OS.\n");
                                          printf("Thanks.\n");
                                    }
                                    
                              }

                        }
                  }
}

PHY_IPhysicsController* CcdPhysicsEnvironment::CreateSphereController(float radius,const PHY__Vector3& position)
{
      
      CcdConstructionInfo     cinfo;
      cinfo.m_collisionShape = new SphereShape(radius);
      cinfo.m_MotionState = 0;
      cinfo.m_physicsEnv = this;
      cinfo.m_collisionFlags |= CollisionObject::noContactResponse;
      DefaultMotionState* motionState = new DefaultMotionState();
      cinfo.m_MotionState = motionState;
      motionState->m_worldTransform.setIdentity();
      motionState->m_worldTransform.setOrigin(SimdVector3(position[0],position[1],position[2]));

      CcdPhysicsController* sphereController = new CcdPhysicsController(cinfo);
      

      return sphereController;
}


PHY_IPhysicsController* CcdPhysicsEnvironment::CreateConeController(float coneradius,float coneheight)
{
      CcdConstructionInfo     cinfo;
      cinfo.m_collisionShape = new ConeShape(coneradius,coneheight);
      cinfo.m_MotionState = 0;
      cinfo.m_physicsEnv = this;
      DefaultMotionState* motionState = new DefaultMotionState();
      cinfo.m_MotionState = motionState;
      motionState->m_worldTransform.setIdentity();
//    motionState->m_worldTransform.setOrigin(SimdVector3(position[0],position[1],position[2]));

      CcdPhysicsController* sphereController = new CcdPhysicsController(cinfo);


      return sphereController;
}
      

Generated by  Doxygen 1.6.0   Back to index