I'll break this commit into two sections in the moto files
[blender-staging.git] / source / gameengine / Physics / Sumo / SumoPhysicsEnvironment.cpp
index ea18666a72d9752b42b4b104b7ac44644a8e11a4..6cd5d513357bbbb0797b7966b329d1c7ce0b69e3 100644 (file)
 #include "PHY_IMotionState.h"
 #include "SumoPhysicsController.h"
 #include "SM_Scene.h"
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-const MT_Scalar UpperBoundForFuzzicsIntegrator = 0.01;
-// At least 100Hz (isn't this CPU hungry ?)
-
+#include "SumoPHYCallbackBridge.h"
+#include <SOLID/SOLID.h>
 
 SumoPhysicsEnvironment::SumoPhysicsEnvironment()
 {
-       // seperate collision scene for events
-       m_solidScene = DT_CreateScene();
-       m_respTable = DT_CreateRespTable();
+       m_fixedTimeStep = 1.f/60.f;
+       m_useFixedTimeStep = true;
+       m_currentTime = 0.f;
 
        m_sumoScene = new SM_Scene();
-       m_sumoScene->setSecondaryRespTable(m_respTable);
-       
 }
 
 
@@ -58,49 +50,204 @@ SumoPhysicsEnvironment::SumoPhysicsEnvironment()
 SumoPhysicsEnvironment::~SumoPhysicsEnvironment()
 {
        delete m_sumoScene;
-
-       DT_DeleteScene(m_solidScene);
-       DT_DeleteRespTable(m_respTable);
 }
 
-void SumoPhysicsEnvironment::proceed(double timeStep)
+
+
+void SumoPhysicsEnvironment::beginFrame()
 {
-       m_sumoScene->proceed(timeStep,UpperBoundForFuzzicsIntegrator);
+       m_sumoScene->beginFrame();
 }
 
-void SumoPhysicsEnvironment::setGravity(float x,float y,float z)
+void SumoPhysicsEnvironment::endFrame()
 {
-       m_sumoScene->setForceField(MT_Vector3(x,y,z));
-
+       m_sumoScene->endFrame();
 }
 
+void           SumoPhysicsEnvironment::setFixedTimeStep(bool useFixedTimeStep,float fixedTimeStep)
+{
+       m_useFixedTimeStep = useFixedTimeStep;
+       if (m_useFixedTimeStep)
+       {
+               m_fixedTimeStep = fixedTimeStep;
+       } else
+       {
+               m_fixedTimeStep  = 0.f;
+       }
+       //reset current time ?
+       m_currentTime = 0.f;
+}
+float          SumoPhysicsEnvironment::getFixedTimeStep()
+{
+       return m_fixedTimeStep;
+}
 
 
+bool           SumoPhysicsEnvironment::proceedDeltaTime(double  curTime,float timeStep)
+{
+       
+       bool result = false;
+       if (m_useFixedTimeStep)
+       {
+               m_currentTime += timeStep;
+               float ticrate = 1.f/m_fixedTimeStep;
 
+               result = m_sumoScene->proceed(curTime, ticrate);
+       } else
+       {
+               m_currentTime += timeStep;
+               result = m_sumoScene->proceed(m_currentTime, timeStep);
+       }
+       return result;
+}
 
-int                    SumoPhysicsEnvironment::createConstraint(class PHY_IPhysicsController* ctrl,class PHY_IPhysicsController* ctrl2,PHY_ConstraintType type,
-               float pivotX,float pivotY,float pivotZ,float axisX,float axisY,float axisZ)
+void SumoPhysicsEnvironment::setGravity(float x,float y,float z)
 {
+       m_sumoScene->setForceField(MT_Vector3(x,y,z));
+}
 
+int SumoPhysicsEnvironment::createConstraint(
+       class PHY_IPhysicsController* ctrl,
+       class PHY_IPhysicsController* ctrl2,
+       PHY_ConstraintType type,
+       float pivotX,float pivotY,float pivotZ,
+       float axisX,float axisY,float axisZ)
+{
        int constraintid = 0;
        return constraintid;
-
 }
 
-void           SumoPhysicsEnvironment::removeConstraint(int constraintid)
+void SumoPhysicsEnvironment::removeConstraint(int constraintid)
 {
        if (constraintid)
        {
        }
 }
 
-PHY_IPhysicsController* SumoPhysicsEnvironment::rayTest(void* 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)
+PHY_IPhysicsController* SumoPhysicsEnvironment::rayTest(PHY_IPhysicsController* ignoreClientCtrl, 
+       float fromX,float fromY,float fromZ, 
+       float toX,float toY,float toZ, 
+       float& hitX,float& hitY,float& hitZ,
+       float& normalX,float& normalY,float& normalZ)
 {
+       SumoPhysicsController* ignoreCtr = static_cast<SumoPhysicsController*> (ignoreClientCtrl);
+
        //collision detection / raytesting
-       //m_sumoScene->rayTest(ignoreclient,from,to,result,normal);
+       MT_Point3 hit, normal;
+       PHY_IPhysicsController *ret = 0;
+
+       SM_Object* sm_ignore = 0;
+       if (ignoreCtr)
+               sm_ignore = ignoreCtr->GetSumoObject();
 
-       return NULL;
+
+       SM_Object* smOb = m_sumoScene->rayTest(sm_ignore,MT_Point3(fromX, fromY, fromZ),MT_Point3(toX, toY, toZ), hit, normal);
+       if (smOb)
+       {
+               ret = (PHY_IPhysicsController *) smOb->getPhysicsClientObject();
+       }
+       hitX = hit[0];
+       hitY = hit[1];
+       hitZ = hit[2];
+
+       normalX = normal[0];
+       normalY = normal[1];
+       normalZ = normal[2];
+       
+       return ret;
+}
+//gamelogic callbacks
+void SumoPhysicsEnvironment::addSensor(PHY_IPhysicsController* ctrl)
+{
+       SumoPhysicsController* smctrl = dynamic_cast<SumoPhysicsController*>(ctrl);
+       SM_Object* smObject = smctrl->GetSumoObject();
+       assert(smObject);
+       if (smObject)
+       {
+               m_sumoScene->addSensor(*smObject);
+       }
+}
+void SumoPhysicsEnvironment::removeSensor(PHY_IPhysicsController* ctrl)
+{
+       SumoPhysicsController* smctrl = dynamic_cast<SumoPhysicsController*>(ctrl);
+       SM_Object* smObject = smctrl->GetSumoObject();
+       assert(smObject);
+       if (smObject)
+       {
+               m_sumoScene->remove(*smObject);
+       }
 }
 
 
+void SumoPhysicsEnvironment::addTouchCallback(int response_class, PHY_ResponseCallback callback, void *user)
+{
+       
+       int sumoRespClass = 0;
+
+       //map PHY_ convention into SM_ convention
+       switch (response_class)
+       {
+       case    PHY_FH_RESPONSE:
+                       sumoRespClass = FH_RESPONSE; 
+               break;
+       case PHY_SENSOR_RESPONSE:
+               sumoRespClass = SENSOR_RESPONSE;
+               break;
+       case PHY_CAMERA_RESPONSE:
+               sumoRespClass =CAMERA_RESPONSE;
+               break;
+       case PHY_OBJECT_RESPONSE:
+               sumoRespClass = OBJECT_RESPONSE;
+               break;
+       case PHY_STATIC_RESPONSE:
+               sumoRespClass = PHY_STATIC_RESPONSE;
+               break;
+       default:
+               assert(0);
+               return;
+       }
+
+       SumoPHYCallbackBridge* bridge = new SumoPHYCallbackBridge(user,callback);
+
+       m_sumoScene->addTouchCallback(sumoRespClass,SumoPHYCallbackBridge::StaticSolidToPHYCallback,bridge);
+}
+void SumoPhysicsEnvironment::requestCollisionCallback(PHY_IPhysicsController* ctrl)
+{
+       SumoPhysicsController* smctrl = dynamic_cast<SumoPhysicsController*>(ctrl);
+       MT_assert(smctrl);
+       SM_Object* smObject = smctrl->GetSumoObject();
+       MT_assert(smObject);
+       if (smObject)
+       {
+               //assert(smObject->getPhysicsClientObject() == ctrl);
+               smObject->setPhysicsClientObject(ctrl);
+       
+               m_sumoScene->requestCollisionCallback(*smObject);
+       }
+}
+PHY_IPhysicsController*        SumoPhysicsEnvironment::CreateSphereController(float radius,const PHY__Vector3& position)
+{
+       DT_ShapeHandle shape    =       DT_NewSphere(0.0);
+       SM_Object* ob = new SM_Object(shape,0,0,0);     
+       ob->setPosition(MT_Point3(position));
+       //testing
+       MT_Quaternion rotquatje(MT_Vector3(0,0,1),MT_radians(90));              
+       ob->setOrientation(rotquatje);
+
+       PHY_IPhysicsController* ctrl = new SumoPhysicsController(m_sumoScene,ob,0,false);
+       ctrl->SetMargin(radius);
+       return ctrl;
+}
+PHY_IPhysicsController* SumoPhysicsEnvironment::CreateConeController(float coneradius,float coneheight)
+{
+       DT_ShapeHandle shape    =       DT_NewCone(coneradius,coneheight);
+       SM_Object* ob = new SM_Object(shape,0,0,0);     
+       ob->setPosition(MT_Point3(0.f,0.f,0.f));
+       MT_Quaternion rotquatje(MT_Vector3(0,0,1),MT_radians(90));              
+       ob->setOrientation(rotquatje);
+
+       PHY_IPhysicsController* ctrl = new SumoPhysicsController(m_sumoScene,ob,0,false);
+
+       return ctrl;
+}
+