I'll break this commit into two sections in the moto files
[blender-staging.git] / source / gameengine / Physics / Sumo / SumoPhysicsEnvironment.cpp
index 78e902ce2215fa7897970ccec94e5cb50f7b9a36..6cd5d513357bbbb0797b7966b329d1c7ce0b69e3 100644 (file)
 #include "PHY_IMotionState.h"
 #include "SumoPhysicsController.h"
 #include "SM_Scene.h"
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-//#include <SOLID/SOLID.h>
-
-const MT_Scalar UpperBoundForFuzzicsIntegrator = 0.01;
-// At least 100Hz (isn't this CPU hungry ?)
-
+#include "SumoPHYCallbackBridge.h"
+#include <SOLID/SOLID.h>
 
 SumoPhysicsEnvironment::SumoPhysicsEnvironment()
 {
+       m_fixedTimeStep = 1.f/60.f;
+       m_useFixedTimeStep = true;
+       m_currentTime = 0.f;
+
        m_sumoScene = new SM_Scene();
 }
 
@@ -56,9 +52,53 @@ SumoPhysicsEnvironment::~SumoPhysicsEnvironment()
        delete m_sumoScene;
 }
 
-void SumoPhysicsEnvironment::proceed(double timeStep)
+
+
+void SumoPhysicsEnvironment::beginFrame()
+{
+       m_sumoScene->beginFrame();
+}
+
+void SumoPhysicsEnvironment::endFrame()
+{
+       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)
 {
-       m_sumoScene->proceed(timeStep,UpperBoundForFuzzicsIntegrator);
+       
+       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;
 }
 
 void SumoPhysicsEnvironment::setGravity(float x,float y,float z)
@@ -84,17 +124,28 @@ void SumoPhysicsEnvironment::removeConstraint(int constraintid)
        }
 }
 
-PHY_IPhysicsController* SumoPhysicsEnvironment::rayTest(void* ignoreClient
+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
        MT_Point3 hit, normal;
-       /* FIXME: Return type is not a PHY_IPhysicsController */
-       PHY_IPhysicsController *ret = (PHY_IPhysicsController *) m_sumoScene->rayTest(ignoreClient,MT_Point3(fromX, fromY, fromZ),MT_Point3(toX, toY, toZ), hit, normal);
-       
+       PHY_IPhysicsController *ret = 0;
+
+       SM_Object* sm_ignore = 0;
+       if (ignoreCtr)
+               sm_ignore = ignoreCtr->GetSumoObject();
+
+
+       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];
@@ -103,9 +154,100 @@ PHY_IPhysicsController* SumoPhysicsEnvironment::rayTest(void* ignoreClient,
        normalY = normal[1];
        normalZ = normal[2];
        
-       assert(false);
-       
        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;
+}