diff options
author | Kester Maddock <Christopher.Maddock.1@uni.massey.ac.nz> | 2005-03-25 13:33:39 +0300 |
---|---|---|
committer | Kester Maddock <Christopher.Maddock.1@uni.massey.ac.nz> | 2005-03-25 13:33:39 +0300 |
commit | c844aa265ad4eb50ad0e18661470fa6092052728 (patch) | |
tree | c4a778ab1227e4266022fd076e8a0cb709badd13 /source/gameengine/Physics/Sumo | |
parent | 3dd17cec3bcaa3885e14630e6a71a8486e9b2697 (diff) |
Big patches:
Erwin Coumans: Abstract the physics engine
Charlie C: Joystick fixes
Me: Moved the ray cast (shadows, mouse sensor & ray sensor)
Diffstat (limited to 'source/gameengine/Physics/Sumo')
7 files changed, 285 insertions, 42 deletions
diff --git a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Object.h b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Object.h index 07eb5a7637f..1911e186a1c 100644 --- a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Object.h +++ b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Object.h @@ -264,7 +264,13 @@ public: SM_ClientObject *getClientObject() { return m_client_object; } void setClientObject(SM_ClientObject *client_object) { m_client_object = client_object; } - + void setPhysicsClientObject(void* physicsClientObject) + { + m_physicsClientObject = physicsClientObject; + } + void* getPhysicsClientObject() { + return m_physicsClientObject; + } void relax(); SM_MotionState &getCurrentFrame(); @@ -325,6 +331,8 @@ private: // on an SM_Object, there must be a way that the SM_Object client // can identify it's clientdata after a collision SM_ClientObject *m_client_object; + + void* m_physicsClientObject; DT_ShapeHandle m_shape; // Shape for collision detection diff --git a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Object.cpp b/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Object.cpp index ab1db7c7941..fe1ac9becd9 100644 --- a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Object.cpp +++ b/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Object.cpp @@ -42,6 +42,8 @@ #pragma warning( disable : 4786 ) #endif +#include "MT_assert.h" + #include "SM_Object.h" #include "SM_Scene.h" #include "SM_FhObject.h" @@ -147,7 +149,7 @@ SM_Object::SM_Object( m_dynamicParent(dynamicParent), m_client_object(0), - + m_physicsClientObject(0), m_shape(shape), m_materialProps(materialProps), m_materialPropsBackup(0), @@ -385,7 +387,7 @@ void SM_Object::dynamicCollision(const MT_Point3 &local2, // I guess the GEN_max is not necessary, so let's check it - assert(impulse >= 0.0); + MT_assert(impulse >= 0.0); /** * Here's the trick. We compute the impulse to make the @@ -481,7 +483,7 @@ DT_Bool SM_Object::boing( if (dist < MT_EPSILON) return DT_CONTINUE; - // Now we are definately intersecting. + // Now we are definitely intersecting. // Set callbacks for game engine. if ((obj1->getClientObject() && obj1->getClientObject()->hasCollisionCallback()) || @@ -595,7 +597,7 @@ void SM_Object::relax(void) SM_Object::SM_Object() : m_dynamicParent(0), m_client_object(0), - + m_physicsClientObject(0), m_shape(0), m_materialProps(0), m_materialPropsBackup(0), @@ -868,7 +870,7 @@ SM_Object:: setOrientation( const MT_Quaternion& orn ){ - assert(!orn.fuzzyZero()); + MT_assert(!orn.fuzzyZero()); m_kinematic = true; getNextFrame().setOrientation(orn); endFrame(); diff --git a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Scene.cpp b/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Scene.cpp index fdd8079b241..081a2fb9794 100644 --- a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Scene.cpp +++ b/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Scene.cpp @@ -140,7 +140,8 @@ void SM_Scene::requestCollisionCallback(SM_Object &object) // DT_SetResponseClass(m_fixRespTable, object.getObjectHandle(), m_fixResponseClass[OBJECT_RESPONSE]); } -void SM_Scene::remove(SM_Object& object) { +void SM_Scene::remove(SM_Object& object) { + //std::cout << "SM_Scene::remove this =" << this << "object = " << &object << std::endl; T_ObjectList::iterator i = std::find(m_objectList.begin(), m_objectList.end(), &object); if (!(i == m_objectList.end())) @@ -358,6 +359,7 @@ DT_Bool SM_Scene::boing( SM_Scene::~SM_Scene() { + //std::cout << "SM_Scene::~ SM_Scene(): destroy " << this << std::endl; // if (m_objectList.begin() != m_objectList.end()) // std::cout << "SM_Scene::~SM_Scene: There are still objects in the Sumo scene!" << std::endl; for (T_ObjectList::iterator it = m_objectList.begin() ; it != m_objectList.end() ; it++) diff --git a/source/gameengine/Physics/Sumo/SumoPhysicsController.cpp b/source/gameengine/Physics/Sumo/SumoPhysicsController.cpp index 46eeef264de..5ff47b475d1 100644 --- a/source/gameengine/Physics/Sumo/SumoPhysicsController.cpp +++ b/source/gameengine/Physics/Sumo/SumoPhysicsController.cpp @@ -35,6 +35,7 @@ #include "SM_Object.h" #include "MT_Quaternion.h" + #ifdef HAVE_CONFIG_H #include <config.h> #endif @@ -54,7 +55,16 @@ SumoPhysicsController::SumoPhysicsController( { if (m_sumoObj) { - //m_sumoObj->setClientObject(this); + + PHY__Vector3 pos1; + getPosition(pos1); + MT_Point3 pos(pos1); + + //temp debugging check + //assert(pos.length() < 100000.f); + + //need this to do the upcast after the solid/sumo collision callback + m_sumoObj->setPhysicsClientObject(this); //if it is a dyna, register for a callback m_sumoObj->registerCallback(*this); } @@ -105,8 +115,25 @@ void SumoPhysicsController::GetWorldOrientation(MT_Matrix3x3& mat) } +void SumoPhysicsController::getPosition(PHY__Vector3& pos) const +{ + assert(m_sumoObj); + + pos[0] = m_sumoObj->getPosition()[0]; + pos[1] = m_sumoObj->getPosition()[0]; + pos[2] = m_sumoObj->getPosition()[0]; + + //m_MotionState->getWorldPosition(pos[0],pos[1],pos[2]); +} + void SumoPhysicsController::GetWorldPosition(MT_Point3& pos) { +// assert(m_sumoObj); + +// pos[0] = m_sumoObj->getPosition()[0]; +// pos[1] = m_sumoObj->getPosition()[0]; +// pos[2] = m_sumoObj->getPosition()[0]; + float worldpos[3]; m_MotionState->getWorldPosition(worldpos[0],worldpos[1],worldpos[2]); pos[0]=worldpos[0]; @@ -237,16 +264,15 @@ void SumoPhysicsController::SetLinearVelocity(float lin_velX,float lin_velY,flo } } -void SumoPhysicsController::resolveCombinedVelocities( - const MT_Vector3 & lin_vel, - const MT_Vector3 & ang_vel - ) +void SumoPhysicsController::resolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ) { if (m_sumoObj) - m_sumoObj->resolveCombinedVelocities(lin_vel, ang_vel); + m_sumoObj->resolveCombinedVelocities(MT_Vector3(linvelX,linvelY,linvelZ),MT_Vector3(angVelX,angVelY,angVelZ)); } + + void SumoPhysicsController::applyImpulse(float attachX,float attachY,float attachZ, float impulseX,float impulseY,float impulseZ) { if (m_sumoObj) @@ -385,9 +411,11 @@ void SumoPhysicsController::WriteMotionStateToDynamics(bool) void SumoPhysicsController::do_me() { + MT_assert(m_sumoObj); const MT_Point3& pos = m_sumoObj->getPosition(); const MT_Quaternion& orn = m_sumoObj->getOrientation(); + MT_assert(m_MotionState); m_MotionState->setWorldPosition(pos[0],pos[1],pos[2]); m_MotionState->setWorldOrientation(orn[0],orn[1],orn[2],orn[3]); } @@ -419,3 +447,51 @@ void SumoPhysicsController::setSumoTransform(bool nondynaonly) } } } + + + // clientinfo for raycasts for example +void* SumoPhysicsController::getNewClientInfo() +{ + if (m_sumoObj) + return m_sumoObj->getClientObject(); + return 0; + +} +void SumoPhysicsController::setNewClientInfo(void* clientinfo) +{ + if (m_sumoObj) + { + SM_ClientObject* clOb = static_cast<SM_ClientObject*> (clientinfo); + m_sumoObj->setClientObject(clOb); + } + +} + +void SumoPhysicsController::calcXform() +{ + if (m_sumoObj) + m_sumoObj->calcXform(); +} + +void SumoPhysicsController::SetMargin(float margin) +{ + if (m_sumoObj) + m_sumoObj->setMargin(margin); +} + +float SumoPhysicsController::GetMargin() const +{ + if (m_sumoObj) + m_sumoObj->getMargin(); + return 0.f; +} + +float SumoPhysicsController::GetRadius() const +{ + if (m_sumoObj && m_sumoObj->getShapeProps()) + { + return m_sumoObj->getShapeProps()->m_radius; + } + return 0.f; + +} diff --git a/source/gameengine/Physics/Sumo/SumoPhysicsController.h b/source/gameengine/Physics/Sumo/SumoPhysicsController.h index 26ff52600f3..349c8cc24a6 100644 --- a/source/gameengine/Physics/Sumo/SumoPhysicsController.h +++ b/source/gameengine/Physics/Sumo/SumoPhysicsController.h @@ -72,6 +72,8 @@ public: virtual void getOrientation(float &quatImag0,float &quatImag1,float &quatImag2,float &quatReal); virtual void setOrientation(float quatImag0,float quatImag1,float quatImag2,float quatReal); virtual void setPosition(float posX,float posY,float posZ); + virtual void getPosition(PHY__Vector3& pos) const; + virtual void setScaling(float scaleX,float scaleY,float scaleZ); /*@}*/ @@ -83,7 +85,7 @@ public: virtual void ApplyForce(float forceX,float forceY,float forceZ,bool local); virtual void SetAngularVelocity(float ang_velX,float ang_velY,float ang_velZ,bool local); virtual void SetLinearVelocity(float lin_velX,float lin_velY,float lin_velZ,bool local); - virtual void resolveCombinedVelocities(const MT_Vector3 & lin_vel, const MT_Vector3 & ang_vel ); + virtual void resolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ); virtual void applyImpulse(float attachX,float attachY,float attachZ, float impulseX,float impulseY,float impulseZ); virtual void SetActive(bool active){}; virtual void SuspendDynamics(); @@ -117,10 +119,16 @@ public: */ virtual bool SynchronizeMotionStates(float time); - // clientinfo for raycasts for example - virtual void* getClientInfo() { return m_clientInfo;} - virtual void setClientInfo(void* clientinfo) {m_clientInfo = clientinfo;}; + virtual void calcXform(); + virtual void SetMargin(float margin) ; + virtual float GetMargin() const; + virtual float GetRadius() const ; + + // clientinfo for raycasts for example + virtual void* getNewClientInfo(); + virtual void setNewClientInfo(void* clientinfo); + float getFriction() { return m_friction;} float getRestitution() { return m_restitution;} @@ -173,8 +181,6 @@ private: class PHY_IMotionState* m_MotionState; - void* m_clientInfo; - }; diff --git a/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp b/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp index f035bfb4cf2..2b29b2602a8 100644 --- a/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp +++ b/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp @@ -33,15 +33,20 @@ #include "PHY_IMotionState.h" #include "SumoPhysicsController.h" #include "SM_Scene.h" +#include "SumoPHYCallbackBridge.h" +#include <SOLID/SOLID.h> #ifdef HAVE_CONFIG_H #include <config.h> #endif -MT_Scalar SumoPhysicsEnvironment::PhysicsTicRate = 60.0; SumoPhysicsEnvironment::SumoPhysicsEnvironment() { + m_fixedTimeStep = 1.f/60.f; + m_useFixedTimeStep = true; + m_currentTime = 0.f; + m_sumoScene = new SM_Scene(); } @@ -52,15 +57,7 @@ SumoPhysicsEnvironment::~SumoPhysicsEnvironment() delete m_sumoScene; } -void SumoPhysicsEnvironment::setTicRate(MT_Scalar ticrate) -{ - PhysicsTicRate = ticrate; -} -MT_Scalar SumoPhysicsEnvironment::getTicRate() -{ - return PhysicsTicRate; -} void SumoPhysicsEnvironment::beginFrame() { @@ -72,9 +69,42 @@ void SumoPhysicsEnvironment::endFrame() m_sumoScene->endFrame(); } -bool SumoPhysicsEnvironment::proceed(double curtime) +void SumoPhysicsEnvironment::setFixedTimeStep(bool useFixedTimeStep,float fixedTimeStep) { - return m_sumoScene->proceed(curtime, PhysicsTicRate); + 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; + float ticrate = 1.f/timeStep; + result = m_sumoScene->proceed(m_currentTime, timeStep); + } + return result; } void SumoPhysicsEnvironment::setGravity(float x,float y,float z) @@ -100,17 +130,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]; @@ -119,9 +160,101 @@ 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; +} diff --git a/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h b/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h index aba341360f9..62672d8ba48 100644 --- a/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h +++ b/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h @@ -35,7 +35,8 @@ #include "MT_Scalar.h" #include "PHY_IPhysicsEnvironment.h" - +class SumoPHYCallbackBridge; +#include <vector> /** * Physics Environment takes care of stepping the simulation and is a container for physics entities (rigidbodies,constraints, materials etc.) * A derived class may be able to 'construct' entities by loading and/or converting @@ -44,6 +45,11 @@ class SumoPhysicsEnvironment : public PHY_IPhysicsEnvironment { class SM_Scene* m_sumoScene; + float m_currentTime; + float m_fixedTimeStep; + bool m_useFixedTimeStep; + + std::vector<SumoPHYCallbackBridge*> m_callbacks; public: SumoPhysicsEnvironment(); @@ -51,19 +57,29 @@ public: virtual void beginFrame(); virtual void endFrame(); // Perform an integration step of duration 'timeStep'. - virtual bool proceed(double curtime); + virtual bool proceedDeltaTime(double curTime,float timeStep); + virtual void setFixedTimeStep(bool useFixedTimeStep,float fixedTimeStep); + virtual float getFixedTimeStep(); + virtual void setGravity(float x,float y,float z); virtual int createConstraint(class PHY_IPhysicsController* ctrl,class PHY_IPhysicsController* ctrl2,PHY_ConstraintType type, float pivotX,float pivotY,float pivotZ, float axisX,float axisY,float axisZ); virtual void removeConstraint(int constraintid); - virtual PHY_IPhysicsController* rayTest(void* ignoreClient,float fromX,float fromY,float fromZ, float toX,float toY,float toZ, + virtual PHY_IPhysicsController* 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); - static void setTicRate(MT_Scalar ticrate); - static MT_Scalar getTicRate(); - // sumo specific + + //gamelogic callbacks + virtual void addSensor(PHY_IPhysicsController* ctrl); + virtual void removeSensor(PHY_IPhysicsController* ctrl); + virtual void addTouchCallback(int response_class, PHY_ResponseCallback callback, void *user); + virtual void requestCollisionCallback(PHY_IPhysicsController* ctrl); + virtual PHY_IPhysicsController* CreateSphereController(float radius,const PHY__Vector3& position); + virtual PHY_IPhysicsController* CreateConeController(float coneradius,float coneheight); + + SM_Scene* GetSumoScene() { return m_sumoScene; |