Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/gameengine/Ketsji/KX_ClientObjectInfo.h31
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp2
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.cpp25
-rw-r--r--source/gameengine/Ketsji/KX_MouseFocusSensor.cpp7
-rw-r--r--source/gameengine/Ketsji/KX_NearSensor.cpp11
-rw-r--r--source/gameengine/Ketsji/KX_RadarSensor.cpp2
-rw-r--r--source/gameengine/Ketsji/KX_RaySensor.cpp4
-rw-r--r--source/gameengine/Ketsji/KX_SumoPhysicsController.cpp1
-rw-r--r--source/gameengine/Ketsji/KX_TouchEventManager.cpp54
-rw-r--r--source/gameengine/Ketsji/KX_TouchEventManager.h21
-rw-r--r--source/gameengine/Ketsji/KX_TouchSensor.cpp12
-rw-r--r--source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.cpp14
-rw-r--r--source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h4
-rw-r--r--source/gameengine/Physics/Sumo/Fuzzics/include/SM_Object.h15
-rw-r--r--source/gameengine/Physics/Sumo/Fuzzics/include/SM_Scene.h4
-rw-r--r--source/gameengine/Physics/Sumo/Fuzzics/src/SM_Object.cpp50
-rw-r--r--source/gameengine/Physics/Sumo/Fuzzics/src/SM_Scene.cpp59
-rw-r--r--source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp14
-rw-r--r--source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h4
-rw-r--r--source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h4
20 files changed, 253 insertions, 85 deletions
diff --git a/source/gameengine/Ketsji/KX_ClientObjectInfo.h b/source/gameengine/Ketsji/KX_ClientObjectInfo.h
index 0ef1a1b86fe..237ec137a1c 100644
--- a/source/gameengine/Ketsji/KX_ClientObjectInfo.h
+++ b/source/gameengine/Ketsji/KX_ClientObjectInfo.h
@@ -32,10 +32,16 @@
#ifndef __KX_CLIENTOBJECT_INFO_H
#define __KX_CLIENTOBJECT_INFO_H
+#include <SM_Object.h>
+
+#include <list>
+
+class SCA_ISensor;
+class KX_GameObject;
/**
* Client Type and Additional Info. This structure can be use instead of a bare void* pointer, for safeness, and additional info for callbacks
*/
-struct KX_ClientObjectInfo
+struct KX_ClientObjectInfo : public SM_ClientObject
{
enum clienttype {
STATIC,
@@ -44,15 +50,32 @@ struct KX_ClientObjectInfo
RADAR,
NEAR
} m_type;
- void* m_clientobject;
+ KX_GameObject* m_gameobject;
void* m_auxilary_info;
+ std::list<SCA_ISensor*> m_sensors;
public:
- KX_ClientObjectInfo(void *clientobject, clienttype type = STATIC, void *auxilary_info = NULL) :
+ KX_ClientObjectInfo(KX_GameObject *gameobject, clienttype type = STATIC, void *auxilary_info = NULL) :
+ SM_ClientObject(),
m_type(type),
- m_clientobject(clientobject),
+ m_gameobject(gameobject),
m_auxilary_info(auxilary_info)
{}
+ KX_ClientObjectInfo(const KX_ClientObjectInfo &copy)
+ : SM_ClientObject(copy),
+ m_type(copy.m_type),
+ m_gameobject(copy.m_gameobject),
+ m_auxilary_info(copy.m_auxilary_info)
+ {
+ }
+
+ virtual ~KX_ClientObjectInfo() {}
+
+ virtual bool hasCollisionCallback()
+ {
+ return m_sensors.size() != 0;
+ }
+
bool isActor() { return m_type <= ACTOR; }
};
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp
index 67148114de8..896da63ea04 100644
--- a/source/gameengine/Ketsji/KX_GameObject.cpp
+++ b/source/gameengine/Ketsji/KX_GameObject.cpp
@@ -188,7 +188,7 @@ void KX_GameObject::ProcessReplica(KX_GameObject* replica)
replica->m_pPhysicsController1 = NULL;
replica->m_pSGNode = NULL;
replica->m_pClient_info = new KX_ClientObjectInfo(*m_pClient_info);
- replica->m_pClient_info->m_clientobject = replica;
+ replica->m_pClient_info->m_gameobject = replica;
}
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
index fbe2fd9c6cd..04777bf4a36 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
@@ -315,17 +315,13 @@ void KX_KetsjiEngine::NextFrame()
m_logger->StartLog(tc_services, m_kxsystem->GetTimeInSeconds(), true);
double curtime;
+ double localtime = m_previoustime;
if (m_bFixedTime)
- {
- m_deltatime = 1.0/m_ticrate;
curtime = m_previoustime + m_deltatime;
- }
else
- {
curtime = m_kxsystem->GetTimeInSeconds();
- m_deltatime += curtime - m_previoustime;
- m_previoustime = curtime;
- }
+ m_deltatime += curtime - m_previoustime;
+ m_previoustime = curtime;
// Compute the number of logic frames to do each update (fixed tic bricks)
int frames = (int) (m_deltatime*m_ticrate);
@@ -337,13 +333,17 @@ void KX_KetsjiEngine::NextFrame()
if (!frames)
{
- for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); sceneit++)
+ for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); ++sceneit)
// for each scene, call the proceed functions
{
KX_Scene* scene = *sceneit;
if (!scene->IsSuspended())
{
+ // set Python hooks for each scene
+ PHY_SetActiveEnvironment(scene->GetPhysicsEnvironment());
+ PHY_SetActiveScene(scene);
+
// Do some cleanup work for this logic frame
m_logger->StartLog(tc_logic, m_kxsystem->GetTimeInSeconds(), true);
scene->LogicUpdateFrame(curtime, false);
@@ -356,7 +356,6 @@ void KX_KetsjiEngine::NextFrame()
// many iterations of the physics solver.
m_logger->StartLog(tc_physics, m_kxsystem->GetTimeInSeconds(), true);
scene->GetPhysicsEnvironment()->proceed(curtime);
-
// Update scenegraph after physics step. This maps physics calculations
// into node positions.
m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
@@ -371,7 +370,8 @@ void KX_KetsjiEngine::NextFrame()
while (frames--)
{
- for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); sceneit++)
+ localtime += 1.0/m_ticrate;
+ for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); ++sceneit)
// for each scene, call the proceed functions
{
KX_Scene* scene = *sceneit;
@@ -385,6 +385,10 @@ void KX_KetsjiEngine::NextFrame()
if (!scene->IsSuspended())
{
+ m_logger->StartLog(tc_physics, m_kxsystem->GetTimeInSeconds(), true);
+ scene->GetPhysicsEnvironment()->endFrame();
+ scene->GetPhysicsEnvironment()->beginFrame();
+
m_logger->StartLog(tc_network, m_kxsystem->GetTimeInSeconds(), true);
scene->GetNetworkScene()->proceed(curtime);
@@ -416,7 +420,6 @@ void KX_KetsjiEngine::NextFrame()
// many iterations of the physics solver.
m_logger->StartLog(tc_physics, m_kxsystem->GetTimeInSeconds(), true);
scene->GetPhysicsEnvironment()->proceed(curtime);
-
// Update scenegraph after physics step. This maps physics calculations
// into node positions.
m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp
index 84b08058ecc..9380ef6f2fa 100644
--- a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp
+++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp
@@ -42,7 +42,6 @@
#endif
#include "MT_Point3.h"
-#include "KX_ClientObjectInfo.h"
#include "RAS_FramingManager.h"
#include "RAS_ICanvas.h"
#include "RAS_IRasterizer.h"
@@ -51,11 +50,11 @@
#include "KX_Camera.h"
#include "KX_MouseFocusSensor.h"
-#include "KX_ClientObjectInfo.h"
#include "SM_Object.h"
#include "SM_Scene.h"
#include "SumoPhysicsEnvironment.h"
#include "KX_SumoPhysicsController.h"
+#include "KX_ClientObjectInfo.h"
/* ------------------------------------------------------------------------- */
/* Native functions */
@@ -259,7 +258,7 @@ bool KX_MouseFocusSensor::ParentObjectHasFocus(void)
/* all this casting makes me nervous... */
KX_ClientObjectInfo* client_info
= ( hitSMObj ?
- (KX_ClientObjectInfo*) hitSMObj->getClientObject() :
+ static_cast<KX_ClientObjectInfo*>( hitSMObj->getClientObject() ):
NULL);
if (!client_info)
@@ -268,7 +267,7 @@ bool KX_MouseFocusSensor::ParentObjectHasFocus(void)
return false;
}
- KX_GameObject* hitKXObj = (KX_GameObject*)client_info->m_clientobject;
+ KX_GameObject* hitKXObj = client_info->m_gameobject;
if (client_info->m_type > KX_ClientObjectInfo::ACTOR)
{
diff --git a/source/gameengine/Ketsji/KX_NearSensor.cpp b/source/gameengine/Ketsji/KX_NearSensor.cpp
index 3bb6bad5029..bfcf9794d1b 100644
--- a/source/gameengine/Ketsji/KX_NearSensor.cpp
+++ b/source/gameengine/Ketsji/KX_NearSensor.cpp
@@ -62,7 +62,9 @@ KX_NearSensor::KX_NearSensor(SCA_EventManager* eventmgr,
m_ResetMargin(resetmargin)
{
+ gameobj->getClientInfo()->m_sensors.remove(this);
m_client_info = new KX_ClientObjectInfo(gameobj, KX_ClientObjectInfo::NEAR);
+ m_client_info->m_sensors.push_back(this);
DT_ShapeHandle shape = (DT_ShapeHandle) vshape;
m_sumoObj = new SM_Object(shape,NULL,NULL,NULL);
@@ -90,7 +92,9 @@ KX_NearSensor::KX_NearSensor(SCA_EventManager* eventmgr,
m_ResetMargin(resetmargin)
{
+ gameobj->getClientInfo()->m_sensors.remove(this);
m_client_info = new KX_ClientObjectInfo(gameobj, KX_ClientObjectInfo::NEAR);
+ m_client_info->m_sensors.push_back(this);
m_sumoObj = new SM_Object(DT_NewSphere(0.0),NULL,NULL,NULL);
m_sumoObj->setMargin(m_Margin);
@@ -115,7 +119,7 @@ CValue* KX_NearSensor::GetReplica()
// this will copy properties and so on...
CValue::AddDataToReplica(replica);
- replica->m_client_info = new KX_ClientObjectInfo(m_client_info->m_clientobject, KX_ClientObjectInfo::NEAR);
+ replica->m_client_info = new KX_ClientObjectInfo(m_client_info->m_gameobject, KX_ClientObjectInfo::NEAR);
replica->m_sumoObj = new SM_Object(DT_NewSphere(0.0),NULL,NULL,NULL);
replica->m_sumoObj->setMargin(m_Margin);
@@ -132,7 +136,8 @@ void KX_NearSensor::ReParent(SCA_IObject* parent)
{
SCA_ISensor::ReParent(parent);
- m_client_info->m_clientobject = static_cast<KX_GameObject*>(parent);
+ m_client_info->m_gameobject = static_cast<KX_GameObject*>(parent);
+ m_client_info->m_sensors.push_back(this);
SynchronizeTransform();
}
@@ -197,7 +202,7 @@ DT_Bool KX_NearSensor::HandleCollision(void* obj1,void* obj2,const DT_CollData *
((SM_Object*)obj1)->getClientObject());
KX_GameObject* gameobj = ( client_info ?
- static_cast<KX_GameObject*>(client_info->m_clientobject) :
+ client_info->m_gameobject :
NULL);
if (gameobj && (gameobj != parent))
diff --git a/source/gameengine/Ketsji/KX_RadarSensor.cpp b/source/gameengine/Ketsji/KX_RadarSensor.cpp
index 798ebdfc944..1ad37504224 100644
--- a/source/gameengine/Ketsji/KX_RadarSensor.cpp
+++ b/source/gameengine/Ketsji/KX_RadarSensor.cpp
@@ -88,7 +88,7 @@ CValue* KX_RadarSensor::GetReplica()
// this will copy properties and so on...
CValue::AddDataToReplica(replica);
- replica->m_client_info = new KX_ClientObjectInfo(m_client_info->m_clientobject, KX_ClientObjectInfo::RADAR);
+ replica->m_client_info = new KX_ClientObjectInfo(m_client_info->m_gameobject, KX_ClientObjectInfo::RADAR);
replica->m_sumoObj = new SM_Object(DT_NewCone(m_coneradius, m_coneheight),NULL,NULL,NULL);
replica->m_sumoObj->setMargin(m_Margin);
diff --git a/source/gameengine/Ketsji/KX_RaySensor.cpp b/source/gameengine/Ketsji/KX_RaySensor.cpp
index 04f57bb754b..c60b2171cab 100644
--- a/source/gameengine/Ketsji/KX_RaySensor.cpp
+++ b/source/gameengine/Ketsji/KX_RaySensor.cpp
@@ -195,7 +195,7 @@ bool KX_RaySensor::Evaluate(CValue* event)
if (hitObj)
{
- KX_ClientObjectInfo* info = (KX_ClientObjectInfo*)hitObj->getClientObject();
+ KX_ClientObjectInfo* info = static_cast<KX_ClientObjectInfo*>(hitObj->getClientObject());
bool bFound = false;
if (!info)
@@ -205,7 +205,7 @@ bool KX_RaySensor::Evaluate(CValue* event)
break;
}
- SCA_IObject *hitgameobj = (SCA_IObject*)info->m_clientobject;
+ SCA_IObject *hitgameobj = info->m_gameobject;
if (hitgameobj == obj || info->m_type > KX_ClientObjectInfo::ACTOR)
{
diff --git a/source/gameengine/Ketsji/KX_SumoPhysicsController.cpp b/source/gameengine/Ketsji/KX_SumoPhysicsController.cpp
index a5284b40165..8f284809a17 100644
--- a/source/gameengine/Ketsji/KX_SumoPhysicsController.cpp
+++ b/source/gameengine/Ketsji/KX_SumoPhysicsController.cpp
@@ -8,6 +8,7 @@
#include "SM_Scene.h"
#include "KX_GameObject.h"
#include "KX_MotionState.h"
+#include "KX_ClientObjectInfo.h"
#ifdef HAVE_CONFIG_H
#include <config.h>
diff --git a/source/gameengine/Ketsji/KX_TouchEventManager.cpp b/source/gameengine/Ketsji/KX_TouchEventManager.cpp
index 704d949b0e7..4f074ce9b12 100644
--- a/source/gameengine/Ketsji/KX_TouchEventManager.cpp
+++ b/source/gameengine/Ketsji/KX_TouchEventManager.cpp
@@ -40,6 +40,31 @@
#include "SM_Object.h"
+KX_TouchEventManager::Collision::Collision(SCA_ISensor *sensor, SM_Object *obj1, SM_Object *obj2)
+ : m_id(next_id++),
+ m_sensor(sensor),
+ m_object1(obj1),
+ m_object2(obj2)
+{
+}
+
+bool KX_TouchEventManager::Collision::operator<(const Collision &other) const
+{
+ if (*this == other)
+ return true;
+
+ return m_id < other.m_id;
+}
+
+bool KX_TouchEventManager::Collision::operator==(const Collision &other) const
+{
+ return m_sensor == other.m_sensor &&
+ ((m_object1 == other.m_object1 && m_object2 == other.m_object2) ||
+ (m_object1 == other.m_object2 && m_object2 == other.m_object1));
+}
+
+int KX_TouchEventManager::Collision::next_id = 0;
+
KX_TouchEventManager::KX_TouchEventManager(class SCA_LogicManager* logicmgr,
SM_Scene *scene)
: SCA_EventManager(TOUCH_EVENTMGR),
@@ -51,6 +76,24 @@ KX_TouchEventManager::KX_TouchEventManager(class SCA_LogicManager* logicmgr,
m_scene->addTouchCallback(SENSOR_RESPONSE, KX_TouchEventManager::collisionResponse, this);
}
+DT_Bool KX_TouchEventManager::HandleCollision(void* object1, void* object2, const DT_CollData *coll_data)
+{
+ SM_Object * obj1 = static_cast<SM_Object*>(object1);
+ SM_Object * obj2 = static_cast<SM_Object*>(object2);
+ KX_ClientObjectInfo *client_info = static_cast<KX_ClientObjectInfo *>(obj1->getClientObject());
+
+ list<SCA_ISensor*>::iterator it;
+ for ( it = client_info->m_sensors.begin(); it != client_info->m_sensors.end(); ++it)
+ m_collisions.insert(Collision(*it, obj1, obj2));
+
+ client_info = static_cast<KX_ClientObjectInfo *>(obj2->getClientObject());
+ for ( it = client_info->m_sensors.begin(); it != client_info->m_sensors.end(); ++it)
+ m_collisions.insert(Collision(*it, obj2, obj1));
+
+ return DT_CONTINUE;
+}
+
+/*
DT_Bool KX_TouchEventManager::HandleCollision(void* object1,void* object2,
const DT_CollData * coll_data)
{
@@ -76,6 +119,8 @@ DT_Bool KX_TouchEventManager::HandleCollision(void* object1,void* object2,
return DT_CONTINUE;
}
+*/
+
DT_Bool KX_TouchEventManager::collisionResponse(void *client_data,
void *object1,
void *object2,
@@ -115,10 +160,15 @@ void KX_TouchEventManager::NextFrame()
{
vector<SCA_ISensor*>::iterator it;
- for (it = m_sensors.begin();!(it==m_sensors.end());it++)
+ for (it = m_sensors.begin();!(it==m_sensors.end());++it)
static_cast<KX_TouchSensor*>(*it)->SynchronizeTransform();
- for (it = m_sensors.begin();!(it==m_sensors.end());it++)
+ for (std::set<Collision>::iterator cit = m_collisions.begin(); cit != m_collisions.end(); ++cit)
+ static_cast<KX_TouchSensor*>((*cit).m_sensor)->HandleCollision((*cit).m_object1, (*cit).m_object2, NULL);
+
+ m_collisions.clear();
+
+ for (it = m_sensors.begin();!(it==m_sensors.end());++it)
(*it)->Activate(m_logicmgr,NULL);
}
}
diff --git a/source/gameengine/Ketsji/KX_TouchEventManager.h b/source/gameengine/Ketsji/KX_TouchEventManager.h
index 923ecd10884..eb2c26a64f3 100644
--- a/source/gameengine/Ketsji/KX_TouchEventManager.h
+++ b/source/gameengine/Ketsji/KX_TouchEventManager.h
@@ -37,11 +37,32 @@
#include "KX_GameObject.h"
#include <vector>
+#include <set>
+
+class SCA_ISensor;
+class SM_Object;
class KX_TouchEventManager : public SCA_EventManager
{
+ struct Collision
+ {
+ static int next_id;
+ int m_id;
+ SCA_ISensor *m_sensor;
+ SM_Object *m_object1;
+ SM_Object *m_object2;
+
+ Collision(SCA_ISensor *sensor, SM_Object *obj1, SM_Object *obj2);
+
+ bool operator<(const Collision &other) const;
+ bool operator==(const Collision &other) const;
+ };
+
class SCA_LogicManager* m_logicmgr;
SM_Scene *m_scene;
+
+ std::set<Collision> m_collisions;
+
static DT_Bool collisionResponse(void *client_data,
void *object1,
diff --git a/source/gameengine/Ketsji/KX_TouchSensor.cpp b/source/gameengine/Ketsji/KX_TouchSensor.cpp
index 9091a41d054..4a7e9d8646d 100644
--- a/source/gameengine/Ketsji/KX_TouchSensor.cpp
+++ b/source/gameengine/Ketsji/KX_TouchSensor.cpp
@@ -103,8 +103,9 @@ m_bLastTriggered(false)
m_colliders = new CListValue();
KX_ClientObjectInfo *client_info = gameobj->getClientInfo();
- client_info->m_clientobject = gameobj;
+ client_info->m_gameobject = gameobj;
client_info->m_auxilary_info = NULL;
+ client_info->m_sensors.push_back(this);
KX_SumoPhysicsController *sphy = dynamic_cast<KX_SumoPhysicsController *>(gameobj->GetPhysicsController());
if (sphy)
@@ -141,8 +142,9 @@ void KX_TouchSensor::ReParent(SCA_IObject* parent)
// m_solidHandle = m_sumoObj->getObjectHandle();
KX_ClientObjectInfo *client_info = gameobj->getClientInfo();
- client_info->m_clientobject = parent;
+ client_info->m_gameobject = gameobj;
client_info->m_auxilary_info = NULL;
+ client_info->m_sensors.push_back(this);
SCA_ISensor::ReParent(parent);
}
@@ -164,12 +166,12 @@ DT_Bool KX_TouchSensor::HandleCollision(void* obj1,void* obj2,const DT_CollDa
// need the mapping from SM_Objects to gameobjects now
- KX_ClientObjectInfo* client_info =(KX_ClientObjectInfo*) (obj1 == m_sumoObj?
+ KX_ClientObjectInfo* client_info = static_cast<KX_ClientObjectInfo*> (obj1 == m_sumoObj?
((SM_Object*)obj2)->getClientObject() :
((SM_Object*)obj1)->getClientObject());
KX_GameObject* gameobj = ( client_info ?
- (KX_GameObject*)client_info->m_clientobject :
+ client_info->m_gameobject :
NULL);
if (gameobj && (gameobj != parent) && client_info->isActor())
@@ -338,7 +340,7 @@ PyObject* KX_TouchSensor::PyGetHitObjectList(PyObject* self,
SM_Object* smob = spc?spc->GetSumoObject():NULL;
if (smob) {
- KX_ClientObjectInfo* cl_inf = (KX_ClientObjectInfo*) smob->getClientObject();
+ KX_ClientObjectInfo* cl_inf = static_cast<KX_ClientObjectInfo*>(smob->getClientObject());
if (m_touchedpropname == ((char*)cl_inf->m_auxilary_info)) {
newList->Add(m_colliders->GetValue(i)->AddRef());
diff --git a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.cpp b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.cpp
index bfb24f5fec1..6c69e14c886 100644
--- a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.cpp
+++ b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.cpp
@@ -48,14 +48,24 @@ DummyPhysicsEnvironment::~DummyPhysicsEnvironment()
//destroy physicsengine data
}
-void DummyPhysicsEnvironment::proceed(double timeStep)
+void DummyPhysicsEnvironment::beginFrame()
+{
+ // beginning of logic frame: apply forces
+}
+
+void DummyPhysicsEnvironment::endFrame()
+{
+ // end of logic frame: clear forces
+}
+
+bool DummyPhysicsEnvironment::proceed(double timeStep)
{
//step physics simulation, typically perform
//collision detection
//solve constraints
//integrate solution
-
+ // return true if an update was done.
}
void DummyPhysicsEnvironment::setGravity(float x,float y,float z)
diff --git a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h
index 96f1ff82f9e..65f42141045 100644
--- a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h
+++ b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h
@@ -48,8 +48,10 @@ class DummyPhysicsEnvironment : public PHY_IPhysicsEnvironment
public:
DummyPhysicsEnvironment ();
virtual ~DummyPhysicsEnvironment ();
+ virtual void beginFrame();
+ virtual void endFrame();
// Perform an integration step of duration 'timeStep'.
- virtual void proceed (double timeStep);
+ virtual bool proceed (double timeStep);
virtual void setGravity(float x,float y,float z);
virtual int createConstraint(class PHY_IPhysicsController* ctrl,class PHY_IPhysicsController* ctrl2,PHY_ConstraintType type,
diff --git a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Object.h b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Object.h
index 54574f9fc55..4a69f7e2990 100644
--- a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Object.h
+++ b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Object.h
@@ -66,6 +66,14 @@ struct SM_MaterialProps {
bool m_fh_normal; ///< Should the object slide off slopes?
};
+class SM_ClientObject
+{
+public:
+ SM_ClientObject() {}
+ virtual ~SM_ClientObject() {}
+
+ virtual bool hasCollisionCallback() = 0;
+};
/**
* SM_Object is an internal part of the Sumo physics engine.
@@ -227,7 +235,6 @@ public:
SM_Object *getDynamicParent() ;
- void beginFrame();
void integrateForces(MT_Scalar timeStep);
void integrateMomentum(MT_Scalar timeSteo);
@@ -255,8 +262,8 @@ public:
);
- void *getClientObject() { return m_client_object; }
- void setClientObject(void *client_object) { m_client_object = client_object; }
+ SM_ClientObject *getClientObject() { return m_client_object; }
+ void setClientObject(SM_ClientObject *client_object) { m_client_object = client_object; }
void relax();
@@ -301,7 +308,7 @@ private:
// as the collision callback now has only information
// on an SM_Object, there must be a way that the SM_Object client
// can identify it's clientdata after a collision
- void *m_client_object;
+ SM_ClientObject *m_client_object;
DT_ShapeHandle m_shape; // Shape for collision detection
diff --git a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Scene.h b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Scene.h
index 1c11df66c38..0b429a3c1a4 100644
--- a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Scene.h
+++ b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Scene.h
@@ -101,13 +101,15 @@ public:
void requestCollisionCallback(SM_Object &object);
+ void beginFrame();
+ void endFrame();
// Perform an integration step of duration 'timeStep'.
// 'subSampling' is the maximum duration of a substep, i.e.,
// The maximum time interval between two collision checks.
// 'subSampling' can be used to control aliasing effects
// (fast moving objects traversing through walls and such).
- void proceed(MT_Scalar curtime, MT_Scalar ticrate);
+ bool proceed(MT_Scalar curtime, MT_Scalar ticrate);
/**
* Test whether any objects lie on the line defined by from and
diff --git a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Object.cpp b/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Object.cpp
index 940f0d221a0..42adfcd4d9e 100644
--- a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Object.cpp
+++ b/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Object.cpp
@@ -101,16 +101,6 @@ SM_Object::SM_Object(
m_suspended = false;
}
- void
-SM_Object::
-beginFrame(
-){
- if (!m_suspended) {
- m_prev_state = *this;
- m_prev_state.setLinearVelocity(actualLinVelocity());
- m_prev_state.setAngularVelocity(actualAngVelocity());
- }
-}
void
SM_Object::
@@ -118,6 +108,9 @@ integrateForces(
MT_Scalar timeStep
){
if (!m_suspended) {
+ m_prev_state = *this;
+ m_prev_state.setLinearVelocity(actualLinVelocity());
+ m_prev_state.setAngularVelocity(actualAngVelocity());
if (isDynamic()) {
// Integrate momentum (forward Euler)
m_lin_mom += m_force * timeStep;
@@ -348,49 +341,68 @@ void SM_Object::dynamicCollision(const MT_Point3 &local2,
}
}
+static void AddCallback(SM_Scene *scene, SM_Object *obj1, SM_Object *obj2)
+{
+ // If we have callbacks on either of the client objects, do a collision test
+ // and add a callback if they intersect.
+ DT_Vector3 v;
+ if ((obj1->getClientObject() && obj1->getClientObject()->hasCollisionCallback()) ||
+ (obj2->getClientObject() && obj2->getClientObject()->hasCollisionCallback()) &&
+ DT_GetIntersect(obj1->getObjectHandle(), obj2->getObjectHandle(), v))
+ scene->addPair(obj1, obj2);
+}
+
DT_Bool SM_Object::boing(
void *client_data,
void *object1,
void *object2,
const DT_CollData *coll_data
){
- //if (!coll_data)
- // return DT_CONTINUE;
-
SM_Scene *scene = (SM_Scene *)client_data;
SM_Object *obj1 = (SM_Object *)object1;
SM_Object *obj2 = (SM_Object *)object2;
- scene->addPair(obj1, obj2); // Record this collision for client callbacks
+ // at this point it is unknown whether we are really intersecting (broad phase)
+
+ DT_Vector3 p1, p2;
+ if (!obj2->isDynamic()) {
+ std::swap(obj1, obj2);
+ }
// If one of the objects is a ghost then ignore it for the dynamics
if (obj1->isGhost() || obj2->isGhost()) {
+ AddCallback(scene, obj1, obj2);
return DT_CONTINUE;
}
// Objects do not collide with parent objects
if (obj1->getDynamicParent() == obj2 || obj2->getDynamicParent() == obj1) {
+ AddCallback(scene, obj1, obj2);
return DT_CONTINUE;
}
if (!obj2->isDynamic()) {
- std::swap(obj1, obj2);
- }
-
- if (!obj2->isDynamic()) {
+ AddCallback(scene, obj1, obj2);
return DT_CONTINUE;
}
// Get collision data from SOLID
- DT_Vector3 p1, p2;
if (!DT_GetPenDepth(obj1->getObjectHandle(), obj2->getObjectHandle(), p1, p2))
return DT_CONTINUE;
+
MT_Point3 local1(p1), local2(p2);
MT_Vector3 normal(local2 - local1);
MT_Scalar dist = normal.length();
if (dist < MT_EPSILON)
return DT_CONTINUE;
+
+ // Now we are definately intersecting.
+
+ // Set callbacks for game engine.
+ if ((obj1->getClientObject() && obj1->getClientObject()->hasCollisionCallback()) ||
+ (obj2->getClientObject() && obj2->getClientObject()->hasCollisionCallback()))
+ scene->addPair(obj1, obj2);
local1 -= obj1->m_pos;
local2 -= obj2->m_pos;
diff --git a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Scene.cpp b/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Scene.cpp
index 0af1c22edbd..1ea19c56336 100644
--- a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Scene.cpp
+++ b/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Scene.cpp
@@ -65,38 +65,38 @@ SM_Scene::SM_Scene() :
/* Sensor */
DT_AddPairResponse(m_respTable, m_ResponseClass[SENSOR_RESPONSE], m_ResponseClass[SENSOR_RESPONSE], 0, DT_NO_RESPONSE, this);
- DT_AddPairResponse(m_respTable, m_ResponseClass[SENSOR_RESPONSE], m_ResponseClass[STATIC_RESPONSE], SM_Scene::boing, DT_SIMPLE_RESPONSE, this);
- DT_AddPairResponse(m_respTable, m_ResponseClass[SENSOR_RESPONSE], m_ResponseClass[OBJECT_RESPONSE], SM_Scene::boing, DT_SIMPLE_RESPONSE, this);
+ DT_AddPairResponse(m_respTable, m_ResponseClass[SENSOR_RESPONSE], m_ResponseClass[STATIC_RESPONSE], SM_Scene::boing, DT_BROAD_RESPONSE, this);
+ DT_AddPairResponse(m_respTable, m_ResponseClass[SENSOR_RESPONSE], m_ResponseClass[OBJECT_RESPONSE], SM_Scene::boing, DT_BROAD_RESPONSE, this);
DT_AddPairResponse(m_respTable, m_ResponseClass[SENSOR_RESPONSE], m_ResponseClass[FH_RESPONSE], 0, DT_NO_RESPONSE, this);
/* Static */
- DT_AddPairResponse(m_respTable, m_ResponseClass[STATIC_RESPONSE], m_ResponseClass[SENSOR_RESPONSE], SM_Scene::boing, DT_SIMPLE_RESPONSE, this);
+ DT_AddPairResponse(m_respTable, m_ResponseClass[STATIC_RESPONSE], m_ResponseClass[SENSOR_RESPONSE], SM_Scene::boing, DT_BROAD_RESPONSE, this);
DT_AddPairResponse(m_respTable, m_ResponseClass[STATIC_RESPONSE], m_ResponseClass[STATIC_RESPONSE], 0, DT_NO_RESPONSE, this);
- DT_AddPairResponse(m_respTable, m_ResponseClass[STATIC_RESPONSE], m_ResponseClass[OBJECT_RESPONSE], SM_Object::boing, DT_SIMPLE_RESPONSE, this);
- DT_AddPairResponse(m_respTable, m_ResponseClass[STATIC_RESPONSE], m_ResponseClass[FH_RESPONSE], SM_FhObject::ray_hit, DT_SIMPLE_RESPONSE, this);
+ DT_AddPairResponse(m_respTable, m_ResponseClass[STATIC_RESPONSE], m_ResponseClass[OBJECT_RESPONSE], SM_Object::boing, DT_BROAD_RESPONSE, this);
+ DT_AddPairResponse(m_respTable, m_ResponseClass[STATIC_RESPONSE], m_ResponseClass[FH_RESPONSE], SM_FhObject::ray_hit, DT_BROAD_RESPONSE, this);
/* Object */
- DT_AddPairResponse(m_respTable, m_ResponseClass[OBJECT_RESPONSE], m_ResponseClass[SENSOR_RESPONSE], SM_Scene::boing, DT_SIMPLE_RESPONSE, this);
- DT_AddPairResponse(m_respTable, m_ResponseClass[OBJECT_RESPONSE], m_ResponseClass[STATIC_RESPONSE], SM_Object::boing, DT_SIMPLE_RESPONSE, this);
- DT_AddPairResponse(m_respTable, m_ResponseClass[OBJECT_RESPONSE], m_ResponseClass[OBJECT_RESPONSE], SM_Object::boing, DT_SIMPLE_RESPONSE, this);
- DT_AddPairResponse(m_respTable, m_ResponseClass[OBJECT_RESPONSE], m_ResponseClass[FH_RESPONSE], SM_FhObject::ray_hit, DT_SIMPLE_RESPONSE, this);
+ DT_AddPairResponse(m_respTable, m_ResponseClass[OBJECT_RESPONSE], m_ResponseClass[SENSOR_RESPONSE], SM_Scene::boing, DT_BROAD_RESPONSE, this);
+ DT_AddPairResponse(m_respTable, m_ResponseClass[OBJECT_RESPONSE], m_ResponseClass[STATIC_RESPONSE], SM_Object::boing, DT_BROAD_RESPONSE, this);
+ DT_AddPairResponse(m_respTable, m_ResponseClass[OBJECT_RESPONSE], m_ResponseClass[OBJECT_RESPONSE], SM_Object::boing, DT_BROAD_RESPONSE, this);
+ DT_AddPairResponse(m_respTable, m_ResponseClass[OBJECT_RESPONSE], m_ResponseClass[FH_RESPONSE], SM_FhObject::ray_hit, DT_BROAD_RESPONSE, this);
/* Fh Object */
DT_AddPairResponse(m_respTable, m_ResponseClass[FH_RESPONSE], m_ResponseClass[SENSOR_RESPONSE], 0, DT_NO_RESPONSE, this);
- DT_AddPairResponse(m_respTable, m_ResponseClass[FH_RESPONSE], m_ResponseClass[STATIC_RESPONSE], SM_FhObject::ray_hit, DT_SIMPLE_RESPONSE, this);
- DT_AddPairResponse(m_respTable, m_ResponseClass[FH_RESPONSE], m_ResponseClass[OBJECT_RESPONSE], SM_FhObject::ray_hit, DT_SIMPLE_RESPONSE, this);
+ DT_AddPairResponse(m_respTable, m_ResponseClass[FH_RESPONSE], m_ResponseClass[STATIC_RESPONSE], SM_FhObject::ray_hit, DT_BROAD_RESPONSE, this);
+ DT_AddPairResponse(m_respTable, m_ResponseClass[FH_RESPONSE], m_ResponseClass[OBJECT_RESPONSE], SM_FhObject::ray_hit, DT_BROAD_RESPONSE, this);
DT_AddPairResponse(m_respTable, m_ResponseClass[FH_RESPONSE], m_ResponseClass[FH_RESPONSE], 0, DT_NO_RESPONSE, this);
/* Object (Fix Pass) */
DT_AddPairResponse(m_fixRespTable, m_ResponseClass[OBJECT_RESPONSE], m_ResponseClass[SENSOR_RESPONSE], 0, DT_NO_RESPONSE, this);
- DT_AddPairResponse(m_fixRespTable, m_ResponseClass[OBJECT_RESPONSE], m_ResponseClass[STATIC_RESPONSE], SM_Object::fix, DT_SIMPLE_RESPONSE, this);
- DT_AddPairResponse(m_fixRespTable, m_ResponseClass[OBJECT_RESPONSE], m_ResponseClass[OBJECT_RESPONSE], SM_Object::fix, DT_SIMPLE_RESPONSE, this);
+ DT_AddPairResponse(m_fixRespTable, m_ResponseClass[OBJECT_RESPONSE], m_ResponseClass[STATIC_RESPONSE], SM_Object::fix, DT_BROAD_RESPONSE, this);
+ DT_AddPairResponse(m_fixRespTable, m_ResponseClass[OBJECT_RESPONSE], m_ResponseClass[OBJECT_RESPONSE], SM_Object::fix, DT_BROAD_RESPONSE, this);
DT_AddPairResponse(m_fixRespTable, m_ResponseClass[OBJECT_RESPONSE], m_ResponseClass[FH_RESPONSE], 0, DT_NO_RESPONSE, this);
}
void SM_Scene::addTouchCallback(int response_class, DT_ResponseCallback callback, void *user)
{
- DT_AddClassResponse(m_secondaryRespTable, m_secondaryResponseClass[response_class], callback, DT_SIMPLE_RESPONSE, user);
+ DT_AddClassResponse(m_secondaryRespTable, m_secondaryResponseClass[response_class], callback, DT_BROAD_RESPONSE, user);
}
void SM_Scene::addSensor(SM_Object& object)
@@ -161,11 +161,27 @@ void SM_Scene::remove(SM_Object& object) {
}
}
-void SM_Scene::proceed(MT_Scalar curtime, MT_Scalar ticrate) {
+void SM_Scene::beginFrame()
+{
+ T_ObjectList::iterator i;
+ // Apply a forcefield (such as gravity)
+ for (i = m_objectList.begin(); i != m_objectList.end(); ++i)
+ (*i)->applyForceField(m_forceField);
+
+}
+
+void SM_Scene::endFrame()
+{
+ T_ObjectList::iterator i;
+ for (i = m_objectList.begin(); i != m_objectList.end(); ++i)
+ (*i)->clearForce();
+}
+
+bool SM_Scene::proceed(MT_Scalar curtime, MT_Scalar ticrate) {
if (m_lastTime < 0.0)
{
m_lastTime = curtime;
- return;
+ return false;
}
// Divide the timeStep into a number of subsamples of size roughly
@@ -177,7 +193,7 @@ void SM_Scene::proceed(MT_Scalar curtime, MT_Scalar ticrate) {
T_ObjectList::iterator i;
// No timestep! (should do a mini update)
- if (!num_samples)
+ if (num_samples <= 0)
{
// Apply a forcefield (such as gravity)
#if 0
@@ -191,7 +207,7 @@ void SM_Scene::proceed(MT_Scalar curtime, MT_Scalar ticrate) {
//(*i)->clearForce();
}
#endif
- return;
+ return false;
}
m_lastTime += MT_Scalar(num_samples)*subStep;
@@ -201,9 +217,8 @@ void SM_Scene::proceed(MT_Scalar curtime, MT_Scalar ticrate) {
for (step = 0; step != num_samples; ++step) {
for (i = m_objectList.begin(); i != m_objectList.end(); ++i) {
- (*i)->beginFrame();
// Apply a forcefield (such as gravity)
- (*i)->applyForceField(m_forceField);
+ //(*i)->applyForceField(m_forceField);
//(*i)->setTimeStep(timeStep);
(*i)->integrateForces(subStep);
// And second we update the object positions by performing
@@ -235,7 +250,7 @@ void SM_Scene::proceed(MT_Scalar curtime, MT_Scalar ticrate) {
(*i)->relax();
(*i)->proceedKinematic(subStep);
(*i)->saveReactionForce(subStep);
- (*i)->clearForce();
+ //(*i)->clearForce();
}
}
// For each pair of object that collided, call the corresponding callback.
@@ -252,6 +267,8 @@ void SM_Scene::proceed(MT_Scalar curtime, MT_Scalar ticrate) {
}
clearPairs();
+
+ return true;
}
SM_Object *SM_Scene::rayTest(void *ignore_client,
diff --git a/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp b/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp
index 151c55d75de..f035bfb4cf2 100644
--- a/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp
+++ b/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp
@@ -62,9 +62,19 @@ MT_Scalar SumoPhysicsEnvironment::getTicRate()
return PhysicsTicRate;
}
-void SumoPhysicsEnvironment::proceed(double curtime)
+void SumoPhysicsEnvironment::beginFrame()
{
- m_sumoScene->proceed(curtime, PhysicsTicRate);
+ m_sumoScene->beginFrame();
+}
+
+void SumoPhysicsEnvironment::endFrame()
+{
+ m_sumoScene->endFrame();
+}
+
+bool SumoPhysicsEnvironment::proceed(double curtime)
+{
+ return m_sumoScene->proceed(curtime, PhysicsTicRate);
}
void SumoPhysicsEnvironment::setGravity(float x,float y,float z)
diff --git a/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h b/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h
index 09ffe6ce112..aba341360f9 100644
--- a/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h
+++ b/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h
@@ -48,8 +48,10 @@ class SumoPhysicsEnvironment : public PHY_IPhysicsEnvironment
public:
SumoPhysicsEnvironment();
virtual ~SumoPhysicsEnvironment();
+ virtual void beginFrame();
+ virtual void endFrame();
// Perform an integration step of duration 'timeStep'.
- virtual void proceed(double curtime);
+ virtual bool proceed(double curtime);
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,
diff --git a/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h b/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h
index 1eabc4bfd64..0fdac35f514 100644
--- a/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h
+++ b/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h
@@ -43,8 +43,10 @@ class PHY_IPhysicsEnvironment
{
public:
virtual ~PHY_IPhysicsEnvironment();
+ virtual void beginFrame() = 0;
+ virtual void endFrame() = 0;
/// Perform an integration step of duration 'timeStep'.
- virtual void proceed(double timeStep)=0;
+ virtual bool proceed(double timeStep)=0;
virtual void setGravity(float x,float y,float z)=0;
virtual int createConstraint(class PHY_IPhysicsController* ctrl,class PHY_IPhysicsController* ctrl2,PHY_ConstraintType type,