diff options
Diffstat (limited to 'source/gameengine/Physics/Sumo/Fuzzics/src/SM_Scene.cpp')
-rw-r--r-- | source/gameengine/Physics/Sumo/Fuzzics/src/SM_Scene.cpp | 193 |
1 files changed, 160 insertions, 33 deletions
diff --git a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Scene.cpp b/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Scene.cpp index 424796ea71e..5ac65cbd816 100644 --- a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Scene.cpp +++ b/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Scene.cpp @@ -2,6 +2,34 @@ * $Id$ * Copyright (C) 2001 NaN Technologies B.V. * The physics scene. + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ #ifdef HAVE_CONFIG_H @@ -16,31 +44,101 @@ #include "SM_Object.h" #include "SM_FhObject.h" +#include "SM_Debug.h" + #include <algorithm> +SM_Scene::SM_Scene() : + m_scene(DT_CreateScene()), + m_respTable(DT_CreateRespTable()), + m_secondaryRespTable(DT_CreateRespTable()), + m_fixRespTable(DT_CreateRespTable()), + m_forceField(0.0, 0.0, 0.0) +{ + for (int i = 0 ; i < NUM_RESPONSE; i++) + { + m_ResponseClass[i] = DT_GenResponseClass(m_respTable); + m_secondaryResponseClass[i] = DT_GenResponseClass(m_secondaryRespTable); + m_fixResponseClass[i] = DT_GenResponseClass(m_fixRespTable); + } + + /* 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[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[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); + + /* 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); + + /* 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[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[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); +} + +void SM_Scene::addSensor(SM_Object& object) +{ + object.calcXform(); + m_objectList.push_back(&object); + DT_AddObject(m_scene, object.getObjectHandle()); + DT_SetResponseClass(m_respTable, object.getObjectHandle(), m_ResponseClass[SENSOR_RESPONSE]); + DT_SetResponseClass(m_secondaryRespTable, object.getObjectHandle(), m_secondaryResponseClass[SENSOR_RESPONSE]); + DT_SetResponseClass(m_fixRespTable, object.getObjectHandle(), m_fixResponseClass[SENSOR_RESPONSE]); +} + void SM_Scene::add(SM_Object& object) { object.calcXform(); m_objectList.push_back(&object); DT_AddObject(m_scene, object.getObjectHandle()); if (object.isDynamic()) { - DT_SetObjectResponse(m_respTable, object.getObjectHandle(), - SM_Object::boing, DT_SIMPLE_RESPONSE, this); - } + DT_SetResponseClass(m_respTable, object.getObjectHandle(), m_ResponseClass[OBJECT_RESPONSE]); + DT_SetResponseClass(m_secondaryRespTable, object.getObjectHandle(), m_secondaryResponseClass[OBJECT_RESPONSE]); + DT_SetResponseClass(m_fixRespTable, object.getObjectHandle(), m_fixResponseClass[OBJECT_RESPONSE]); + } else { + DT_SetResponseClass(m_respTable, object.getObjectHandle(), m_ResponseClass[STATIC_RESPONSE]); + DT_SetResponseClass(m_secondaryRespTable, object.getObjectHandle(), m_secondaryResponseClass[STATIC_RESPONSE]); + DT_SetResponseClass(m_fixRespTable, object.getObjectHandle(), m_fixResponseClass[STATIC_RESPONSE]); + } - if (object.getDynamicParent()) { - DT_SetPairResponse(m_respTable, object.getObjectHandle(), - object.getDynamicParent()->getObjectHandle(), - 0, DT_NO_RESPONSE, 0); - } SM_FhObject *fh_object = object.getFhObject(); if (fh_object) { DT_AddObject(m_scene, fh_object->getObjectHandle()); - DT_SetObjectResponse(m_respTable, fh_object->getObjectHandle(), - SM_FhObject::ray_hit, DT_SIMPLE_RESPONSE, this); + DT_SetResponseClass(m_respTable, fh_object->getObjectHandle(), m_ResponseClass[FH_RESPONSE]); + DT_SetResponseClass(m_secondaryRespTable, fh_object->getObjectHandle(), m_secondaryResponseClass[FH_RESPONSE]); + DT_SetResponseClass(m_fixRespTable, fh_object->getObjectHandle(), m_fixResponseClass[FH_RESPONSE]); } } +void SM_Scene::requestCollisionCallback(SM_Object &object) +{ + DT_SetResponseClass(m_respTable, object.getObjectHandle(), m_ResponseClass[OBJECT_RESPONSE]); + DT_SetResponseClass(m_secondaryRespTable, object.getObjectHandle(), m_secondaryResponseClass[OBJECT_RESPONSE]); +// DT_SetResponseClass(m_fixRespTable, object.getObjectHandle(), m_fixResponseClass[OBJECT_RESPONSE]); +} + void SM_Scene::remove(SM_Object& object) { T_ObjectList::iterator i = std::find(m_objectList.begin(), m_objectList.end(), &object); @@ -49,21 +147,11 @@ void SM_Scene::remove(SM_Object& object) { std::swap(*i, m_objectList.back()); m_objectList.pop_back(); DT_RemoveObject(m_scene, object.getObjectHandle()); - if (object.isDynamic()) { - DT_ClearObjectResponse(m_respTable, object.getObjectHandle()); - } - - if (object.getDynamicParent()) { - DT_ClearPairResponse(m_respTable, object.getObjectHandle(), - object.getDynamicParent()->getObjectHandle()); - } SM_FhObject *fh_object = object.getFhObject(); if (fh_object) { DT_RemoveObject(m_scene, fh_object->getObjectHandle()); - DT_ClearObjectResponse(m_respTable, - fh_object->getObjectHandle()); } } else { @@ -81,29 +169,28 @@ void SM_Scene::proceed(MT_Scalar timeStep, MT_Scalar subSampling) { // equal to subSampling (might be a little smaller). int num_samples = (int)ceil(timeStep / subSampling); - MT_Scalar subStep = timeStep / num_samples; T_ObjectList::iterator i; // Apply a forcefield (such as gravity) for (i = m_objectList.begin(); i != m_objectList.end(); ++i) { (*i)->applyForceField(m_forceField); + //(*i)->integrateForces(subStep); + //(*i)->integrateMomentum(subStep); } // Do the integration steps per object. int step; for (step = 0; step != num_samples; ++step) { + for (i = m_objectList.begin(); i != m_objectList.end(); ++i) { (*i)->integrateForces(subStep); - } - + //(*i)->backup(); // And second we update the object positions by performing // an integration step for each object - for (i = m_objectList.begin(); i != m_objectList.end(); ++i) { (*i)->integrateMomentum(subStep); } -#if 0 // I changed the order of the next 2 statements. // Originally objects were first integrated with a call // to proceed(). However if external objects were @@ -113,17 +200,18 @@ void SM_Scene::proceed(MT_Scalar timeStep, MT_Scalar subSampling) { // So now first we let the physics scene respond to // new forces, velocities set externally. -#endif // The collsion and friction impulses are computed here. DT_Test(m_scene, m_respTable); - } - // clear the user set velocities. #if 0 clearObjectCombinedVelocities(); #endif + for (step = 0; step < 5 && DT_Test(m_scene, m_fixRespTable); step++) + for (i = m_objectList.begin(); i != m_objectList.end(); ++i) + (*i)->relax(); + // Finish this timestep by saving al state information for the next // timestep and clearing the accumulated forces. @@ -132,7 +220,7 @@ void SM_Scene::proceed(MT_Scalar timeStep, MT_Scalar subSampling) { (*i)->saveReactionForce(timeStep); (*i)->clearForce(); } - + // For each pair of object that collided, call the corresponding callback. // Additional collisions of a pair within the same time step are ignored. @@ -152,14 +240,25 @@ void SM_Scene::proceed(MT_Scalar timeStep, MT_Scalar subSampling) { SM_Object *SM_Scene::rayTest(void *ignore_client, const MT_Point3& from, const MT_Point3& to, MT_Point3& result, MT_Vector3& normal) const { - MT_Point3 local; +#ifdef SM_DEBUG_RAYCAST + std::cout << "ray: { " << from << " } - { " << to << " }" << std::endl; +#endif + DT_Vector3 n, dfrom, dto; + DT_Scalar param; + from.getValue(dfrom); + to.getValue(dto); SM_Object *hit_object = (SM_Object *) - DT_RayTest(m_scene, ignore_client, from.getValue(), to.getValue(), - local.getValue(), normal.getValue()); + DT_RayCast(m_scene, ignore_client, dfrom, dto, 1., ¶m, n); if (hit_object) { - result = hit_object->getWorldCoord(local); + //result = hit_object->getWorldCoord(from + (to - from)*param); + result = from + (to - from) * param; + normal.setValue(n); +#ifdef SM_DEBUG_RAYCAST + std::cout << "ray: { " << from << " } -> { " << to << " }: { " << result + << " } (" << param << "), normal = { " << normal << " }" << std::endl; +#endif } return hit_object; @@ -178,6 +277,34 @@ void SM_Scene::clearObjectCombinedVelocities() { } +void SM_Scene::setSecondaryRespTable(DT_RespTableHandle secondaryRespTable) { + m_secondaryRespTable = secondaryRespTable; +} +DT_Bool SM_Scene::boing( + void *client_data, + void *object1, + void *object2, + const DT_CollData *coll_data +){ + 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 +#ifdef SM_DEBUG_BOING + printf("SM_Scene::boing\n"); +#endif + + return DT_CONTINUE; +} + +SM_Scene::~SM_Scene() +{ +/* if (m_objectList.begin() != m_objectList.end()) + std::cout << "SM_Scene::~SM_Scene: There are still objects in the Sumo scene!" << std::endl; */ + DT_DestroyRespTable(m_respTable); + DT_DestroyScene(m_scene); +} |