From c844aa265ad4eb50ad0e18661470fa6092052728 Mon Sep 17 00:00:00 2001 From: Kester Maddock Date: Fri, 25 Mar 2005 10:33:39 +0000 Subject: [PATCH] Big patches: Erwin Coumans: Abstract the physics engine Charlie C: Joystick fixes Me: Moved the ray cast (shadows, mouse sensor & ray sensor) --- .../BlenderRoutines/BL_KetsjiEmbedStart.cpp | 4 +- .../BlenderRoutines/KX_BlenderRenderTools.cpp | 63 +++--- .../BlenderRoutines/KX_BlenderRenderTools.h | 4 + .../gameengine/Converter/BL_ActionActuator.h | 6 +- .../Converter/KX_BlenderSceneConverter.cpp | 10 +- .../Converter/KX_ConvertSensors.cpp | 24 +- source/gameengine/Expressions/InputParser.cpp | 14 +- source/gameengine/Expressions/Makefile | 3 +- .../gameengine/Expressions/PyObjectPlus.cpp | 4 +- source/gameengine/Expressions/PyObjectPlus.h | 2 +- source/gameengine/Expressions/SConscript | 3 +- source/gameengine/Expressions/Value.cpp | 2 +- .../GameLogic/Joystick/SCA_Joystick.cpp | 12 +- .../GameLogic/Joystick/SCA_JoystickEvents.cpp | 4 +- source/gameengine/GameLogic/Makefile | 2 +- .../GameLogic/SCA_JoystickManager.cpp | 21 +- .../GameLogic/SCA_JoystickManager.h | 5 +- .../GameLogic/SCA_JoystickSensor.cpp | 86 +++++--- .../GamePlayer/common/GPC_RenderTools.cpp | 62 +++--- .../GamePlayer/common/GPC_RenderTools.h | 3 + .../GamePlayer/ghost/GPG_Application.cpp | 10 +- .../Ketsji/KX_ConvertPhysicsObjects.cpp | 83 +++---- source/gameengine/Ketsji/KX_GameObject.cpp | 32 +-- source/gameengine/Ketsji/KX_GameObject.h | 2 +- .../gameengine/Ketsji/KX_IPO_SGController.cpp | 23 +- .../gameengine/Ketsji/KX_IPO_SGController.h | 6 - .../Ketsji/KX_IPhysicsController.cpp | 6 +- .../gameengine/Ketsji/KX_IPhysicsController.h | 7 +- source/gameengine/Ketsji/KX_KetsjiEngine.cpp | 25 ++- source/gameengine/Ketsji/KX_KetsjiEngine.h | 2 +- .../gameengine/Ketsji/KX_MouseFocusSensor.cpp | 207 +++++++++++------- .../gameengine/Ketsji/KX_MouseFocusSensor.h | 2 + source/gameengine/Ketsji/KX_NearSensor.cpp | 82 +++---- source/gameengine/Ketsji/KX_NearSensor.h | 13 +- .../Ketsji/KX_OdePhysicsController.cpp | 6 +- .../Ketsji/KX_OdePhysicsController.h | 4 +- .../gameengine/Ketsji/KX_PolygonMaterial.cpp | 2 +- .../Ketsji/KX_PyConstraintBinding.cpp | 24 +- .../Ketsji/KX_PyConstraintBinding.h | 2 + source/gameengine/Ketsji/KX_PythonInit.cpp | 7 +- source/gameengine/Ketsji/KX_RadarSensor.cpp | 21 +- source/gameengine/Ketsji/KX_RadarSensor.h | 1 + source/gameengine/Ketsji/KX_RayCast.cpp | 97 ++++++++ source/gameengine/Ketsji/KX_RayCast.h | 107 +++++++++ source/gameengine/Ketsji/KX_RaySensor.cpp | 194 ++++++++-------- source/gameengine/Ketsji/KX_RaySensor.h | 4 + .../Ketsji/KX_SG_NodeRelationships.cpp | 6 +- source/gameengine/Ketsji/KX_Scene.cpp | 24 +- source/gameengine/Ketsji/KX_Scene.h | 2 +- source/gameengine/Ketsji/KX_SoundActuator.cpp | 2 + .../Ketsji/KX_SumoPhysicsController.cpp | 11 +- .../Ketsji/KX_SumoPhysicsController.h | 6 +- .../Ketsji/KX_TouchEventManager.cpp | 81 +++---- .../gameengine/Ketsji/KX_TouchEventManager.h | 33 +-- source/gameengine/Ketsji/KX_TouchSensor.cpp | 53 +++-- source/gameengine/Ketsji/KX_TouchSensor.h | 19 +- source/gameengine/Ketsji/SConscript | 1 + .../NG_LoopBackNetworkDeviceInterface.cpp | 9 +- source/gameengine/Network/Makefile | 1 + source/gameengine/Network/NG_NetworkScene.cpp | 4 +- source/gameengine/Network/SConscript | 3 +- .../Physics/BlOde/OdePhysicsController.cpp | 6 + .../Physics/BlOde/OdePhysicsController.h | 14 +- .../Physics/BlOde/OdePhysicsEnvironment.cpp | 74 +++++-- .../Physics/BlOde/OdePhysicsEnvironment.h | 28 ++- .../Physics/Dummy/DummyPhysicsEnvironment.cpp | 17 +- .../Physics/Dummy/DummyPhysicsEnvironment.h | 18 +- .../Physics/Sumo/Fuzzics/include/SM_Object.h | 10 +- .../Physics/Sumo/Fuzzics/src/SM_Object.cpp | 12 +- .../Physics/Sumo/Fuzzics/src/SM_Scene.cpp | 4 +- .../Physics/Sumo/SumoPhysicsController.cpp | 88 +++++++- .../Physics/Sumo/SumoPhysicsController.h | 18 +- .../Physics/Sumo/SumoPhysicsEnvironment.cpp | 167 ++++++++++++-- .../Physics/Sumo/SumoPhysicsEnvironment.h | 28 ++- .../Physics/common/PHY_DynamicTypes.h | 48 ++++ .../Physics/common/PHY_IPhysicsController.h | 18 +- .../Physics/common/PHY_IPhysicsEnvironment.h | 20 +- source/gameengine/PyDoc/KX_PolygonMaterial.py | 9 +- 78 files changed, 1411 insertions(+), 726 deletions(-) create mode 100644 source/gameengine/Ketsji/KX_RayCast.cpp create mode 100644 source/gameengine/Ketsji/KX_RayCast.h diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp index f0eb36107e8..ca908f86344 100644 --- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp +++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp @@ -346,7 +346,6 @@ extern "C" void StartKetsjiShell(struct ScrArea *area, // clean up some stuff audiodevice->StopCD(); - SND_DeviceManager::Unsubscribe(); if (ketsjiengine) { @@ -388,6 +387,9 @@ extern "C" void StartKetsjiShell(struct ScrArea *area, delete canvas; canvas = NULL; } + + SND_DeviceManager::Unsubscribe(); + } while (exitrequested == KX_EXIT_REQUEST_RESTART_GAME || exitrequested == KX_EXIT_REQUEST_START_OTHER_GAME); if (bfd) BLO_blendfiledata_free(bfd); diff --git a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp index d8a89461031..e35ec6f41ef 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp +++ b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp @@ -47,7 +47,6 @@ #include "RAS_ICanvas.h" #include "RAS_GLExtensionManager.h" - // next two includes/dependencies come from the shadow feature // it needs the gameobject and the sumo physics scene for a raycast #include "KX_GameObject.h" @@ -60,9 +59,9 @@ #include "STR_String.h" #include "RAS_BucketManager.h" // for polymaterial (needed for textprinting) -#include "SM_Scene.h" -#include "SumoPhysicsEnvironment.h" -#include "KX_SumoPhysicsController.h" +#include "KX_RayCast.h" +#include "KX_IPhysicsController.h" +#include "PHY_IPhysicsEnvironment.h" #include "KX_Scene.h" KX_BlenderRenderTools::KX_BlenderRenderTools() @@ -125,7 +124,27 @@ void KX_BlenderRenderTools::BeginFrame(RAS_IRasterizer* rasty) } + +bool KX_BlenderRenderTools::RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_Vector3& hit_normal, void * const data) +{ + double* const oglmatrix = (double* const) data; + MT_Point3 resultpoint(hit_point); + MT_Vector3 resultnormal(hit_normal); + MT_Vector3 left(oglmatrix[0],oglmatrix[1],oglmatrix[2]); + MT_Vector3 dir = -(left.cross(resultnormal)).safe_normalized(); + left = (dir.cross(resultnormal)).safe_normalized(); + // for the up vector, we take the 'resultnormal' returned by the physics + double maat[16]={ + left[0], left[1], left[2], 0, + dir[0], dir[1], dir[2], 0, + resultnormal[0],resultnormal[1],resultnormal[2], 0, + 0, 0, 0, 1}; + glTranslated(resultpoint[0],resultpoint[1],resultpoint[2]); + //glMultMatrixd(oglmatrix); + glMultMatrixd(maat); + return true; +} void KX_BlenderRenderTools::applyTransform(RAS_IRasterizer* rasty,double* oglmatrix,int objectdrawmode ) { @@ -196,44 +215,26 @@ void KX_BlenderRenderTools::applyTransform(RAS_IRasterizer* rasty,double* oglmat KX_GameObject *gameobj = (KX_GameObject*) this->m_clientobject; MT_Vector3 direction = MT_Vector3(0,0,-1); - direction.normalize(); direction *= 100000; MT_Point3 topoint = frompoint + direction; - MT_Point3 resultpoint; - MT_Vector3 resultnormal; - //todo: - //use physics abstraction KX_Scene* kxscene = (KX_Scene*) m_auxilaryClientInfo; - SumoPhysicsEnvironment *spe = dynamic_cast( kxscene->GetPhysicsEnvironment()); - SM_Scene *scene = spe->GetSumoScene(); - KX_SumoPhysicsController *spc = dynamic_cast( gameobj->GetPhysicsController()); + PHY_IPhysicsEnvironment* physics_environment = kxscene->GetPhysicsEnvironment(); + KX_IPhysicsController* physics_controller = gameobj->GetPhysicsController(); + KX_GameObject *parent = gameobj->GetParent(); - if (!spc && parent) - spc = dynamic_cast(parent->GetPhysicsController()); + if (!physics_controller && parent) + physics_controller = parent->GetPhysicsController(); if (parent) parent->Release(); - SM_Object *thisObj = spc?spc->GetSumoObject():NULL; - - if (scene->rayTest(thisObj, frompoint, topoint, resultpoint, resultnormal)) - { - MT_Vector3 left(oglmatrix[0],oglmatrix[1],oglmatrix[2]); - MT_Vector3 dir = -(left.cross(resultnormal)).safe_normalized(); - left = (dir.cross(resultnormal)).safe_normalized(); - // for the up vector, we take the 'resultnormal' returned by the physics - double maat[16]={ - left[0], left[1], left[2], 0, - dir[0], dir[1], dir[2], 0, - resultnormal[0],resultnormal[1],resultnormal[2], 0, - 0, 0, 0, 1}; - glTranslated(resultpoint[0],resultpoint[1],resultpoint[2]); - //glMultMatrixd(oglmatrix); - glMultMatrixd(maat); - } else + MT_Point3 resultpoint; + MT_Vector3 resultnormal; + if (!KX_RayCast::RayTest(physics_controller, physics_environment, frompoint, topoint, resultpoint, resultnormal, KX_RayCast::Callback(this, oglmatrix))) { + // couldn't find something to cast the shadow on... glMultMatrixd(oglmatrix); } } else diff --git a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h index 48b1ca42357..dc638d1a43a 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h +++ b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h @@ -39,6 +39,8 @@ #include "RAS_IRenderTools.h" +struct KX_ClientObjectInfo; + /** BlenderRenderTools are a set of tools to apply 2D/3D graphics effects, which are not part of the (polygon) Rasterizer. @@ -96,6 +98,8 @@ public: bool bIsTriangle, void* clientobject, void* tface); + + bool RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_Vector3& hit_normal, void * const data); }; #endif //__KX_BLENDERRENDERTOOLS diff --git a/source/gameengine/Converter/BL_ActionActuator.h b/source/gameengine/Converter/BL_ActionActuator.h index 5587cbd9c5e..f96855408b7 100644 --- a/source/gameengine/Converter/BL_ActionActuator.h +++ b/source/gameengine/Converter/BL_ActionActuator.h @@ -58,9 +58,11 @@ public: m_flag(0), m_startframe (starttime), m_endframe(endtime) , + m_starttime(0), m_localtime(starttime), m_lastUpdate(-1), m_blendin(blendin), + m_blendstart(0), m_stridelength(stride), m_playtype(playtype), m_priority(priority), @@ -73,8 +75,8 @@ public: }; virtual ~BL_ActionActuator(); virtual bool Update(double curtime, bool frame); - CValue* GetReplica(); - void ProcessReplica(); + virtual CValue* GetReplica(); + virtual void ProcessReplica(); void SetBlendTime (float newtime); diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp index 6b3cbbea2e5..53b775b8920 100644 --- a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp +++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp @@ -152,7 +152,6 @@ bool KX_BlenderSceneConverter::TryAndLoadNewFile() * Find the specified scene by name, or the first * scene if nothing matches (shouldn't happen). */ -#if 0 static struct Scene *GetSceneForName2(struct Main *maggie, const STR_String& scenename) { Scene *sce; @@ -162,7 +161,7 @@ static struct Scene *GetSceneForName2(struct Main *maggie, const STR_String& sce return (Scene*) maggie->scene.first; } -#endif + void KX_BlenderSceneConverter::ConvertScene(const STR_String& scenename, class KX_Scene* destinationscene, @@ -172,12 +171,10 @@ void KX_BlenderSceneConverter::ConvertScene(const STR_String& scenename, class RAS_ICanvas* canvas) { //find out which physics engine - // Scene *blenderscene = GetSceneForName2(m_maggie, scenename); /*unused*/ + Scene *blenderscene = GetSceneForName2(m_maggie, scenename); e_PhysicsEngine physics_engine = UseSumo; - /* FIXME: Force physics engine = sumo. - This isn't really a problem - no other physics engines are available. if (blenderscene) { int i=0; @@ -210,7 +207,7 @@ void KX_BlenderSceneConverter::ConvertScene(const STR_String& scenename, } } - */ + switch (physics_engine) { @@ -220,6 +217,7 @@ void KX_BlenderSceneConverter::ConvertScene(const STR_String& scenename, break; #endif #ifdef USE_ODE + case UseODE: destinationscene ->SetPhysicsEnvironment(new ODEPhysicsEnvironment()); break; diff --git a/source/gameengine/Converter/KX_ConvertSensors.cpp b/source/gameengine/Converter/KX_ConvertSensors.cpp index 396d633043c..450f4c0b523 100644 --- a/source/gameengine/Converter/KX_ConvertSensors.cpp +++ b/source/gameengine/Converter/KX_ConvertSensors.cpp @@ -79,6 +79,7 @@ probably misplaced */ #include "KX_BlenderKeyboardDevice.h" #include "KX_BlenderGL.h" #include "RAS_ICanvas.h" +#include "PHY_IPhysicsEnvironment.h" #include "KX_KetsjiEngine.h" #include "KX_BlenderSceneConverter.h" @@ -374,11 +375,23 @@ void BL_ConvertSensors(struct Object* blenderobject, // this sumoObject is not deleted by a gameobj, so delete it ourself // later (memleaks)! - //SM_Object* sumoObj = new SM_Object(shape,NULL,NULL,NULL); - //sumoObj->setMargin(blendernearsensor->dist); - //sumoObj->setPosition(gameobj->NodeGetWorldPosition()); + float radius = blendernearsensor->dist; + PHY__Vector3 pos; + const MT_Vector3& wpos = gameobj->NodeGetWorldPosition(); + pos[0] = wpos[0]; + pos[1] = wpos[1]; + pos[2] = wpos[2]; + pos[3] = 0.f; bool bFindMaterial = false; - gamesensor = new KX_NearSensor(eventmgr,gameobj,blendernearsensor->dist,blendernearsensor->resetdist,bFindMaterial,nearpropertyname,kxscene); + PHY_IPhysicsController* physCtrl = kxscene->GetPhysicsEnvironment()->CreateSphereController(radius,pos); + + gamesensor = new KX_NearSensor(eventmgr,gameobj, + blendernearsensor->dist, + blendernearsensor->resetdist, + bFindMaterial, + nearpropertyname,kxscene, + physCtrl + ); } break; @@ -551,9 +564,12 @@ void BL_ConvertSensors(struct Object* blenderobject, MT_Scalar largemargin = 0.0; bool bFindMaterial = false; + PHY_IPhysicsController* ctrl = kxscene->GetPhysicsEnvironment()->CreateConeController(coneradius,coneheight); + gamesensor = new KX_RadarSensor( eventmgr, gameobj, + ctrl, coneradius, coneheight, radaraxis, diff --git a/source/gameengine/Expressions/InputParser.cpp b/source/gameengine/Expressions/InputParser.cpp index 090c95e3c07..24033dd21a2 100644 --- a/source/gameengine/Expressions/InputParser.cpp +++ b/source/gameengine/Expressions/InputParser.cpp @@ -14,6 +14,8 @@ #include +#include "MT_assert.h" + #include "Value.h" #include "InputParser.h" #include "ErrorValue.h" @@ -371,7 +373,7 @@ int CParser::Priority(int optorkind) { case OPtimes: case OPdivide: return 5; } - assert(false); + MT_assert(false); return 0; // should not happen } @@ -400,7 +402,7 @@ CExpression *CParser::Ex(int i) { case OPless: e1 = new COperator2Expr(VALUE_LES_OPERATOR,e1, e2); break; case OPgreaterequal: e1 = new COperator2Expr(VALUE_GEQ_OPERATOR,e1, e2); break; case OPlessequal: e1 = new COperator2Expr(VALUE_LEQ_OPERATOR,e1, e2); break; - default: assert(false); break; // should not happen + default: MT_assert(false); break; // should not happen } } } else if (i == NUM_PRIORITY) { @@ -445,7 +447,7 @@ CExpression *CParser::Ex(int i) { e1 = new CConstExpr(new CStringValue(const_as_string,"")); break; default : - assert(false); + MT_assert(false); break; } NextSym(); @@ -483,7 +485,7 @@ CExpression *CParser::Ex(int i) { } case errorsym: { - assert(!e1); + MT_assert(!e1); STR_String errtext="[no info]"; if (errmsg) { @@ -498,7 +500,7 @@ CExpression *CParser::Ex(int i) { errmsg=NULL; } else { // does this happen ? - assert ("does this happen"); + MT_assert ("does this happen"); } } e1 = Error(errtext); @@ -508,7 +510,7 @@ CExpression *CParser::Ex(int i) { default: NextSym(); //return Error("Expression expected"); - assert(!e1); + MT_assert(!e1); e1 = Error("Expression expected"); } } diff --git a/source/gameengine/Expressions/Makefile b/source/gameengine/Expressions/Makefile index 88746c18eae..18dca9a1c68 100644 --- a/source/gameengine/Expressions/Makefile +++ b/source/gameengine/Expressions/Makefile @@ -40,6 +40,7 @@ CCFLAGS += $(LEVEL_1_CPP_WARNINGS) CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION) -CPPFLAGS += -I$(NAN_STRING)/include +CPPFLAGS += -I$(NAN_STRING)/include +CPPFLAGS += -I$(NAN_MOTO)/include CPPFLAGS += -I../../kernel/gen_system diff --git a/source/gameengine/Expressions/PyObjectPlus.cpp b/source/gameengine/Expressions/PyObjectPlus.cpp index 2b331d7f728..b75da2c12a2 100644 --- a/source/gameengine/Expressions/PyObjectPlus.cpp +++ b/source/gameengine/Expressions/PyObjectPlus.cpp @@ -49,7 +49,7 @@ * http://www.python.org/doc/PyCPP.html * ------------------------------*/ -#include +#include #include "stdlib.h" #include "PyObjectPlus.h" #include "STR_String.h" @@ -79,7 +79,7 @@ PyTypeObject PyObjectPlus::Type = { PyObjectPlus::PyObjectPlus(PyTypeObject *T) // constructor { - assert(T != NULL); + MT_assert(T != NULL); this->ob_type = T; _Py_NewReference(this); }; diff --git a/source/gameengine/Expressions/PyObjectPlus.h b/source/gameengine/Expressions/PyObjectPlus.h index 7e6b3f29bab..8784d28d502 100644 --- a/source/gameengine/Expressions/PyObjectPlus.h +++ b/source/gameengine/Expressions/PyObjectPlus.h @@ -48,7 +48,7 @@ // some basic python macros #define Py_NEWARGS 1 -#define Py_Return Py_INCREF(Py_None); return Py_None; +#define Py_Return { Py_INCREF(Py_None); return Py_None;} #define Py_Error(E, M) {PyErr_SetString(E, M); return NULL;} #define Py_Try(F) {if (!(F)) return NULL;} diff --git a/source/gameengine/Expressions/SConscript b/source/gameengine/Expressions/SConscript index 93a197e085b..212381cc034 100755 --- a/source/gameengine/Expressions/SConscript +++ b/source/gameengine/Expressions/SConscript @@ -26,7 +26,8 @@ source_files = ['BoolValue.cpp', expressions_env.Append (CPPPATH = ['.', '#source/kernel/gen_system', - '#intern/string']) + '#intern/string', + '#intern/moto/include']) expressions_env.Append (CPPPATH = user_options_dict['PYTHON_INCLUDE']) diff --git a/source/gameengine/Expressions/Value.cpp b/source/gameengine/Expressions/Value.cpp index fbb1e9a8c99..1a09123c107 100644 --- a/source/gameengine/Expressions/Value.cpp +++ b/source/gameengine/Expressions/Value.cpp @@ -532,7 +532,7 @@ int CValue::Release() else { // Reference count reached 0, delete ourselves and return 0 -// assert(m_refcount==0, "Reference count reached sub-zero, object released too much"); +// MT_assert(m_refcount==0, "Reference count reached sub-zero, object released too much"); delete this; return 0; } diff --git a/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp b/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp index 7d1d4b28730..02775c58168 100644 --- a/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp +++ b/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp @@ -28,7 +28,7 @@ * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ #include - + #include "SCA_Joystick.h" #include "SCA_JoystickPrivate.h" @@ -47,11 +47,14 @@ SCA_Joystick::SCA_Joystick() m_private = new PrivateData(); } + SCA_Joystick::~SCA_Joystick() + { delete m_private; } + bool SCA_Joystick::CreateJoystickDevice() { bool init = false; @@ -66,6 +69,7 @@ void SCA_Joystick::DestroyJoystickDevice() pDestroyJoystickDevice(); } + void SCA_Joystick::HandleEvents() { if(m_isinit) @@ -91,6 +95,7 @@ void SCA_Joystick::cSetPrecision(int val) m_prec = val; } + bool SCA_Joystick::aRightAxisIsPositive(int axis) { bool result; @@ -164,7 +169,6 @@ int SCA_Joystick::pGetButtonPress(int button) if(button == m_buttonnum) return m_buttonnum; return -2; - } @@ -279,6 +283,7 @@ int SCA_Joystick::GetNumberOfButtons() return -1; } + int SCA_Joystick::GetNumberOfHats() { int number; @@ -291,7 +296,6 @@ int SCA_Joystick::GetNumberOfHats() return -1; } - bool SCA_Joystick::pCreateJoystickDevice() { if(m_isinit == false){ @@ -328,6 +332,7 @@ void SCA_Joystick::pDestroyJoystickDevice() SDL_QuitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_VIDEO ); } + void SCA_Joystick::pFillAxes() { if(GetNumberOfAxes() == 1){ @@ -344,6 +349,7 @@ void SCA_Joystick::pFillAxes() } } + int SCA_Joystick::pGetAxis(int axisnum, int udlr) { if(axisnum == 1 && udlr == 1)return m_axis10; //u/d diff --git a/source/gameengine/GameLogic/Joystick/SCA_JoystickEvents.cpp b/source/gameengine/GameLogic/Joystick/SCA_JoystickEvents.cpp index 90bb728936b..5fd8510d566 100644 --- a/source/gameengine/GameLogic/Joystick/SCA_JoystickEvents.cpp +++ b/source/gameengine/GameLogic/Joystick/SCA_JoystickEvents.cpp @@ -28,10 +28,11 @@ * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ #include - #include "SCA_Joystick.h" #include "SCA_JoystickPrivate.h" + + void SCA_Joystick::OnAxisMotion(void) { pFillAxes(); @@ -70,4 +71,3 @@ void SCA_Joystick::OnNothing(void) { m_istrig = 0; } - diff --git a/source/gameengine/GameLogic/Makefile b/source/gameengine/GameLogic/Makefile index dcf2163a68b..9e6f4515bad 100644 --- a/source/gameengine/GameLogic/Makefile +++ b/source/gameengine/GameLogic/Makefile @@ -35,8 +35,8 @@ LIBNAME = logic DIR = $(OCGDIR)/gameengine/$(LIBNAME) DIRS = Joystick -include nan_compile.mk include nan_subdirs.mk +include nan_compile.mk CCFLAGS += $(LEVEL_1_CPP_WARNINGS) diff --git a/source/gameengine/GameLogic/SCA_JoystickManager.cpp b/source/gameengine/GameLogic/SCA_JoystickManager.cpp index 3637883047d..cf182a0503e 100644 --- a/source/gameengine/GameLogic/SCA_JoystickManager.cpp +++ b/source/gameengine/GameLogic/SCA_JoystickManager.cpp @@ -27,28 +27,31 @@ * * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ - #include "SCA_JoystickSensor.h" #include "SCA_JoystickManager.h" #include "SCA_LogicManager.h" -#include +//#include #include "SCA_ISensor.h" #ifdef HAVE_CONFIG_H #include #endif +//using namespace std; -using namespace std; SCA_JoystickManager::SCA_JoystickManager(class SCA_LogicManager* logicmgr) : SCA_EventManager(JOY_EVENTMGR), m_logicmgr(logicmgr) { - Joystick.CreateJoystickDevice(); + m_joystick = new SCA_Joystick(); + m_joystick->CreateJoystickDevice(); } + + SCA_JoystickManager::~SCA_JoystickManager() { - Joystick.DestroyJoystickDevice(); + m_joystick->DestroyJoystickDevice(); + delete m_joystick; } @@ -59,23 +62,23 @@ void SCA_JoystickManager::NextFrame(double curtime,double deltatime) SCA_JoystickSensor* joysensor = (SCA_JoystickSensor*) m_sensors[i]; if(!joysensor->IsSuspended()) { - Joystick.HandleEvents(); + m_joystick->HandleEvents(); joysensor->Activate(m_logicmgr, NULL); } } } - void SCA_JoystickManager::RegisterSensor(SCA_ISensor* sensor) { m_sensors.push_back(sensor); } -SCA_Joystick SCA_JoystickManager::GetJoystickDevice() + +SCA_Joystick *SCA_JoystickManager::GetJoystickDevice() { /* *Return the instance of SCA_Joystick for use */ - return Joystick; + return m_joystick; } diff --git a/source/gameengine/GameLogic/SCA_JoystickManager.h b/source/gameengine/GameLogic/SCA_JoystickManager.h index c6ca0a4990c..5c892d71f6c 100644 --- a/source/gameengine/GameLogic/SCA_JoystickManager.h +++ b/source/gameengine/GameLogic/SCA_JoystickManager.h @@ -43,14 +43,15 @@ class SCA_JoystickManager : public SCA_EventManager /** * SDL Joystick Class Instance */ - SCA_Joystick Joystick; + SCA_Joystick *m_joystick; public: SCA_JoystickManager(class SCA_LogicManager* logicmgr); virtual ~SCA_JoystickManager(); virtual void NextFrame(double curtime,double deltatime); virtual void RegisterSensor(SCA_ISensor* sensor); - SCA_Joystick GetJoystickDevice(void); + SCA_Joystick* GetJoystickDevice(void); }; #endif + diff --git a/source/gameengine/GameLogic/SCA_JoystickSensor.cpp b/source/gameengine/GameLogic/SCA_JoystickSensor.cpp index d1a35469c3a..40942dd296f 100644 --- a/source/gameengine/GameLogic/SCA_JoystickSensor.cpp +++ b/source/gameengine/GameLogic/SCA_JoystickSensor.cpp @@ -1,4 +1,4 @@ -/** +/* * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** * * This program is free software; you can redistribute it and/or @@ -39,6 +39,7 @@ #include #endif + SCA_JoystickSensor::SCA_JoystickSensor(class SCA_JoystickManager* eventmgr, SCA_IObject* gameobj, short int joymode, @@ -70,13 +71,11 @@ std::cout << " hat flag " << m_hatf << std::endl; } - SCA_JoystickSensor::~SCA_JoystickSensor() { } - CValue* SCA_JoystickSensor::GetReplica() { CValue* replica = new SCA_JoystickSensor(*this); @@ -86,7 +85,6 @@ CValue* SCA_JoystickSensor::GetReplica() } - bool SCA_JoystickSensor::IsPositiveTrigger() { bool result = m_istrig; @@ -94,10 +92,11 @@ bool SCA_JoystickSensor::IsPositiveTrigger() result = !result; return result; } + + bool SCA_JoystickSensor::Evaluate(CValue* event) { - SCA_Joystick js = m_pJoystickMgr->GetJoystickDevice(); - + SCA_Joystick *js = m_pJoystickMgr->GetJoystickDevice(); bool result = false; switch(m_joymode) @@ -111,9 +110,9 @@ bool SCA_JoystickSensor::Evaluate(CValue* event) m_axisf == 3 == down numberof== m_axis -- max 2 */ - js.cSetPrecision(m_precision); + js->cSetPrecision(m_precision); if(m_axisf == 1){ - if(js.aUpAxisIsPositive(m_axis)){ + if(js->aUpAxisIsPositive(m_axis)){ m_istrig =1; result = true; }else{ @@ -124,7 +123,7 @@ bool SCA_JoystickSensor::Evaluate(CValue* event) } } if(m_axisf == 3){ - if(js.aDownAxisIsPositive(m_axis)){ + if(js->aDownAxisIsPositive(m_axis)){ m_istrig = 1; result = true; }else{ @@ -135,7 +134,7 @@ bool SCA_JoystickSensor::Evaluate(CValue* event) } } if(m_axisf == 2){ - if(js.aLeftAxisIsPositive(m_axis)){ + if(js->aLeftAxisIsPositive(m_axis)){ m_istrig = 1; result = true; }else{ @@ -146,7 +145,7 @@ bool SCA_JoystickSensor::Evaluate(CValue* event) } } if(m_axisf == 0){ - if(js.aRightAxisIsPositive(m_axis)){ + if(js->aRightAxisIsPositive(m_axis)){ m_istrig = 1; result = true; }else{ @@ -166,7 +165,7 @@ bool SCA_JoystickSensor::Evaluate(CValue* event) m_button = the actual button in question */ if(m_buttonf == 0){ - if(js.aButtonPressIsPositive(m_button)){ + if(js->aButtonPressIsPositive(m_button)){ m_istrig = 1; result = true; }else { @@ -177,7 +176,7 @@ bool SCA_JoystickSensor::Evaluate(CValue* event) } } if(m_buttonf == 1){ - if(js.aButtonReleaseIsPositive(m_button)){ + if(js->aButtonReleaseIsPositive(m_button)){ m_istrig = 1; result = true; }else { @@ -196,7 +195,7 @@ bool SCA_JoystickSensor::Evaluate(CValue* event) direction= m_hatf -- max 12 */ if(m_hat == 1){ - if(js.aHatIsPositive(m_hatf)){ + if(js->aHatIsPositive(m_hatf)){ m_istrig = 1; result = true; }else{ @@ -204,10 +203,10 @@ bool SCA_JoystickSensor::Evaluate(CValue* event) m_istrig = 0; result = true; } - } + } } if(m_hat == 2){ - if(js.aHatIsPositive(m_hatf)){ + if(js->aHatIsPositive(m_hatf)){ m_istrig = 1; result = true; }else{ @@ -219,7 +218,7 @@ bool SCA_JoystickSensor::Evaluate(CValue* event) } /* if(m_hat == 3){ - if(js.aHatIsPositive(m_hatf)){ + if(js->aHatIsPositive(m_hatf)){ m_istrig = 1; result = true; }else{ @@ -237,7 +236,7 @@ bool SCA_JoystickSensor::Evaluate(CValue* event) printf("Error invalid switch statement\n"); break; } - if(!js.IsTrig()){ + if(!js->IsTrig()){ m_istrig = 0; } return result; @@ -247,12 +246,11 @@ bool SCA_JoystickSensor::Evaluate(CValue* event) bool SCA_JoystickSensor::isValid(SCA_JoystickSensor::KX_JOYSENSORMODE m) { bool res = false; - res = ((m > KX_JOYSENSORMODE_NODEF) && (m < KX_JOYSENSORMODE_MAX)); - return res; } + /* ------------------------------------------------------------------------- */ /* Python functions */ /* ------------------------------------------------------------------------- */ @@ -277,6 +275,7 @@ PyTypeObject SCA_JoystickSensor::Type = { 0 }; + PyParentObject SCA_JoystickSensor::Parents[] = { &SCA_JoystickSensor::Type, &SCA_ISensor::Type, @@ -285,6 +284,7 @@ PyParentObject SCA_JoystickSensor::Parents[] = { NULL }; + PyMethodDef SCA_JoystickSensor::Methods[] = { {"getAxis", (PyCFunction) SCA_JoystickSensor::sPyGetAxis, METH_NOARGS, GetAxis_doc}, {"setAxis", (PyCFunction) SCA_JoystickSensor::sPySetAxis, METH_VARARGS, SetAxis_doc}, @@ -301,10 +301,12 @@ PyMethodDef SCA_JoystickSensor::Methods[] = { {NULL,NULL} //Sentinel }; + PyObject* SCA_JoystickSensor::_getattr(const STR_String& attr) { _getattr_up(SCA_ISensor); } + /* get axis ---------------------------------------------------------- */ char SCA_JoystickSensor::GetAxis_doc[] = "getAxis\n" @@ -314,6 +316,8 @@ PyObject* SCA_JoystickSensor::PyGetAxis( PyObject* self, PyObject* kwds) { return Py_BuildValue("[ii]",m_axis, m_axisf); } + + /* set axis ---------------------------------------------------------- */ char SCA_JoystickSensor::SetAxis_doc[] = "setAxis\n" @@ -330,6 +334,8 @@ PyObject* SCA_JoystickSensor::PySetAxis( PyObject* self, m_axisf = axisflag; Py_Return; } + + /* get axis value ----------------------------------------------------- */ char SCA_JoystickSensor::GetRealAxis_doc[] = "getAxisValue\n" @@ -338,13 +344,15 @@ PyObject* SCA_JoystickSensor::PyGetRealAxis( PyObject* self, PyObject* args, PyObject* kwds) { int a,b,c,d; - SCA_Joystick joy = m_pJoystickMgr->GetJoystickDevice(); - a = joy.GetAxis10(); - b = joy.GetAxis11(); - c = joy.GetAxis20(); - d = joy.GetAxis21(); + SCA_Joystick *joy = m_pJoystickMgr->GetJoystickDevice(); + a = joy->GetAxis10(); + b = joy->GetAxis11(); + c = joy->GetAxis20(); + d = joy->GetAxis21(); return Py_BuildValue("[iiii]",a,b,c,d); } + + /* get threshold ----------------------------------------------------- */ char SCA_JoystickSensor::GetThreshold_doc[] = "getThreshold\n" @@ -354,6 +362,8 @@ PyObject* SCA_JoystickSensor::PyGetThreshold( PyObject* self, PyObject* kwds) { return Py_BuildValue("i", m_precision); } + + /* set threshold ----------------------------------------------------- */ char SCA_JoystickSensor::SetThreshold_doc[] = "setThreshold\n" @@ -368,6 +378,8 @@ PyObject* SCA_JoystickSensor::PySetThreshold( PyObject* self, m_precision = thresh; Py_Return; } + + /* get button -------------------------------------------------------- */ char SCA_JoystickSensor::GetButton_doc[] = "getButton\n" @@ -377,6 +389,8 @@ PyObject* SCA_JoystickSensor::PyGetButton( PyObject* self, PyObject* kwds) { return Py_BuildValue("[ii]",m_button, m_buttonf); } + + /* set button -------------------------------------------------------- */ char SCA_JoystickSensor::SetButton_doc[] = "setButton\n" @@ -392,6 +406,8 @@ PyObject* SCA_JoystickSensor::PySetButton( PyObject* self, m_buttonf = buttonflag; Py_Return; } + + /* get hat ----------------------------------------------------------- */ char SCA_JoystickSensor::GetHat_doc[] = "getHat\n" @@ -401,6 +417,8 @@ PyObject* SCA_JoystickSensor::PyGetHat( PyObject* self, PyObject* kwds) { return Py_BuildValue("[ii]",m_hat, m_hatf); } + + /* set hat ----------------------------------------------------------- */ char SCA_JoystickSensor::SetHat_doc[] = "setHat\n" @@ -416,6 +434,8 @@ PyObject* SCA_JoystickSensor::PySetHat( PyObject* self, m_hatf = hatflag; Py_Return; } + + /* get # of ----------------------------------------------------- */ char SCA_JoystickSensor::NumberOfAxes_doc[] = "getNumAxes\n" @@ -424,10 +444,12 @@ PyObject* SCA_JoystickSensor::PyNumberOfAxes( PyObject* self, PyObject* args, PyObject* kwds) { int num; - SCA_Joystick joy = m_pJoystickMgr->GetJoystickDevice(); - num = joy.GetNumberOfAxes(); + SCA_Joystick *joy = m_pJoystickMgr->GetJoystickDevice(); + num = joy->GetNumberOfAxes(); return Py_BuildValue("i",num); } + + char SCA_JoystickSensor::NumberOfButtons_doc[] = "getNumButtons\n" "\tReturns the number of buttons .\n"; @@ -435,10 +457,12 @@ PyObject* SCA_JoystickSensor::PyNumberOfButtons( PyObject* self, PyObject* args, PyObject* kwds) { int num; - SCA_Joystick joy = m_pJoystickMgr->GetJoystickDevice(); - num = joy.GetNumberOfButtons(); + SCA_Joystick *joy = m_pJoystickMgr->GetJoystickDevice(); + num = joy->GetNumberOfButtons(); return Py_BuildValue("i",num); } + + char SCA_JoystickSensor::NumberOfHats_doc[] = "getNumHats\n" "\tReturns the number of hats .\n"; @@ -446,7 +470,7 @@ PyObject* SCA_JoystickSensor::PyNumberOfHats( PyObject* self, PyObject* args, PyObject* kwds) { int num; - SCA_Joystick joy = m_pJoystickMgr->GetJoystickDevice(); - num = joy.GetNumberOfHats(); + SCA_Joystick *joy = m_pJoystickMgr->GetJoystickDevice(); + num = joy->GetNumberOfHats(); return Py_BuildValue("i",num); } diff --git a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp index 96c3c21ee90..8c3a17f58f3 100644 --- a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp +++ b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp @@ -94,10 +94,10 @@ #include "IMB_imbuf_types.h" // End of Blender includes -#include "SM_Scene.h" -#include "SumoPhysicsEnvironment.h" -#include "KX_SumoPhysicsController.h" #include "KX_Scene.h" +#include "KX_RayCast.h" +#include "KX_IPhysicsController.h" +#include "PHY_IPhysicsEnvironment.h" GPC_RenderTools::GPC_RenderTools() @@ -436,6 +436,26 @@ int GPC_RenderTools::applyLights(int objectlayer) } +bool GPC_RenderTools::RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_Vector3& hit_normal, void * const data) +{ + double* const oglmatrix = (double* const) data; + MT_Point3 resultpoint(hit_point); + MT_Vector3 resultnormal(hit_normal); + MT_Vector3 left(oglmatrix[0],oglmatrix[1],oglmatrix[2]); + MT_Vector3 dir = -(left.cross(resultnormal)).safe_normalized(); + left = (dir.cross(resultnormal)).safe_normalized(); + // for the up vector, we take the 'resultnormal' returned by the physics + + double maat[16]={ + left[0], left[1], left[2], 0, + dir[0], dir[1], dir[2], 0, + resultnormal[0],resultnormal[1],resultnormal[2], 0, + 0, 0, 0, 1}; + glTranslated(resultpoint[0],resultpoint[1],resultpoint[2]); + //glMultMatrixd(oglmatrix); + glMultMatrixd(maat); + return true; +} void GPC_RenderTools::applyTransform(RAS_IRasterizer* rasty,double* oglmatrix,int objectdrawmode ) { @@ -494,44 +514,26 @@ void GPC_RenderTools::applyTransform(RAS_IRasterizer* rasty,double* oglmatrix,in KX_GameObject *gameobj = (KX_GameObject*) this->m_clientobject; MT_Vector3 direction = MT_Vector3(0,0,-1); - direction.normalize(); direction *= 100000; MT_Point3 topoint = frompoint + direction; - MT_Point3 resultpoint; - MT_Vector3 resultnormal; - //todo: - //use physics abstraction KX_Scene* kxscene = (KX_Scene*) m_auxilaryClientInfo; - SumoPhysicsEnvironment *spe = dynamic_cast( kxscene->GetPhysicsEnvironment()); - SM_Scene *scene = spe->GetSumoScene(); - KX_SumoPhysicsController *spc = dynamic_cast( gameobj->GetPhysicsController()); + PHY_IPhysicsEnvironment* physics_environment = kxscene->GetPhysicsEnvironment(); + KX_IPhysicsController* physics_controller = gameobj->GetPhysicsController(); + KX_GameObject *parent = gameobj->GetParent(); - if (!spc && parent) - spc = dynamic_cast(parent->GetPhysicsController()); + if (!physics_controller && parent) + physics_controller = parent->GetPhysicsController(); if (parent) parent->Release(); - SM_Object *thisObj = spc?spc->GetSumoObject():NULL; - - if (scene->rayTest(thisObj, frompoint, topoint, resultpoint, resultnormal)) - { - MT_Vector3 left(oglmatrix[0],oglmatrix[1],oglmatrix[2]); - MT_Vector3 dir = -(left.cross(resultnormal)).normalized(); - left = (dir.cross(resultnormal)).normalized(); - // for the up vector, we take the 'resultnormal' returned by the physics - double maat[16]={ - left[0], left[1], left[2], 0, - dir[0], dir[1], dir[2], 0, - resultnormal[0],resultnormal[1],resultnormal[2], 0, - 0, 0, 0, 1}; - glTranslated(resultpoint[0],resultpoint[1],resultpoint[2]); - //glMultMatrixd(oglmatrix); - glMultMatrixd(maat); - } else + MT_Point3 resultpoint; + MT_Vector3 resultnormal; + if (!KX_RayCast::RayTest(physics_controller, physics_environment, frompoint, topoint, resultpoint, resultnormal, KX_RayCast::Callback(this, oglmatrix))) { + // couldn't find something to cast the shadow on... glMultMatrixd(oglmatrix); } } else diff --git a/source/gameengine/GamePlayer/common/GPC_RenderTools.h b/source/gameengine/GamePlayer/common/GPC_RenderTools.h index 62b69c07c5c..3ff9479f9da 100644 --- a/source/gameengine/GamePlayer/common/GPC_RenderTools.h +++ b/source/gameengine/GamePlayer/common/GPC_RenderTools.h @@ -50,6 +50,8 @@ #include "BMF_Api.h" +struct KX_ClientObjectInfo; + class GPC_RenderTools : public RAS_IRenderTools { @@ -146,6 +148,7 @@ public: int applyLights(int objectlayer); + bool RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_Vector3& hit_normal, void * const data); protected: /** * Copied from KX_BlenderGL.cpp in KX_blenderhook diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp index a956ede0d57..52bee8e81dd 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp @@ -51,7 +51,7 @@ #include "GPG_Application.h" #include -#include +#include /********************************** * Begin Blender include block @@ -725,7 +725,7 @@ void GPG_Application::exitEngine() bool GPG_Application::handleWheel(GHOST_IEvent* event) { bool handled = false; - assert(event); + MT_assert(event); if (m_mouse) { GHOST_TEventDataPtr eventData = ((GHOST_IEvent*)event)->getData(); @@ -744,7 +744,7 @@ bool GPG_Application::handleWheel(GHOST_IEvent* event) bool GPG_Application::handleButton(GHOST_IEvent* event, bool isDown) { bool handled = false; - assert(event); + MT_assert(event); if (m_mouse) { GHOST_TEventDataPtr eventData = ((GHOST_IEvent*)event)->getData(); @@ -773,7 +773,7 @@ bool GPG_Application::handleButton(GHOST_IEvent* event, bool isDown) bool GPG_Application::handleCursorMove(GHOST_IEvent* event) { bool handled = false; - assert(event); + MT_assert(event); if (m_mouse && m_mainWindow) { GHOST_TEventDataPtr eventData = ((GHOST_IEvent*)event)->getData(); @@ -790,7 +790,7 @@ bool GPG_Application::handleCursorMove(GHOST_IEvent* event) bool GPG_Application::handleKey(GHOST_IEvent* event, bool isDown) { bool handled = false; - assert(event); + MT_assert(event); if (m_keyboard) { GHOST_TEventDataPtr eventData = ((GHOST_IEvent*)event)->getData(); diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp index 9c60bc0f32f..c877b699860 100644 --- a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp +++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp @@ -33,6 +33,8 @@ #pragma warning (disable : 4786) #endif +#include "MT_assert.h" + // defines USE_ODE to choose physics engine #include "KX_ConvertPhysicsObject.h" #include "KX_GameObject.h" @@ -258,7 +260,7 @@ void KX_ConvertSumoObject( KX_GameObject* gameobj, dynamicParent = sumoctrl->GetSumoObject(); } - assert(dynamicParent); + MT_assert(dynamicParent); } @@ -303,11 +305,12 @@ static void BL_RegisterSumoObject( // need easy access, not via 'node' etc. KX_SumoPhysicsController* physicscontroller = new KX_SumoPhysicsController(sumoScene,sumoObj,motionstate,isDynamic); gameobj->SetPhysicsController(physicscontroller); - physicscontroller->setClientInfo(gameobj); + if (!gameobj->getClientInfo()) std::cout << "BL_RegisterSumoObject: WARNING: Object " << gameobj->GetName() << " has no client info" << std::endl; - sumoObj->setClientObject(gameobj->getClientInfo()); + physicscontroller->setNewClientInfo(gameobj->getClientInfo()); + gameobj->GetSGNode()->AddSGController(physicscontroller); @@ -586,6 +589,7 @@ void KX_ConvertODEEngineObject(KX_GameObject* gameobj, struct PHY_MaterialProps* smmaterial, struct KX_ObjectProperties* objprop) { + // not yet, future extension :) bool dyna=objprop->m_dyna; bool fullRigidBody= ( objprop->m_dyna && objprop->m_angular_rigidbody) != 0; @@ -598,48 +602,51 @@ void KX_ConvertODEEngineObject(KX_GameObject* gameobj, dxSpace* space = odeEnv->GetOdeSpace(); dxWorld* world = odeEnv->GetOdeWorld(); - if (!objprop->m_implicitsphere && - MT_fuzzyZero(objprop->m_boundingbox.m_extends[0]) || - MT_fuzzyZero(objprop->m_boundingbox.m_extends[1]) || - MT_fuzzyZero(objprop->m_boundingbox.m_extends[2]) - ) + bool isSphere = false; + + switch (objprop->m_boundclass) { + case KX_BOUNDBOX: + { - } else - { + KX_OdePhysicsController* physicscontroller = + new KX_OdePhysicsController( + dyna, + fullRigidBody, + phantom, + motionstate, + space, + world, + shapeprops->m_mass, + smmaterial->m_friction, + smmaterial->m_restitution, + isSphere, + objprop->m_boundobject.box.m_center, + objprop->m_boundobject.box.m_extends, + objprop->m_boundobject.c.m_radius + ); - KX_OdePhysicsController* physicscontroller = - new KX_OdePhysicsController( - dyna, - fullRigidBody, - phantom, - motionstate, - space, - world, - shapeprops->m_mass, - smmaterial->m_friction, - smmaterial->m_restitution, - objprop->m_implicitsphere, - objprop->m_boundingbox.m_center, - objprop->m_boundingbox.m_extends, - objprop->m_radius - ); + gameobj->SetPhysicsController(physicscontroller); + physicscontroller->setNewClientInfo(gameobj->getClientInfo()); + gameobj->GetSGNode()->AddSGController(physicscontroller); - gameobj->SetPhysicsController(physicscontroller); - physicscontroller->setClientInfo(gameobj); - gameobj->GetSGNode()->AddSGController(physicscontroller); + bool isActor = objprop->m_isactor; + STR_String materialname; + if (meshobj) + materialname = meshobj->GetMaterialName(0); - bool isActor = objprop->m_isactor; - STR_String materialname; - if (meshobj) - materialname = meshobj->GetMaterialName(0); - - const char* matname = materialname.ReadPtr(); + const char* matname = materialname.ReadPtr(); - physicscontroller->SetObject(gameobj->GetSGNode()); - - } + physicscontroller->SetObject(gameobj->GetSGNode()); + + break; + } + default: + { + } + }; + } diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index d255fd1d18f..c89bf33b21c 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -360,31 +360,6 @@ void KX_GameObject::UpdateIPO(float curframetime, UpdateTransform(); } - -/* -void KX_GameObject::RegisterSumoObject(class SM_Scene* sumoScene, - DT_SceneHandle solidscene, - class SM_Object* sumoObj, - const char* matname, - bool isDynamic, - bool isActor) -{ - m_bDyna = isDynamic; - - // need easy access, not via 'node' etc. - m_pPhysicsController = new KX_PhysicsController(sumoScene,solidscene,sumoObj,isDynamic); - - GetSGNode()->AddSGController(m_pPhysicsController); - - m_pClient_info->m_type = (isActor ? 1 : 0); - m_pClient_info->m_clientobject = this; - - // store materialname in auxinfo, needed for touchsensors - m_pClient_info->m_auxilary_info = (matname? (void*)(matname+2) : NULL); - m_pPhysicsController->SetObject(this->GetSGNode()); -} -*/ - bool KX_GameObject::GetVisible( void @@ -468,10 +443,11 @@ void KX_GameObject::ResolveCombinedVelocities( ){ if (m_pPhysicsController1) { + + MT_Vector3 lv = lin_vel_local ? NodeGetWorldOrientation() * lin_vel : lin_vel; + MT_Vector3 av = ang_vel_local ? NodeGetWorldOrientation() * ang_vel : ang_vel; m_pPhysicsController1->resolveCombinedVelocities( - lin_vel_local ? NodeGetWorldOrientation() * lin_vel : lin_vel, - ang_vel_local ? NodeGetWorldOrientation() * ang_vel : ang_vel - ); + lv.x(),lv.y(),lv.z(),av.x(),av.y(),av.z()); } } diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index 27451f637db..c84d905da8b 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -57,7 +57,7 @@ struct KX_ClientObjectInfo; class RAS_MeshObject; class KX_IPhysicsController; -class SM_Object; + /** * KX_GameObject is the main class for dynamic objects. diff --git a/source/gameengine/Ketsji/KX_IPO_SGController.cpp b/source/gameengine/Ketsji/KX_IPO_SGController.cpp index 2152fa35cd1..e54fb11dc14 100644 --- a/source/gameengine/Ketsji/KX_IPO_SGController.cpp +++ b/source/gameengine/Ketsji/KX_IPO_SGController.cpp @@ -57,7 +57,6 @@ KX_IpoSGController::KX_IpoSGController() m_modified(true), m_ipotime(1.0) { - m_sumo_object = NULL; m_game_object = NULL; } @@ -86,7 +85,7 @@ KX_IpoSGController::UpdateSumoReference( ) { if (m_game_object) { - m_sumo_object = 0;//m_game_object->GetSumoObject(); + } } @@ -113,15 +112,7 @@ bool KX_IpoSGController::Update(double currentTime) if (m_modify_position) { if (m_ipo_as_force) { - /* - UpdateSumoReference(); - if (m_sumo_object && ob) { - m_sumo_object->applyCenterForce(m_force_ipo_acts_local ? - ob->GetWorldOrientation() * m_ipo_xform.GetPosition() : - m_ipo_xform.GetPosition()); - m_sumo_object->calcXform(); - } - */ + if (m_game_object && ob) { m_game_object->GetPhysicsController()->ApplyForce(m_force_ipo_acts_local ? ob->GetWorldOrientation() * m_ipo_xform.GetPosition() : @@ -134,15 +125,7 @@ bool KX_IpoSGController::Update(double currentTime) } if (m_modify_orientation) { if (m_ipo_as_force) { - /* - UpdateSumoReference(); - if (m_sumo_object && ob) { - m_sumo_object->applyTorque(m_force_ipo_acts_local ? - ob->GetWorldOrientation() * m_ipo_xform.GetEulerAngles() : - m_ipo_xform.GetEulerAngles()); - m_sumo_object->calcXform(); - } - */ + if (m_game_object && ob) { m_game_object->ApplyTorque(m_force_ipo_acts_local ? ob->GetWorldOrientation() * m_ipo_xform.GetEulerAngles() : diff --git a/source/gameengine/Ketsji/KX_IPO_SGController.h b/source/gameengine/Ketsji/KX_IPO_SGController.h index 107d5026370..3b20f47f5fc 100644 --- a/source/gameengine/Ketsji/KX_IPO_SGController.h +++ b/source/gameengine/Ketsji/KX_IPO_SGController.h @@ -59,12 +59,6 @@ class KX_IpoSGController : public SG_Controller /** Local time of this ipo.*/ double m_ipotime; - /** A reference to the sm scene an eventually associated physics object is in. */ -// class SM_Scene* m_sumo_scene; - - /** A reference an eventually associated physics object is in. */ - class SM_Object* m_sumo_object; - /** A reference to the original game object. */ class KX_GameObject* m_game_object; diff --git a/source/gameengine/Ketsji/KX_IPhysicsController.cpp b/source/gameengine/Ketsji/KX_IPhysicsController.cpp index 9cc7764227b..c2328e45435 100644 --- a/source/gameengine/Ketsji/KX_IPhysicsController.cpp +++ b/source/gameengine/Ketsji/KX_IPhysicsController.cpp @@ -36,14 +36,18 @@ #include #endif +#include "PHY_DynamicTypes.h" + KX_IPhysicsController::KX_IPhysicsController(bool dyna,void* userdata) : m_bDyna(dyna), m_suspendDynamics(false), m_userdata(userdata) { -}; +} KX_IPhysicsController::~KX_IPhysicsController() { } + + diff --git a/source/gameengine/Ketsji/KX_IPhysicsController.h b/source/gameengine/Ketsji/KX_IPhysicsController.h index d2f1f59bac8..ca64888fd55 100644 --- a/source/gameengine/Ketsji/KX_IPhysicsController.h +++ b/source/gameengine/Ketsji/KX_IPhysicsController.h @@ -37,6 +37,8 @@ #include "MT_Point3.h" #include "MT_Matrix3x3.h" +struct KX_ClientObjectInfo; + /** Physics Controller, a special kind of Scene Graph Transformation Controller. It get's callbacks from Physics in case a transformation change took place. @@ -47,7 +49,6 @@ class KX_IPhysicsController : public SG_Controller { - protected: bool m_bDyna; bool m_suspendDynamics; @@ -68,7 +69,7 @@ public: virtual MT_Vector3 GetVelocity(const MT_Point3& pos)=0; virtual void SetAngularVelocity(const MT_Vector3& ang_vel,bool local)=0; virtual void SetLinearVelocity(const MT_Vector3& lin_vel,bool local)=0; - virtual void resolveCombinedVelocities(const MT_Vector3 & lin_vel, const MT_Vector3 & ang_vel) = 0; + virtual void resolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ) = 0; virtual void getOrientation(MT_Quaternion& orn)=0; virtual void setOrientation(const MT_Quaternion& orn)=0; @@ -95,8 +96,6 @@ public: // call from scene graph to update virtual bool Update(double time)=0; void* GetUserData() { return m_userdata;} - - }; #endif //__KX_IPHYSICSCONTROLLER_H diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index af75e3493c1..2e76103ac13 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -177,7 +177,7 @@ KX_KetsjiEngine::~KX_KetsjiEngine() void KX_KetsjiEngine::SetKeyboardDevice(SCA_IInputDevice* keyboarddevice) { - assert(keyboarddevice); + MT_assert(keyboarddevice); m_keyboarddevice = keyboarddevice; } @@ -185,7 +185,7 @@ void KX_KetsjiEngine::SetKeyboardDevice(SCA_IInputDevice* keyboarddevice) void KX_KetsjiEngine::SetMouseDevice(SCA_IInputDevice* mousedevice) { - assert(mousedevice); + MT_assert(mousedevice); m_mousedevice = mousedevice; } @@ -193,7 +193,7 @@ void KX_KetsjiEngine::SetMouseDevice(SCA_IInputDevice* mousedevice) void KX_KetsjiEngine::SetNetworkDevice(NG_NetworkDeviceInterface* networkdevice) { - assert(networkdevice); + MT_assert(networkdevice); m_networkdevice = networkdevice; } @@ -201,7 +201,7 @@ void KX_KetsjiEngine::SetNetworkDevice(NG_NetworkDeviceInterface* networkdevice) void KX_KetsjiEngine::SetAudioDevice(SND_IAudioDevice* audiodevice) { - assert(audiodevice); + MT_assert(audiodevice); m_audiodevice = audiodevice; } @@ -209,7 +209,7 @@ void KX_KetsjiEngine::SetAudioDevice(SND_IAudioDevice* audiodevice) void KX_KetsjiEngine::SetCanvas(RAS_ICanvas* canvas) { - assert(canvas); + MT_assert(canvas); m_canvas = canvas; } @@ -217,7 +217,7 @@ void KX_KetsjiEngine::SetCanvas(RAS_ICanvas* canvas) void KX_KetsjiEngine::SetRenderTools(RAS_IRenderTools* rendertools) { - assert(rendertools); + MT_assert(rendertools); m_rendertools = rendertools; } @@ -225,7 +225,7 @@ void KX_KetsjiEngine::SetRenderTools(RAS_IRenderTools* rendertools) void KX_KetsjiEngine::SetRasterizer(RAS_IRasterizer* rasterizer) { - assert(rasterizer); + MT_assert(rasterizer); m_rasterizer = rasterizer; } @@ -233,7 +233,7 @@ void KX_KetsjiEngine::SetRasterizer(RAS_IRasterizer* rasterizer) void KX_KetsjiEngine::SetPythonDictionary(PyObject* pythondictionary) { - assert(pythondictionary); + MT_assert(pythondictionary); m_pythondictionary = pythondictionary; } @@ -241,7 +241,7 @@ void KX_KetsjiEngine::SetPythonDictionary(PyObject* pythondictionary) void KX_KetsjiEngine::SetSceneConverter(KX_ISceneConverter* sceneconverter) { - assert(sceneconverter); + MT_assert(sceneconverter); m_sceneconverter = sceneconverter; } @@ -258,7 +258,6 @@ void KX_KetsjiEngine::StartEngine() m_firstframe = true; m_bInitialized = true; m_ticrate = DEFAULT_LOGIC_TIC_RATE; - SumoPhysicsEnvironment::setTicRate(DEFAULT_PHYSICS_TIC_RATE); } bool KX_KetsjiEngine::BeginFrame() @@ -320,6 +319,8 @@ void KX_KetsjiEngine::NextFrame() else curtime = m_kxsystem->GetTimeInSeconds(); m_deltatime += curtime - m_previoustime; + float realDeltaTime = curtime - m_previoustime; + m_previoustime = curtime; double localtime = curtime - m_deltatime; @@ -386,7 +387,7 @@ void KX_KetsjiEngine::NextFrame() // Perform physics calculations on the scene. This can involve // many iterations of the physics solver. m_logger->StartLog(tc_physics, m_kxsystem->GetTimeInSeconds(), true); - scene->GetPhysicsEnvironment()->proceed(localtime); + scene->GetPhysicsEnvironment()->proceedDeltaTime(localtime,realDeltaTime); } // suspended DoSound(scene); @@ -430,7 +431,7 @@ void KX_KetsjiEngine::NextFrame() // Perform physics calculations on the scene. This can involve // many iterations of the physics solver. m_logger->StartLog(tc_physics, m_kxsystem->GetTimeInSeconds(), true); - scene->GetPhysicsEnvironment()->proceed(curtime); + scene->GetPhysicsEnvironment()->proceedDeltaTime(curtime,0.f); // 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_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h index 9a6f18a5c5f..8ea611298e7 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.h +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h @@ -296,7 +296,7 @@ public: * @param b Blue component of the override color. */ void GetOverrideFrameColor(float& r, float& g, float& b) const; - + protected: /** * Processes all scheduled scene activity. diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp index 1ffde7e31f8..7c61edd45e7 100644 --- a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp +++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp @@ -50,10 +50,12 @@ #include "KX_Camera.h" #include "KX_MouseFocusSensor.h" -#include "SM_Object.h" -#include "SM_Scene.h" -#include "SumoPhysicsEnvironment.h" -#include "KX_SumoPhysicsController.h" +#include "KX_RayCast.h" +#include "KX_IPhysicsController.h" +#include "PHY_IPhysicsController.h" +#include "PHY_IPhysicsEnvironment.h" + + #include "KX_ClientObjectInfo.h" /* ------------------------------------------------------------------------- */ @@ -117,10 +119,40 @@ bool KX_MouseFocusSensor::Evaluate(CValue* event) return result; } +bool KX_MouseFocusSensor::RayHit(KX_ClientObjectInfo* client_info, MT_Point3& hit_point, MT_Vector3& hit_normal, void * const data) +{ + KX_GameObject* hitKXObj = client_info->m_gameobject; + + if (client_info->m_type > KX_ClientObjectInfo::ACTOR) + { + // false hit + return false; + } + + /* Is this me? In the ray test, there are a lot of extra checks + * for aliasing artefacts from self-hits. That doesn't happen + * here, so a simple test suffices. Or does the camera also get + * self-hits? (No, and the raysensor shouldn't do it either, since + * self-hits are excluded by setting the correct ignore-object.) + * Hitspots now become valid. */ + KX_GameObject* thisObj = (KX_GameObject*) GetParent(); + if (hitKXObj == thisObj) + { + m_hitPosition = hit_point; + m_hitNormal = hit_normal; + return true; + } + + return true; // object must be visible to trigger + //return false; // occluded objects can trigger +} + + + bool KX_MouseFocusSensor::ParentObjectHasFocus(void) { - // bool res = false; /*unused*/ + bool res = false; m_hitPosition = MT_Vector3(0,0,0); m_hitNormal = MT_Vector3(1,0,0); MT_Point3 resultpoint; @@ -236,88 +268,99 @@ bool KX_MouseFocusSensor::ParentObjectHasFocus(void) m_prevTargetPoint = topoint3; m_prevSourcePoint = frompoint3; - /* 2. Get the object from SuMO*/ + /* 2. Get the object from PhysicsEnvironment */ /* Shoot! Beware that the first argument here is an * ignore-object. We don't ignore anything... */ - KX_GameObject* thisObj = (KX_GameObject*) GetParent(); - SumoPhysicsEnvironment *spe = dynamic_cast (m_kxscene->GetPhysicsEnvironment()); - SM_Scene *sumoScene = spe->GetSumoScene(); - KX_SumoPhysicsController *spc = dynamic_cast (cam->GetPhysicsController()); - SM_Object *sumoCam = spc?spc->GetSumoObject():NULL; - MT_Vector3 todir = topoint3 - frompoint3; - if (todir.dot(todir) < MT_EPSILON) - return false; - todir.normalize(); + KX_IPhysicsController* physics_controller = (cam->GetPhysicsController()); + PHY_IPhysicsEnvironment* physics_environment = m_kxscene->GetPhysicsEnvironment(); - while (true) - { - SM_Object* hitSMObj = sumoScene->rayTest(sumoCam, - frompoint3, - topoint3, - resultpoint, - resultnormal); - - if (!hitSMObj) - return false; - - /* all this casting makes me nervous... */ - KX_ClientObjectInfo* client_info - = ( hitSMObj ? - static_cast( hitSMObj->getClientObject() ): - NULL); - - if (!client_info) - { - std::cout<< "WARNING: MouseOver sensor " << GetName() << " cannot sense SM_Object " << hitSMObj << " - no client info.\n" << std::endl; - return false; - } +// MT_Vector3 todir = topoint3 - frompoint3; +// if (todir.dot(todir) < MT_EPSILON) +// return false; +// todir.normalize(); - KX_GameObject* hitKXObj = client_info->m_gameobject; - - if (client_info->m_type > KX_ClientObjectInfo::ACTOR) - { - // false hit - KX_SumoPhysicsController *hitspc = dynamic_cast (static_cast (hitKXObj) ->GetPhysicsController()); - if (hitspc) - { - /* We add 0.01 of fudge, so that if the margin && radius == 0., we don't endless loop. */ - MT_Scalar marg = 0.01 + hitspc->GetSumoObject()->getMargin(); - if (hitspc->GetSumoObject()->getShapeProps()) - { - marg += 2*hitspc->GetSumoObject()->getShapeProps()->m_radius; - } - - /* Calculate the other side of this object */ - MT_Point3 hitObjPos; - hitspc->GetWorldPosition(hitObjPos); - MT_Vector3 hitvector = hitObjPos - resultpoint; - if (hitvector.dot(hitvector) > MT_EPSILON) - { - hitvector.normalize(); - marg *= 2.*todir.dot(hitvector); - } - frompoint3 = resultpoint + marg * todir; - } else { - return false; - } - continue; - } - /* Is this me? In the ray test, there are a lot of extra checks - * for aliasing artefacts from self-hits. That doesn't happen - * here, so a simple test suffices. Or does the camera also get - * self-hits? (No, and the raysensor shouldn't do it either, since - * self-hits are excluded by setting the correct ignore-object.) - * Hitspots now become valid. */ - if (hitKXObj == thisObj) - { - m_hitPosition = resultpoint; - m_hitNormal = resultnormal; - return true; - } - - return false; - } + KX_RayCast::RayTest(physics_controller, physics_environment, frompoint3, topoint3, resultpoint, resultnormal, KX_RayCast::Callback(this)); + + +// while (true) +// { +// PHY__Vector3 resultpt; +// PHY__Vector3 resultnr; +// +// PHY_IPhysicsController* hitCtrl= physEnv->rayTest(camCtrl, +// frompoint3.x(),frompoint3.y(),frompoint3.z(), +// topoint3.x(),topoint3.y(),topoint3.z(), +// resultpt[0], resultpt[1],resultpt[2], +// resultnr[0],resultnr[1],resultnr[2]); +// +// if (!hitCtrl) +// return false; +// +// resultpoint = MT_Vector3(resultpt); +// resultnormal = MT_Vector3(resultnr); +// +// /* all this casting makes me nervous... */ +// KX_ClientObjectInfo* client_info +// = static_cast( hitCtrl->getNewClientInfo()); +// +// if (!client_info) +// { +// std::cout<< "WARNING: MouseOver sensor " << GetName() << " cannot sense - no client info.\n" << std::endl; +// +// return false; +// } +// +// KX_GameObject* hitKXObj = client_info->m_gameobject; +// +// if (client_info->m_type > KX_ClientObjectInfo::ACTOR) +// { +// // false hit +// // FIXME: add raytest interface to KX_IPhysicsController, remove casting +// PHY_IPhysicsController* hitspc = (PHY_IPhysicsController*) (static_cast (hitKXObj)->GetPhysicsController()); +// if (hitspc) +// { +// /* We add 0.01 of fudge, so that if the margin && radius == 0., we don't endless loop. */ +// MT_Scalar marg = 0.01 + hitspc->GetMargin(); +// marg += hitspc->GetRadius(); //this is changed, check ! +// +// //if (hitspc->GetSumoObject()->getShapeProps()) +// //{ +// // marg += 2*hitspc->GetSumoObject()->getShapeProps()->m_radius; +// //} +// +// /* Calculate the other side of this object */ +// MT_Point3 hitObjPos; +// PHY__Vector3 hitpos; +// hitspc->getPosition(hitpos); +// hitObjPos = MT_Vector3(hitpos); +// MT_Vector3 hitvector = hitObjPos - resultpoint; +// if (hitvector.dot(hitvector) > MT_EPSILON) +// { +// hitvector.normalize(); +// marg *= 2.*todir.dot(hitvector); +// } +// frompoint3 = resultpoint + marg * todir; +// } else { +// return false; +// } +// continue; +// } +// /* Is this me? In the ray test, there are a lot of extra checks +// * for aliasing artefacts from self-hits. That doesn't happen +// * here, so a simple test suffices. Or does the camera also get +// * self-hits? (No, and the raysensor shouldn't do it either, since +// * self-hits are excluded by setting the correct ignore-object.) +// * Hitspots now become valid. */ +// if (hitKXObj == thisObj) +// { +// m_hitPosition = resultpoint; +// m_hitNormal = resultnormal; +// return true; +// } +// +// return false; +// } return false; } diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.h b/source/gameengine/Ketsji/KX_MouseFocusSensor.h index 61571e190ec..d92cebfb4e1 100644 --- a/source/gameengine/Ketsji/KX_MouseFocusSensor.h +++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.h @@ -78,6 +78,8 @@ class KX_MouseFocusSensor : public SCA_MouseSensor return result; }; + bool RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_Vector3& hit_normal, void * const data); + /* --------------------------------------------------------------------- */ /* Python interface ---------------------------------------------------- */ diff --git a/source/gameengine/Ketsji/KX_NearSensor.cpp b/source/gameengine/Ketsji/KX_NearSensor.cpp index 4766d837069..9f9188ab9a1 100644 --- a/source/gameengine/Ketsji/KX_NearSensor.cpp +++ b/source/gameengine/Ketsji/KX_NearSensor.cpp @@ -37,20 +37,21 @@ #include "KX_GameObject.h" #include "KX_TouchEventManager.h" #include "KX_Scene.h" // needed to create a replica +#include "PHY_IPhysicsEnvironment.h" +#include "PHY_IPhysicsController.h" -#include "SM_Object.h" #ifdef HAVE_CONFIG_H #include #endif KX_NearSensor::KX_NearSensor(SCA_EventManager* eventmgr, KX_GameObject* gameobj, - void *vshape, double margin, double resetmargin, bool bFindMaterial, const STR_String& touchedpropname, class KX_Scene* scene, + PHY_IPhysicsController* ctrl, PyTypeObject* T) :KX_TouchSensor(eventmgr, gameobj, @@ -66,46 +67,17 @@ KX_NearSensor::KX_NearSensor(SCA_EventManager* eventmgr, 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); - m_sumoObj->setMargin(m_Margin); - m_sumoObj->setClientObject(m_client_info); - - SynchronizeTransform(); -} - -KX_NearSensor::KX_NearSensor(SCA_EventManager* eventmgr, - KX_GameObject* gameobj, - double margin, - double resetmargin, - bool bFindMaterial, - const STR_String& touchedpropname, - class KX_Scene* scene, - PyTypeObject* T) - :KX_TouchSensor(eventmgr, - gameobj, - bFindMaterial, - touchedpropname, - /* scene, */ - T), - m_Margin(margin), - 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); - m_sumoObj->setClientObject(m_client_info); + //DT_ShapeHandle shape = (DT_ShapeHandle) vshape; + m_physCtrl = ctrl; + m_physCtrl->SetMargin(m_Margin); + m_physCtrl->setNewClientInfo(m_client_info); SynchronizeTransform(); } void KX_NearSensor::RegisterSumo(KX_TouchEventManager *touchman) { - touchman->GetSumoScene()->addSensor(*m_sumoObj); + touchman->GetPhysicsEnvironment()->addSensor(m_physCtrl); } CValue* KX_NearSensor::GetReplica() @@ -121,9 +93,11 @@ CValue* KX_NearSensor::GetReplica() 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); - replica->m_sumoObj->setClientObject(replica->m_client_info); + replica->m_physCtrl = replica->m_physCtrl->GetReplica(); + //todo: make sure replication works fine + //>m_sumoObj = new SM_Object(DT_NewSphere(0.0),NULL,NULL,NULL); + //replica->m_sumoObj->setMargin(m_Margin); + //replica->m_sumoObj->setClientObject(replica->m_client_info); replica->SynchronizeTransform(); @@ -148,11 +122,11 @@ KX_NearSensor::~KX_NearSensor() { // for nearsensor, the sensor is the 'owner' of sumoobj // for touchsensor, it's the parent - if (m_sumoObj) + if (m_physCtrl) { - static_cast(m_eventmgr)->GetSumoScene()->remove(*m_sumoObj); - delete m_sumoObj; - m_sumoObj = NULL; + static_cast(m_eventmgr)->GetPhysicsEnvironment()->removeSensor(m_physCtrl); + delete m_physCtrl; + m_physCtrl = NULL; } if (m_client_info) @@ -163,22 +137,22 @@ KX_NearSensor::~KX_NearSensor() bool KX_NearSensor::Evaluate(CValue* event) { bool result = false; - // KX_GameObject* parent = static_cast(GetParent()); /*unused*/ + KX_GameObject* parent = static_cast(GetParent()); if (m_bTriggered != m_bLastTriggered) { m_bLastTriggered = m_bTriggered; if (m_bTriggered) { - if (m_sumoObj) + if (m_physCtrl) { - m_sumoObj->setMargin(m_ResetMargin); + m_physCtrl->SetMargin(m_ResetMargin); } } else { - if (m_sumoObj) + if (m_physCtrl) { - m_sumoObj->setMargin(m_Margin); + m_physCtrl->SetMargin(m_Margin); } } @@ -190,16 +164,16 @@ bool KX_NearSensor::Evaluate(CValue* event) -DT_Bool KX_NearSensor::HandleCollision(void* obj1,void* obj2,const DT_CollData * coll_data) +bool KX_NearSensor::NewHandleCollision(void* obj1,void* obj2,const PHY_CollData * coll_data) { - // KX_TouchEventManager* toucheventmgr = static_cast(m_eventmgr); /*unused*/ + KX_TouchEventManager* toucheventmgr = static_cast(m_eventmgr); KX_GameObject* parent = static_cast(GetParent()); - // need the mapping from SM_Objects to gameobjects now + // need the mapping from PHY_IPhysicsController to gameobjects now - KX_ClientObjectInfo* client_info =static_cast (obj1 == m_sumoObj? - ((SM_Object*)obj2)->getClientObject() : - ((SM_Object*)obj1)->getClientObject()); + KX_ClientObjectInfo* client_info =static_cast (obj1 == m_physCtrl? + ((PHY_IPhysicsController*)obj2)->getNewClientInfo() : + ((PHY_IPhysicsController*)obj1)->getNewClientInfo()); KX_GameObject* gameobj = ( client_info ? client_info->m_gameobject : diff --git a/source/gameengine/Ketsji/KX_NearSensor.h b/source/gameengine/Ketsji/KX_NearSensor.h index 080df58639e..d1b8984b91b 100644 --- a/source/gameengine/Ketsji/KX_NearSensor.h +++ b/source/gameengine/Ketsji/KX_NearSensor.h @@ -39,25 +39,27 @@ #include "KX_ClientObjectInfo.h" class KX_Scene; +struct PHY_CollData; class KX_NearSensor : public KX_TouchSensor { Py_Header; +protected: double m_Margin; double m_ResetMargin; KX_Scene* m_scene; KX_ClientObjectInfo* m_client_info; -protected: +public: KX_NearSensor(class SCA_EventManager* eventmgr, class KX_GameObject* gameobj, - void *shape, double margin, double resetmargin, bool bFindMaterial, const STR_String& touchedpropname, class KX_Scene* scene, + PHY_IPhysicsController* ctrl, PyTypeObject* T=&Type); - +/* public: KX_NearSensor(class SCA_EventManager* eventmgr, class KX_GameObject* gameobj, @@ -67,13 +69,14 @@ public: const STR_String& touchedpropname, class KX_Scene* scene, PyTypeObject* T=&Type); +*/ virtual ~KX_NearSensor(); virtual CValue* GetReplica(); virtual bool Evaluate(CValue* event); virtual void ReParent(SCA_IObject* parent); - virtual DT_Bool HandleCollision(void* obj1,void* obj2, - const DT_CollData * coll_data); + virtual bool NewHandleCollision(void* obj1,void* obj2, + const PHY_CollData * coll_data); virtual void RegisterSumo(KX_TouchEventManager *touchman); virtual PyObject* _getattr(const STR_String& attr); diff --git a/source/gameengine/Ketsji/KX_OdePhysicsController.cpp b/source/gameengine/Ketsji/KX_OdePhysicsController.cpp index 14461145cb7..cce2ceb70c2 100644 --- a/source/gameengine/Ketsji/KX_OdePhysicsController.cpp +++ b/source/gameengine/Ketsji/KX_OdePhysicsController.cpp @@ -23,6 +23,10 @@ #include "KX_GameObject.h" #include "KX_MotionState.h" +#include "MT_assert.h" + +#include "PHY_IPhysicsEnvironment.h" + #ifdef HAVE_CONFIG_H #include #endif @@ -225,7 +229,7 @@ SG_Controller* KX_OdePhysicsController::GetReplica(class SG_Node* destnode) } -void KX_OdePhysicsController::resolveCombinedVelocities(const MT_Vector3 & lin_vel, const MT_Vector3 & ang_vel ) +void KX_OdePhysicsController::resolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ) { } diff --git a/source/gameengine/Ketsji/KX_OdePhysicsController.h b/source/gameengine/Ketsji/KX_OdePhysicsController.h index 69c06a2b620..f5bc7dee165 100644 --- a/source/gameengine/Ketsji/KX_OdePhysicsController.h +++ b/source/gameengine/Ketsji/KX_OdePhysicsController.h @@ -65,7 +65,7 @@ public: virtual MT_Vector3 GetVelocity(const MT_Point3& pos); virtual void SetAngularVelocity(const MT_Vector3& ang_vel,bool local); virtual void SetLinearVelocity(const MT_Vector3& lin_vel,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 getOrientation(MT_Quaternion& orn); virtual void setOrientation(const MT_Quaternion& orn); virtual void setPosition(const MT_Point3& pos); @@ -95,7 +95,7 @@ public: ){ // intentionally empty }; - + }; #endif //__KX_ODEPHYSICSCONTROLLER_H diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp index 0c7be571c8d..89c84d63913 100644 --- a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp +++ b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp @@ -71,7 +71,7 @@ KX_PolygonMaterial::KX_PolygonMaterial(const STR_String &texname, PyTypeObject *T) : PyObjectPlus(T), RAS_IPolyMaterial(texname, - material?STR_String(material->id.name):STR_String(""), + STR_String(material?material->id.name:""), tile, tilexrep, tileyrep, diff --git a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp index 1f810e655ac..0111fd36cb2 100644 --- a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp +++ b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp @@ -41,7 +41,7 @@ // nasty glob variable to connect scripting language // if there is a better way (without global), please do so! -static PHY_IPhysicsEnvironment* g_physics_env = NULL; +static PHY_IPhysicsEnvironment* g_CurrentActivePhysicsEnvironment = NULL; static char PhysicsConstraints_module_documentation[] = "This is the Python API for the Physics Constraints"; @@ -59,8 +59,8 @@ static PyObject* gPySetGravity(PyObject* self, int len = PyTuple_Size(args); if ((len == 3) && PyArg_ParseTuple(args,"fff",&x,&y,&z)) { - if (g_physics_env) - g_physics_env->setGravity(x,y,z); + if (PHY_GetActiveEnvironment()) + PHY_GetActiveEnvironment()->setGravity(x,y,z); } Py_INCREF(Py_None); return Py_None; } @@ -99,16 +99,16 @@ static PyObject* gPyCreateConstraint(PyObject* self, if (success) { - if (g_physics_env) + if (PHY_GetActiveEnvironment()) { PHY_IPhysicsController* physctrl = (PHY_IPhysicsController*) physicsid; PHY_IPhysicsController* physctrl2 = (PHY_IPhysicsController*) physicsid2; if (physctrl) //TODO:check for existance of this pointer! { - int constraintid = g_physics_env->createConstraint(physctrl,physctrl2,(enum PHY_ConstraintType)constrainttype,pivotX,pivotY,pivotZ,axisX,axisY,axisZ); + int constraintid = PHY_GetActiveEnvironment()->createConstraint(physctrl,physctrl2,(enum PHY_ConstraintType)constrainttype,pivotX,pivotY,pivotZ,axisX,axisY,axisZ); - KX_ConstraintWrapper* wrap = new KX_ConstraintWrapper((enum PHY_ConstraintType)constrainttype,constraintid,g_physics_env); + KX_ConstraintWrapper* wrap = new KX_ConstraintWrapper((enum PHY_ConstraintType)constrainttype,constraintid,PHY_GetActiveEnvironment()); return wrap; @@ -130,9 +130,9 @@ static PyObject* gPyRemoveConstraint(PyObject* self, if (PyArg_ParseTuple(args,"i",&constraintid)) { - if (g_physics_env) + if (PHY_GetActiveEnvironment()) { - g_physics_env->removeConstraint(constraintid); + PHY_GetActiveEnvironment()->removeConstraint(constraintid); } } Py_INCREF(Py_None); return Py_None; @@ -188,5 +188,11 @@ void KX_RemovePythonConstraintBinding() void PHY_SetActiveEnvironment(class PHY_IPhysicsEnvironment* env) { - g_physics_env = env; + g_CurrentActivePhysicsEnvironment = env; } + +PHY_IPhysicsEnvironment* PHY_GetActiveEnvironment() +{ + return g_CurrentActivePhysicsEnvironment; +} + diff --git a/source/gameengine/Ketsji/KX_PyConstraintBinding.h b/source/gameengine/Ketsji/KX_PyConstraintBinding.h index f1ba459a19f..a8651a175c2 100644 --- a/source/gameengine/Ketsji/KX_PyConstraintBinding.h +++ b/source/gameengine/Ketsji/KX_PyConstraintBinding.h @@ -37,6 +37,8 @@ PyObject* initPythonConstraintBinding(); void PHY_RemovePythonConstraintBinding(); void PHY_SetActiveEnvironment(class PHY_IPhysicsEnvironment* env); +PHY_IPhysicsEnvironment* PHY_GetActiveEnvironment(); + #endif //PHY_PYTHON_CONSTRAINTBINDING diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index 42b26185b4c..6f2fced3bd1 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -40,6 +40,8 @@ #endif //WIN32 #include "KX_PythonInit.h" +//python physics binding +#include "KX_PyConstraintBinding.h" #include "KX_KetsjiEngine.h" @@ -211,7 +213,8 @@ static PyObject* gPySetPhysicsTicRate(PyObject*, float ticrate; if (PyArg_ParseTuple(args, "f", &ticrate)) { - SumoPhysicsEnvironment::setTicRate(ticrate); + + PHY_GetActiveEnvironment()->setFixedTimeStep(true,ticrate); Py_Return; } @@ -220,7 +223,7 @@ static PyObject* gPySetPhysicsTicRate(PyObject*, static PyObject* gPyGetPhysicsTicRate(PyObject*, PyObject*, PyObject*) { - return PyFloat_FromDouble(SumoPhysicsEnvironment::getTicRate()); + return PyFloat_FromDouble(PHY_GetActiveEnvironment()->getFixedTimeStep()); } static STR_String gPyGetCurrentScene_doc = diff --git a/source/gameengine/Ketsji/KX_RadarSensor.cpp b/source/gameengine/Ketsji/KX_RadarSensor.cpp index 1ad37504224..ea656877e92 100644 --- a/source/gameengine/Ketsji/KX_RadarSensor.cpp +++ b/source/gameengine/Ketsji/KX_RadarSensor.cpp @@ -31,6 +31,7 @@ #include "KX_RadarSensor.h" #include "KX_GameObject.h" +#include "PHY_IPhysicsController.h" #ifdef HAVE_CONFIG_H #include @@ -41,6 +42,7 @@ */ KX_RadarSensor::KX_RadarSensor(SCA_EventManager* eventmgr, KX_GameObject* gameobj, + PHY_IPhysicsController* physCtrl, double coneradius, double coneheight, int axis, @@ -54,12 +56,13 @@ KX_RadarSensor::KX_RadarSensor(SCA_EventManager* eventmgr, : KX_NearSensor( eventmgr, gameobj, - DT_NewCone(coneradius,coneheight), + //DT_NewCone(coneradius,coneheight), margin, resetmargin, bFindMaterial, touchedpropname, kxscene, + physCtrl, T), m_coneradius(coneradius), m_coneheight(coneheight), @@ -90,9 +93,11 @@ CValue* KX_RadarSensor::GetReplica() 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); - replica->m_sumoObj->setClientObject(replica->m_client_info); + replica->m_physCtrl = replica->m_physCtrl->GetReplica(); + //todo: make sure replication works fine! + //>m_sumoObj = new SM_Object(DT_NewCone(m_coneradius, m_coneheight),NULL,NULL,NULL); + //replica->m_sumoObj->setMargin(m_Margin); + //replica->m_sumoObj->setClientObject(replica->m_client_info); replica->SynchronizeTransform(); @@ -145,9 +150,11 @@ void KX_RadarSensor::SynchronizeTransform() m_cone_origin = trans.getOrigin(); m_cone_target = trans(MT_Point3(0, -m_coneheight/2.0 ,0)); - m_sumoObj->setPosition(trans.getOrigin()); - m_sumoObj->setOrientation(trans.getRotation()); - m_sumoObj->calcXform(); + + m_physCtrl->setPosition(trans.getOrigin().x(),trans.getOrigin().y(),trans.getOrigin().z()); + m_physCtrl->setOrientation(trans.getRotation().x(),trans.getRotation().y(),trans.getRotation().z(),trans.getRotation().w()); + m_physCtrl->calcXform(); + } /* ------------------------------------------------------------------------- */ diff --git a/source/gameengine/Ketsji/KX_RadarSensor.h b/source/gameengine/Ketsji/KX_RadarSensor.h index 0e055357f18..4f5ff994b40 100644 --- a/source/gameengine/Ketsji/KX_RadarSensor.h +++ b/source/gameengine/Ketsji/KX_RadarSensor.h @@ -65,6 +65,7 @@ public: KX_RadarSensor(SCA_EventManager* eventmgr, KX_GameObject* gameobj, + PHY_IPhysicsController* physCtrl, double coneradius, double coneheight, int axis, diff --git a/source/gameengine/Ketsji/KX_RayCast.cpp b/source/gameengine/Ketsji/KX_RayCast.cpp new file mode 100644 index 00000000000..98ebde9ca5a --- /dev/null +++ b/source/gameengine/Ketsji/KX_RayCast.cpp @@ -0,0 +1,97 @@ +/** + * $Id$ + * + * ***** 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 ***** + * KX_MouseFocusSensor determines mouse in/out/over events. + */ + +#include "KX_RayCast.h" + +#include "MT_Point3.h" +#include "MT_Vector3.h" + +#include "KX_IPhysicsController.h" +#include "PHY_IPhysicsEnvironment.h" +#include "PHY_IPhysicsController.h" + +bool KX_RayCast::RayTest(KX_IPhysicsController* ignore_controller, PHY_IPhysicsEnvironment* physics_environment, const MT_Point3& _frompoint, const MT_Point3& topoint, MT_Point3& result_point, MT_Vector3& result_normal, const KX_RayCast& callback) +{ + // Loops over all physics objects between frompoint and topoint, + // calling callback.RayHit for each one. + // + // callback.RayHit should return true to stop looking, or false to continue. + // + // returns true if an object was found, false if not. + MT_Point3 frompoint(_frompoint); + const MT_Vector3 todir( (topoint - frompoint).normalized() ); + + PHY_IPhysicsController* hit_controller; + PHY__Vector3 phy_pos; + PHY__Vector3 phy_normal; + + while((hit_controller = physics_environment->rayTest(dynamic_cast(ignore_controller), + frompoint.x(),frompoint.y(),frompoint.z(), + topoint.x(),topoint.y(),topoint.z(), + phy_pos[0],phy_pos[1],phy_pos[2], + phy_normal[0],phy_normal[1],phy_normal[2]))) + { + result_point = MT_Point3(phy_pos); + result_normal = MT_Vector3(phy_normal); + KX_ClientObjectInfo* info = static_cast(hit_controller->getNewClientInfo()); + + if (!info) + { + MT_assert(info && "Physics controller with no client object info"); + return false; + } + + if (callback.RayHit(info, result_point, result_normal)) + return true; + + // skip past the object and keep tracing + /* We add 0.01 of fudge, so that if the margin && radius == 0., we don't endless loop. */ + MT_Scalar marg = 0.01 + hit_controller->GetMargin(); + marg += 2.f * hit_controller->GetMargin(); + /* Calculate the other side of this object */ + PHY__Vector3 hitpos; + hit_controller->getPosition(hitpos); + MT_Point3 hitObjPos(hitpos); + + MT_Vector3 hitvector = hitObjPos - result_point; + if (hitvector.dot(hitvector) > MT_EPSILON) + { + hitvector.normalize(); + marg *= 2.*todir.dot(hitvector); + } + frompoint = result_point + marg * todir; + } + + return hit_controller; +} + diff --git a/source/gameengine/Ketsji/KX_RayCast.h b/source/gameengine/Ketsji/KX_RayCast.h new file mode 100644 index 00000000000..8bb21e28aca --- /dev/null +++ b/source/gameengine/Ketsji/KX_RayCast.h @@ -0,0 +1,107 @@ +/** + * $Id$ + * + * ***** 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 ***** + */ + +#ifndef __KX_RAYCAST_H__ +#define __KX_RAYCAST_H__ + +class MT_Point3; +class MT_Vector3; +class KX_IPhysicsController; +class PHY_IPhysicsEnvironment; + +struct KX_ClientObjectInfo; + +/** + * Defines a function for doing a ray cast. + * + * eg KX_RayCast::RayTest(ignore_physics_controller, physics_environment, frompoint, topoint, result_point, result_normal, KX_RayCast::Callback(this, data) + * + * Calls myclass->RayHit(client, hit_point, hit_normal, data) for all client + * between frompoint and topoint + * + * myclass->RayHit should return true to end the raycast, false to ignore the current client. + * + * Returns true if a client was accepted, false if nothing found. + */ +class KX_RayCast +{ +protected: + KX_RayCast() {}; +public: + virtual ~KX_RayCast() {} + + /** ray test callback. + * either override this in your class, or use a callback wrapper. + */ + virtual bool RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_Vector3& hit_normal) const = 0; + + /** + * Callback wrapper. + * + * Construct with KX_RayCast::Callback(this, data) + * and pass to KX_RayCast::RayTest + */ + template class Callback; + + /// Public interface. + /// Implement bool RayHit in your class to receive ray callbacks. + static bool RayTest(KX_IPhysicsController* physics_controller, + PHY_IPhysicsEnvironment* physics_environment, + const MT_Point3& _frompoint, + const MT_Point3& topoint, + MT_Point3& result_point, + MT_Vector3& result_normal, + const KX_RayCast& callback); + +}; + +template class KX_RayCast::Callback : public KX_RayCast +{ + T *self; + void *data; +public: + Callback(T *_self, void *_data = NULL) + : self(_self), + data(_data) + { + } + + ~Callback() {} + + virtual bool RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_Vector3& hit_normal) const + { + return self->RayHit(client, hit_point, hit_normal, data); + } +}; + + +#endif diff --git a/source/gameengine/Ketsji/KX_RaySensor.cpp b/source/gameengine/Ketsji/KX_RaySensor.cpp index c60b2171cab..fa5f5215aa4 100644 --- a/source/gameengine/Ketsji/KX_RaySensor.cpp +++ b/source/gameengine/Ketsji/KX_RaySensor.cpp @@ -41,8 +41,11 @@ #include "KX_GameObject.h" #include "KX_Scene.h" -#include "SumoPhysicsEnvironment.h" -#include "KX_SumoPhysicsController.h" +#include "KX_RayCast.h" +#include "PHY_IPhysicsEnvironment.h" +#include "PHY_IPhysicsController.h" +#include "KX_IPhysicsController.h" + #ifdef HAVE_CONFIG_H #include @@ -101,7 +104,47 @@ bool KX_RaySensor::IsPositiveTrigger() return result; } +bool KX_RaySensor::RayHit(KX_ClientObjectInfo* info, MT_Point3& hit_point, MT_Vector3& hit_normal, void* const data) +{ + KX_GameObject* obj = (KX_GameObject*)GetParent(); + SCA_IObject *hitgameobj = info->m_gameobject; + if (hitgameobj == obj || info->m_type > KX_ClientObjectInfo::ACTOR) + { + // false hit + return false; + } + + bool bFound = false; + if (m_propertyname.Length() == 0) + { + bFound = true; + } + else + { + if (m_bFindMaterial) + { + if (info->m_auxilary_info) + { + bFound = (m_propertyname== ((char*)info->m_auxilary_info)); + } + } + else + { + bFound = hitgameobj->GetProperty(m_propertyname) != NULL; + } + } + if (bFound) + { + m_rayHit = true; + m_hitObject = hitgameobj; + m_hitPosition = hit_point; + m_hitNormal = hit_normal; + + } + + return true; +} bool KX_RaySensor::Evaluate(CValue* event) { @@ -168,115 +211,64 @@ bool KX_RaySensor::Evaluate(CValue* event) MT_Point3 topoint = frompoint + (m_distance) * todir; MT_Point3 resultpoint; MT_Vector3 resultnormal; - bool ready = false; - SumoPhysicsEnvironment *spe = dynamic_cast(m_scene->GetPhysicsEnvironment()); - if (!spe) + PHY_IPhysicsEnvironment* physics_environment = m_scene->GetPhysicsEnvironment(); + if (!physics_environment) { std::cout << "WARNING: Ray sensor " << GetName() << ": There is no physics environment!" << std::endl; std::cout << " Check universe for malfunction." << std::endl; return false; } - SM_Scene *scene = spe->GetSumoScene(); - KX_SumoPhysicsController *spc = dynamic_cast(obj->GetPhysicsController()); + KX_IPhysicsController* physics_controller = obj->GetPhysicsController(); + + // Use the parent's physics controller if obj has no physics controller. KX_GameObject *parent = obj->GetParent(); - if (!spc && parent) - spc = dynamic_cast(parent->GetPhysicsController()); + if (!physics_controller && parent) + physics_controller = parent->GetPhysicsController(); + if (parent) parent->Release(); - SM_Object *thisObj = spc?spc->GetSumoObject():NULL; - - do { - SM_Object* hitObj = scene->rayTest(thisObj, - frompoint, - topoint, - resultpoint, - resultnormal); - - if (hitObj) - { - - KX_ClientObjectInfo* info = static_cast(hitObj->getClientObject()); - bool bFound = false; - - if (!info) - { - std::cout<< "WARNING: Ray sensor " << GetName() << " cannot sense SM_Object " << hitObj << " - no client info.\n" << std::endl; - ready = true; - break; - } - - SCA_IObject *hitgameobj = info->m_gameobject; - - if (hitgameobj == obj || info->m_type > KX_ClientObjectInfo::ACTOR) - { - // false hit - KX_SumoPhysicsController *hitspc = dynamic_cast (static_cast (hitgameobj) ->GetPhysicsController()); - if (hitspc) - { - /* We add 0.01 of fudge, so that if the margin && radius == 0., we don't endless loop. */ - MT_Scalar marg = 0.01 + hitspc->GetSumoObject()->getMargin(); - if (hitspc->GetSumoObject()->getShapeProps()) - { - marg += 2*hitspc->GetSumoObject()->getShapeProps()->m_radius; - } - - /* Calculate the other side of this object */ - MT_Point3 hitObjPos; - hitspc->GetWorldPosition(hitObjPos); - MT_Vector3 hitvector = hitObjPos - resultpoint; - if (hitvector.dot(hitvector) > MT_EPSILON) - { - hitvector.normalize(); - marg *= 2.*todir.dot(hitvector); - } - frompoint = resultpoint + marg * todir; - } else { - ready = true; - } - } - else - { - ready = true; - if (m_propertyname.Length() == 0) - { - bFound = true; - } - else - { - if (m_bFindMaterial) - { - if (info->m_auxilary_info) - { - bFound = (m_propertyname== ((char*)info->m_auxilary_info)); - } - } - else - { - bFound = hitgameobj->GetProperty(m_propertyname) != NULL; - } - } + + KX_RayCast::RayTest(physics_controller, physics_environment, frompoint, topoint, resultpoint, resultnormal, KX_RayCast::Callback(this)); - if (bFound) - { - m_rayHit = true; - m_hitObject = hitgameobj; - m_hitPosition = resultpoint; - m_hitNormal = resultnormal; - - } - } - } - else - { - ready = true; - } - } - while (!ready); - +// do { +// PHY__Vector3 respos; +// PHY__Vector3 resnormal; +// +// PHY_IPhysicsController* hitCtrl = spe->rayTest(physCtrl, +// frompoint.x(),frompoint.y(),frompoint.z(), +// topoint.x(),topoint.y(),topoint.z(), +// respos[0],respos[1],respos[2], +// resnormal[0],resnormal[1],resnormal[2]); +// +// if (hitCtrl) +// { +// +// resultpoint = MT_Vector3(respos); +// resultnormal = MT_Vector3(resnormal); +// KX_ClientObjectInfo* info = static_cast(hitCtrl->getNewClientInfo()); +// bool bFound = false; +// +// if (!info) +// { +// std::cout<< "WARNING: Ray sensor " << GetName() << " cannot sense PHY_IPhysicsController - no client info.\n" << std::endl; +// ready = true; +// break; +// } +// +// +// +// } +// else +// { +// ready = true; +// } +// } +// while (!ready); +// /* now pass this result to some controller */ - if (m_rayHit) + if (m_rayHit) { if (!m_bTriggered) { @@ -284,10 +276,6 @@ bool KX_RaySensor::Evaluate(CValue* event) result = true; m_bTriggered = true; } - else - { - - } } else { diff --git a/source/gameengine/Ketsji/KX_RaySensor.h b/source/gameengine/Ketsji/KX_RaySensor.h index 8d361f53d3e..0e05c6021c0 100644 --- a/source/gameengine/Ketsji/KX_RaySensor.h +++ b/source/gameengine/Ketsji/KX_RaySensor.h @@ -38,6 +38,8 @@ #include "SCA_ISensor.h" #include "MT_Point3.h" +struct KX_ClientObjectInfo; + class KX_RaySensor : public SCA_ISensor { Py_Header; @@ -68,6 +70,8 @@ public: virtual bool Evaluate(CValue* event); virtual bool IsPositiveTrigger(); + bool RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_Vector3& hit_normal, void * const data); + KX_PYMETHOD_DOC(KX_RaySensor,GetHitObject); KX_PYMETHOD_DOC(KX_RaySensor,GetHitPosition); KX_PYMETHOD_DOC(KX_RaySensor,GetHitNormal); diff --git a/source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp b/source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp index 8af01c561f2..540e14d06ea 100644 --- a/source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp +++ b/source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp @@ -56,7 +56,7 @@ UpdateChildCoordinates( SG_Spatial * child, const SG_Spatial * parent ){ - assert(child != NULL); + MT_assert(child != NULL); // This way of accessing child coordinates is a bit cumbersome // be nice to have non constant reference access to these values. @@ -140,7 +140,7 @@ UpdateChildCoordinates( const SG_Spatial * parent ){ - assert(child != NULL); + MT_assert(child != NULL); const MT_Vector3 & child_scale = child->GetLocalScale(); const MT_Point3 & child_pos = child->GetLocalPosition(); @@ -225,7 +225,7 @@ UpdateChildCoordinates( SG_Spatial * child, const SG_Spatial * parent ){ - assert(child != NULL); + MT_assert(child != NULL); const MT_Vector3 & child_scale = child->GetLocalScale(); const MT_Point3 & child_pos = child->GetLocalPosition(); diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index 2046c52355c..eb3f8821b62 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -73,8 +73,6 @@ #include "PHY_IPhysicsEnvironment.h" #include "KX_IPhysicsController.h" -#include "SM_Scene.h" -#include "SumoPhysicsEnvironment.h" void* KX_SceneReplicationFunc(SG_IObject* node,void* gameobj,void* scene) { @@ -398,7 +396,7 @@ KX_GameObject* KX_Scene::AddNodeReplicaObject(class SG_IObject* node, class CVal } SG_IObject* replicanode = newobj->GetSGNode(); - // SG_Node* rootnode = (replicanode == m_rootnode ? NULL : m_rootnode); /*unused*/ + SG_Node* rootnode = (replicanode == m_rootnode ? NULL : m_rootnode); replicanode->SetSGClientObject(newobj); @@ -660,11 +658,10 @@ void KX_Scene::DelayedRemoveObject(class CValue* gameobj) void KX_Scene::NewRemoveObject(class CValue* gameobj) { KX_GameObject* newobj = (KX_GameObject*) gameobj; - //SM_Object* sumoObj = newobj->GetSumoObject(); - //if (sumoObj) - //{ - // this->GetSumoScene()->remove(*sumoObj); - //} + + //todo: look at this + //GetPhysicsEnvironment()->RemovePhysicsController(gameobj->getPhysicsController()); + // remove all sensors/controllers/actuators from logicsystem... SCA_SensorList& sensors = newobj->GetSensors(); @@ -1104,14 +1101,11 @@ void KX_Scene::SetNodeTree(SG_Tree* root) void KX_Scene::SetPhysicsEnvironment(class PHY_IPhysicsEnvironment* physEnv) { - SumoPhysicsEnvironment *sme = dynamic_cast(physEnv); m_physicsEnvironment = physEnv; - if (sme) - { - KX_TouchEventManager* touchmgr = new KX_TouchEventManager(m_logicmgr, sme->GetSumoScene()); - m_logicmgr->RegisterEventManager(touchmgr); - return; - } + + KX_TouchEventManager* touchmgr = new KX_TouchEventManager(m_logicmgr, physEnv); + m_logicmgr->RegisterEventManager(touchmgr); + return; } //---------------------------------------------------------------------------- diff --git a/source/gameengine/Ketsji/KX_Scene.h b/source/gameengine/Ketsji/KX_Scene.h index 27f234f52a6..0c0ee4e287a 100644 --- a/source/gameengine/Ketsji/KX_Scene.h +++ b/source/gameengine/Ketsji/KX_Scene.h @@ -128,7 +128,7 @@ protected: * physics engine abstraction */ - e_PhysicsEngine m_physicsEngine; + //e_PhysicsEngine m_physicsEngine; //who needs this ? class PHY_IPhysicsEnvironment* m_physicsEnvironment; /** diff --git a/source/gameengine/Ketsji/KX_SoundActuator.cpp b/source/gameengine/Ketsji/KX_SoundActuator.cpp index 793c3b84206..f7a2001fcdf 100644 --- a/source/gameengine/Ketsji/KX_SoundActuator.cpp +++ b/source/gameengine/Ketsji/KX_SoundActuator.cpp @@ -64,6 +64,8 @@ KX_SoundActuator::KX_SoundActuator(SCA_IObject* gameobj, m_startFrame = start; m_endFrame = end; m_pino = false; + + } diff --git a/source/gameengine/Ketsji/KX_SumoPhysicsController.cpp b/source/gameengine/Ketsji/KX_SumoPhysicsController.cpp index 8f284809a17..609f0fc0e0b 100644 --- a/source/gameengine/Ketsji/KX_SumoPhysicsController.cpp +++ b/source/gameengine/Ketsji/KX_SumoPhysicsController.cpp @@ -10,6 +10,8 @@ #include "KX_MotionState.h" #include "KX_ClientObjectInfo.h" +#include "PHY_IPhysicsEnvironment.h" + #ifdef HAVE_CONFIG_H #include #endif @@ -64,12 +66,9 @@ MT_Vector3 KX_SumoPhysicsController::GetLinearVelocity() } -void KX_SumoPhysicsController::resolveCombinedVelocities( - const MT_Vector3 & lin_vel, - const MT_Vector3 & ang_vel - ) +void KX_SumoPhysicsController::resolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ) { - SumoPhysicsController::resolveCombinedVelocities(lin_vel, ang_vel); + SumoPhysicsController::resolveCombinedVelocities(linvelX,linvelY,linvelZ,angVelX,angVelY,angVelZ); } void KX_SumoPhysicsController::ApplyTorque(const MT_Vector3& torque,bool local) @@ -215,3 +214,5 @@ KX_SumoPhysicsController::~KX_SumoPhysicsController() } + + diff --git a/source/gameengine/Ketsji/KX_SumoPhysicsController.h b/source/gameengine/Ketsji/KX_SumoPhysicsController.h index b160315ce53..b4b0f8a4cd0 100644 --- a/source/gameengine/Ketsji/KX_SumoPhysicsController.h +++ b/source/gameengine/Ketsji/KX_SumoPhysicsController.h @@ -33,7 +33,6 @@ #define __KX_SUMOPHYSICSCONTROLLER_H #include "PHY_IPhysicsController.h" -#include "SM_Object.h" // for SM_Callback /** Physics Controller, a special kind of Scene Graph Transformation Controller. @@ -54,7 +53,6 @@ class KX_SumoPhysicsController : public KX_IPhysicsController, public: KX_SumoPhysicsController( class SM_Scene* sumoScene, -/* DT_SceneHandle solidscene, */ class SM_Object* sumoObj, class PHY_IMotionState* motionstate ,bool dyna) @@ -76,7 +74,7 @@ public: MT_Vector3 GetVelocity(const MT_Point3& pos); void SetAngularVelocity(const MT_Vector3& ang_vel,bool local); void SetLinearVelocity(const MT_Vector3& lin_vel,bool local); - void resolveCombinedVelocities(const MT_Vector3 & lin_vel, const MT_Vector3 & ang_vel); + void resolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ); void SuspendDynamics(); @@ -108,8 +106,6 @@ public: ){ // intentionally empty }; - - }; #endif //__KX_SUMOPHYSICSCONTROLLER_H diff --git a/source/gameengine/Ketsji/KX_TouchEventManager.cpp b/source/gameengine/Ketsji/KX_TouchEventManager.cpp index a95e6a13548..575ade6dc3b 100644 --- a/source/gameengine/Ketsji/KX_TouchEventManager.cpp +++ b/source/gameengine/Ketsji/KX_TouchEventManager.cpp @@ -33,70 +33,50 @@ #include "SCA_ISensor.h" #include "KX_TouchSensor.h" #include "KX_GameObject.h" +#include "PHY_IPhysicsEnvironment.h" +#include "PHY_IPhysicsController.h" #ifdef HAVE_CONFIG_H #include #endif -#include "SM_Object.h" KX_TouchEventManager::KX_TouchEventManager(class SCA_LogicManager* logicmgr, - SM_Scene *scene) + PHY_IPhysicsEnvironment* physEnv) : SCA_EventManager(TOUCH_EVENTMGR), m_logicmgr(logicmgr), - m_scene(scene) + m_physEnv(physEnv) { - //m_scene->addTouchCallback(STATIC_RESPONSE, KX_TouchEventManager::collisionResponse, this); - m_scene->addTouchCallback(OBJECT_RESPONSE, KX_TouchEventManager::collisionResponse, this); - m_scene->addTouchCallback(SENSOR_RESPONSE, KX_TouchEventManager::collisionResponse, this); + //notm_scene->addTouchCallback(STATIC_RESPONSE, KX_TouchEventManager::collisionResponse, this); + + //m_scene->addTouchCallback(OBJECT_RESPONSE, KX_TouchEventManager::collisionResponse, this); + //m_scene->addTouchCallback(SENSOR_RESPONSE, KX_TouchEventManager::collisionResponse, this); + + m_physEnv->addTouchCallback(PHY_OBJECT_RESPONSE, KX_TouchEventManager::newCollisionResponse, this); + m_physEnv->addTouchCallback(PHY_SENSOR_RESPONSE, KX_TouchEventManager::newCollisionResponse, this); + } -DT_Bool KX_TouchEventManager::HandleCollision(void* object1, void* object2, const DT_CollData *coll_data) +bool KX_TouchEventManager::NewHandleCollision(void* object1, void* object2, const PHY_CollData *coll_data) { - SM_Object * obj1 = static_cast(object1); - SM_Object * obj2 = static_cast(object2); + + PHY_IPhysicsController* obj1 = static_cast(object1); + PHY_IPhysicsController* obj2 = static_cast(object2); - m_collisions.insert(std::pair(obj1, obj2)); + m_newCollisions.insert(std::pair(obj1, obj2)); - return DT_CONTINUE; + return false; } -/* -DT_Bool KX_TouchEventManager::HandleCollision(void* object1,void* object2, - const DT_CollData * coll_data) -{ - SM_Object * obj1 = (SM_Object *) object1; - SM_Object * obj2 = (SM_Object *) object2; - for ( vector::iterator it = m_sensors.begin(); !(it==m_sensors.end()); it++) - { - KX_GameObject* gameobj = ((KX_GameObject*)((KX_TouchSensor*)*it)->GetParent()); - KX_ClientObjectInfo *client_info = (KX_ClientObjectInfo *) obj1->getClientObject(); -// Enable these printfs to create excesive debug info -// printf("KX_TEM::HC: Sensor %s\tGO: %p o1: %s (%p)", (const char *) (*it)->GetName(), gameobj, (const char *) ((KX_GameObject *) client_info->m_clientobject)->GetName(), client_info->m_clientobject); - if (client_info && client_info->m_clientobject == gameobj) - ((KX_TouchSensor*)*it)->HandleCollision(object1,object2,coll_data); - - client_info = (KX_ClientObjectInfo *) obj2->getClientObject(); -// printf(" o2: %s (%p)\n", (const char *) ((KX_GameObject *) client_info->m_clientobject)->GetName(), client_info->m_clientobject); - if (client_info && client_info->m_clientobject == gameobj) - ((KX_TouchSensor*)*it)->HandleCollision(object1,object2,coll_data); - - } - - return DT_CONTINUE; -} - -*/ - -DT_Bool KX_TouchEventManager::collisionResponse(void *client_data, +bool KX_TouchEventManager::newCollisionResponse(void *client_data, void *object1, void *object2, - const DT_CollData *coll_data) + const PHY_CollData *coll_data) { KX_TouchEventManager *touchmgr = (KX_TouchEventManager *) client_data; - touchmgr->HandleCollision(object1, object2, coll_data); - return DT_CONTINUE; + touchmgr->NewHandleCollision(object1, object2, coll_data); + return false; } void KX_TouchEventManager::RegisterSensor(SCA_ISensor* sensor) @@ -131,20 +111,25 @@ void KX_TouchEventManager::NextFrame() for (it = m_sensors.begin();!(it==m_sensors.end());++it) static_cast(*it)->SynchronizeTransform(); - for (std::set::iterator cit = m_collisions.begin(); cit != m_collisions.end(); ++cit) + for (std::set::iterator cit = m_newCollisions.begin(); cit != m_newCollisions.end(); ++cit) { - KX_ClientObjectInfo *client_info = static_cast((*cit).first->getClientObject()); + PHY_IPhysicsController* ctrl1 = (*cit).first; + PHY_IPhysicsController* ctrl2 = (*cit).second; +// KX_GameObject* gameOb1 = ctrl1->getClientInfo(); +// KX_GameObject* gameOb1 = ctrl1->getClientInfo(); + + KX_ClientObjectInfo *client_info = static_cast(ctrl1->getNewClientInfo()); list::iterator sit; for ( sit = client_info->m_sensors.begin(); sit != client_info->m_sensors.end(); ++sit) - static_cast(*sit)->HandleCollision((*cit).first, (*cit).second, NULL); + static_cast(*sit)->NewHandleCollision((*cit).first, (*cit).second, NULL); - client_info = static_cast((*cit).second->getClientObject()); + client_info = static_cast((*cit).second->getNewClientInfo()); for ( sit = client_info->m_sensors.begin(); sit != client_info->m_sensors.end(); ++sit) - static_cast(*sit)->HandleCollision((*cit).second, (*cit).first, NULL); + static_cast(*sit)->NewHandleCollision((*cit).second, (*cit).first, NULL); } - m_collisions.clear(); + m_newCollisions.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 128758f0be6..21faceef799 100644 --- a/source/gameengine/Ketsji/KX_TouchEventManager.h +++ b/source/gameengine/Ketsji/KX_TouchEventManager.h @@ -32,6 +32,7 @@ #ifndef __KX_TOUCHEVENTMANAGER #define __KX_TOUCHEVENTMANAGER + #include "SCA_EventManager.h" #include "KX_TouchSensor.h" #include "KX_GameObject.h" @@ -40,35 +41,39 @@ #include class SCA_ISensor; -class SM_Object; +class PHY_IPhysicsEnvironment; class KX_TouchEventManager : public SCA_EventManager { - typedef std::pair Collision; + typedef std::pair NewCollision; class SCA_LogicManager* m_logicmgr; - SM_Scene *m_scene; + PHY_IPhysicsEnvironment* m_physEnv; - std::set m_collisions; + std::set m_newCollisions; + + static bool newCollisionResponse(void *client_data, + void *object1, + void *object2, + const PHY_CollData *coll_data); + + virtual bool NewHandleCollision(void* obj1,void* obj2, + const PHY_CollData * coll_data); + + + - static DT_Bool collisionResponse(void *client_data, - void *object1, - void *object2, - const DT_CollData *coll_data); - - virtual DT_Bool HandleCollision(void* obj1,void* obj2, - const DT_CollData * coll_data); - public: KX_TouchEventManager(class SCA_LogicManager* logicmgr, - SM_Scene *scene); + PHY_IPhysicsEnvironment* physEnv); virtual void NextFrame(); virtual void EndFrame(); virtual void RemoveSensor(class SCA_ISensor* sensor); virtual void RegisterSensor(SCA_ISensor* sensor); SCA_LogicManager* GetLogicManager() { return m_logicmgr;} - SM_Scene *GetSumoScene() { return m_scene; } + PHY_IPhysicsEnvironment *GetPhysicsEnvironment() { return m_physEnv; } + }; #endif //__KX_TOUCHEVENTMANAGER diff --git a/source/gameengine/Ketsji/KX_TouchSensor.cpp b/source/gameengine/Ketsji/KX_TouchSensor.cpp index 64dc175f451..e89b1e41434 100644 --- a/source/gameengine/Ketsji/KX_TouchSensor.cpp +++ b/source/gameengine/Ketsji/KX_TouchSensor.cpp @@ -37,9 +37,9 @@ #include "SCA_LogicManager.h" #include "KX_GameObject.h" #include "KX_TouchEventManager.h" -#include "SM_Object.h" #include "KX_SumoPhysicsController.h" #include +#include "PHY_IPhysicsEnvironment.h" #ifdef HAVE_CONFIG_H #include @@ -52,13 +52,13 @@ void KX_TouchSensor::SynchronizeTransform() { - if (m_sumoObj) + if (m_physCtrl) { - m_sumoObj->setPosition(((KX_GameObject*)GetParent())->NodeGetWorldPosition()); - m_sumoObj->setOrientation( - ((KX_GameObject*)GetParent())->NodeGetWorldOrientation().getRotation() - ); - m_sumoObj->calcXform(); + MT_Vector3 pos = ((KX_GameObject*)GetParent())->NodeGetWorldPosition(); + MT_Quaternion orn = ((KX_GameObject*)GetParent())->NodeGetWorldOrientation().getRotation(); + m_physCtrl->setPosition(pos.x(),pos.y(),pos.z()); + m_physCtrl->setOrientation(orn.x(),orn.y(),orn.z(),orn.w()); + m_physCtrl->calcXform(); } } @@ -84,7 +84,7 @@ bool KX_TouchSensor::Evaluate(CValue* event) return result; } -KX_TouchSensor::KX_TouchSensor(SCA_EventManager* eventmgr,KX_GameObject* gameobj,/*SM_Object* sumoObj,*/bool bFindMaterial,const STR_String& touchedpropname,PyTypeObject* T) +KX_TouchSensor::KX_TouchSensor(SCA_EventManager* eventmgr,KX_GameObject* gameobj,bool bFindMaterial,const STR_String& touchedpropname,PyTypeObject* T) :SCA_ISensor(gameobj,eventmgr,T), m_touchedpropname(touchedpropname), m_bFindMaterial(bFindMaterial), @@ -94,7 +94,7 @@ m_bCollision(false), m_bTriggered(false), m_bLastTriggered(false) { - // KX_TouchEventManager* touchmgr = (KX_TouchEventManager*) eventmgr; /*unused*/ + KX_TouchEventManager* touchmgr = (KX_TouchEventManager*) eventmgr; // m_resptable = touchmgr->GetResponseTable(); // m_solidHandle = m_sumoObj->getObjectHandle(); @@ -107,10 +107,8 @@ m_bLastTriggered(false) client_info->m_auxilary_info = NULL; client_info->m_sensors.push_back(this); - KX_SumoPhysicsController *sphy = dynamic_cast(gameobj->GetPhysicsController()); - if (sphy) - m_sumoObj = sphy->GetSumoObject(); - + m_physCtrl = dynamic_cast(gameobj->GetPhysicsController()); + MT_assert( !gameobj->GetPhysicsController() || m_physCtrl ); } @@ -136,10 +134,10 @@ CValue* KX_TouchSensor::GetReplica() void KX_TouchSensor::ReParent(SCA_IObject* parent) { KX_GameObject *gameobj = static_cast(parent); - KX_SumoPhysicsController *sphy = dynamic_cast(((KX_GameObject*)parent)->GetPhysicsController()); + PHY_IPhysicsController *sphy = dynamic_cast(((KX_GameObject*)parent)->GetPhysicsController()); if (sphy) - m_sumoObj = sphy->GetSumoObject(); - + m_physCtrl = sphy; + // m_solidHandle = m_sumoObj->getObjectHandle(); KX_ClientObjectInfo *client_info = gameobj->getClientInfo(); client_info->m_gameobject = gameobj; @@ -150,25 +148,25 @@ void KX_TouchSensor::ReParent(SCA_IObject* parent) void KX_TouchSensor::RegisterSumo(KX_TouchEventManager *touchman) { - if (m_sumoObj) + if (m_physCtrl) { - touchman->GetSumoScene()->requestCollisionCallback(*m_sumoObj); + touchman->GetPhysicsEnvironment()->requestCollisionCallback(m_physCtrl); // collision // Deprecated } } -DT_Bool KX_TouchSensor::HandleCollision(void* obj1,void* obj2,const DT_CollData * coll_data) +bool KX_TouchSensor::NewHandleCollision(void*object1,void*object2,const PHY_CollData* colldata) { - // KX_TouchEventManager* toucheventmgr = (KX_TouchEventManager*)m_eventmgr; /*unused*/ + KX_TouchEventManager* toucheventmgr = (KX_TouchEventManager*)m_eventmgr; KX_GameObject* parent = (KX_GameObject*)GetParent(); - // need the mapping from SM_Objects to gameobjects now + // need the mapping from PHY_IPhysicsController to gameobjects now - KX_ClientObjectInfo* client_info = static_cast (obj1 == m_sumoObj? - ((SM_Object*)obj2)->getClientObject() : - ((SM_Object*)obj1)->getClientObject()); + KX_ClientObjectInfo* client_info = static_cast (object1 == m_physCtrl? + ((PHY_IPhysicsController*)object2)->getNewClientInfo(): + ((PHY_IPhysicsController*)object1)->getNewClientInfo()); KX_GameObject* gameobj = ( client_info ? client_info->m_gameobject : @@ -336,11 +334,10 @@ PyObject* KX_TouchSensor::PyGetHitObjectList(PyObject* self, * - this also doesn't work (obviously) for multi-materials... */ KX_GameObject* gameob = (KX_GameObject*) m_colliders->GetValue(i); - KX_SumoPhysicsController* spc = dynamic_cast(gameob->GetPhysicsController()); - SM_Object* smob = spc?spc->GetSumoObject():NULL; + PHY_IPhysicsController* spc = dynamic_cast(gameob->GetPhysicsController()); - if (smob) { - KX_ClientObjectInfo* cl_inf = static_cast(smob->getClientObject()); + if (spc) { + KX_ClientObjectInfo* cl_inf = static_cast(spc->getNewClientInfo()); if (m_touchedpropname == ((char*)cl_inf->m_auxilary_info)) { newList->Add(m_colliders->GetValue(i)->AddRef()); diff --git a/source/gameengine/Ketsji/KX_TouchSensor.h b/source/gameengine/Ketsji/KX_TouchSensor.h index 9dd17a5fe83..f1a2a26e822 100644 --- a/source/gameengine/Ketsji/KX_TouchSensor.h +++ b/source/gameengine/Ketsji/KX_TouchSensor.h @@ -38,8 +38,7 @@ #include "SCA_ISensor.h" #include "ListValue.h" -#include -#include "SM_Scene.h" +struct PHY_CollData; #include "KX_ClientObjectInfo.h" @@ -57,10 +56,9 @@ protected: bool m_bFindMaterial; class SCA_EventManager* m_eventmgr; - class SM_Object* m_sumoObj; - DT_ObjectHandle m_solidHandle; - DT_RespTableHandle m_resptable; - + class PHY_IPhysicsController* m_physCtrl; + class PHY_ResponseTable* m_responstTable; + class PHY_PhysicsController* m_responsObject; bool m_bCollision; bool m_bTriggered; @@ -71,7 +69,6 @@ protected: public: KX_TouchSensor(class SCA_EventManager* eventmgr, class KX_GameObject* gameobj, - /*class SM_Object* sumoObj,*/ bool fFindMaterial, const STR_String& touchedpropname, PyTypeObject* T=&Type) ; @@ -84,12 +81,12 @@ public: virtual void RegisterSumo(KX_TouchEventManager* touchman); - virtual DT_Bool HandleCollision(void* obj1,void* obj2, - const DT_CollData * coll_data); +// virtual DT_Bool HandleCollision(void* obj1,void* obj2, +// const DT_CollData * coll_data); + virtual bool NewHandleCollision(void*obj1,void*obj2,const PHY_CollData* colldata); - SM_Object* GetSumoObject() { return m_sumoObj; }; - + PHY_PhysicsController* GetPhysicsController() { return m_responsObject;} virtual bool IsPositiveTrigger() { diff --git a/source/gameengine/Ketsji/SConscript b/source/gameengine/Ketsji/SConscript index 35cfa47700e..0407232a9ac 100644 --- a/source/gameengine/Ketsji/SConscript +++ b/source/gameengine/Ketsji/SConscript @@ -26,6 +26,7 @@ source_files = ['KX_WorldIpoController.cpp', 'KX_SCA_AddObjectActuator.cpp', 'KX_RaySensor.cpp', 'KX_RayEventManager.cpp', + 'KX_RayCast.cpp', 'KX_RadarSensor.cpp', 'KX_PyMath.cpp', 'KX_PythonInit.cpp', diff --git a/source/gameengine/Network/LoopBackNetwork/NG_LoopBackNetworkDeviceInterface.cpp b/source/gameengine/Network/LoopBackNetwork/NG_LoopBackNetworkDeviceInterface.cpp index ec86e510c49..e36aa4750af 100644 --- a/source/gameengine/Network/LoopBackNetwork/NG_LoopBackNetworkDeviceInterface.cpp +++ b/source/gameengine/Network/LoopBackNetwork/NG_LoopBackNetworkDeviceInterface.cpp @@ -58,6 +58,9 @@ void NG_LoopBackNetworkDeviceInterface::NextFrame() { // Release reference to the messages while emptying the queue while (m_messages[m_currentQueue].size() > 0) { +#ifdef NAN_NET_DEBUG + printf("NG_LBNDI::NextFrame %d '%s'\n", m_currentQueue, m_messages[m_currentQueue][0]->GetSubject().ReadPtr()); +#endif // Should do assert(m_events[0]); m_messages[m_currentQueue][0]->Release(); m_messages[m_currentQueue].pop_front(); @@ -75,7 +78,8 @@ STR_String NG_LoopBackNetworkDeviceInterface::GetNetworkVersion() void NG_LoopBackNetworkDeviceInterface::SendNetworkMessage(NG_NetworkMessage* nwmsg) { #ifdef NAN_NET_DEBUG - printf("NG_LBNDI::SendNetworkMessage '%s'->'%s' '%s' '%s'\n", + printf("NG_LBNDI::SendNetworkMessage %d, '%s'->'%s' '%s' '%s'\n", + 1-m_currentQueue, nwmsg->GetDestinationName().ReadPtr(), nwmsg->GetSenderName().ReadPtr(), nwmsg->GetSubject().ReadPtr(), @@ -102,7 +106,8 @@ vector NG_LoopBackNetworkDeviceInterface::RetrieveNetworkMes messages.push_back(*mesit); #ifdef NAN_NET_DEBUG - printf("NG_LBNDI::RetrieveNetworkMessages '%s'->'%s' '%s' '%s'\n", + printf("NG_LBNDI::RetrieveNetworkMessages %d '%s'->'%s' '%s' '%s'\n", + m_currentQueue, (*mesit)->GetDestinationName().ReadPtr(), (*mesit)->GetSenderName().ReadPtr(), (*mesit)->GetSubject().ReadPtr(), diff --git a/source/gameengine/Network/Makefile b/source/gameengine/Network/Makefile index 3c5ed35e539..dd4819f46e5 100644 --- a/source/gameengine/Network/Makefile +++ b/source/gameengine/Network/Makefile @@ -39,6 +39,7 @@ include nan_compile.mk CCFLAGS += $(LEVEL_1_CPP_WARNINGS) CPPFLAGS += -I$(NAN_STRING)/include +CPPFLAGS += -I$(NAN_MOTO)/include CPPFLAGS += -I../GameLogic CPPFLAGS += -I../../kernel/gen_system diff --git a/source/gameengine/Network/NG_NetworkScene.cpp b/source/gameengine/Network/NG_NetworkScene.cpp index b867791e12d..c66eb3730ac 100644 --- a/source/gameengine/Network/NG_NetworkScene.cpp +++ b/source/gameengine/Network/NG_NetworkScene.cpp @@ -31,7 +31,7 @@ * NetworkSceneManagement generic implementation */ #include -#include +#include #include #include "NG_NetworkScene.h" @@ -199,7 +199,7 @@ vector NG_NetworkScene::FindMessages( // possibly it's there, but maybe not (false hit) if (to.IsEmpty()) { // take all messages, and check other fields - assert("objectnames that are empty are not valid, so make it a hobby project :)\n"); + MT_assert(!"objectnames that are empty are not valid, so make it a hobby project :)\n"); } else { //todo: find intersection of messages (that are in other 2 maps) vector** tolistptr = m_messagesByDestinationName[to]; diff --git a/source/gameengine/Network/SConscript b/source/gameengine/Network/SConscript index 40e3278e9e9..489bea7a970 100755 --- a/source/gameengine/Network/SConscript +++ b/source/gameengine/Network/SConscript @@ -10,7 +10,8 @@ source_files = ['NG_NetworkMessage.cpp', ng_network_env.Append (CPPPATH=['.', '#source/kernel/gen_system', - '#intern/string' + '#intern/string', + '#intern/moto/include' ]) ng_network_env.Library (target='#'+user_options_dict['BUILD_DIR']+'/lib/NG_network', source=source_files) diff --git a/source/gameengine/Physics/BlOde/OdePhysicsController.cpp b/source/gameengine/Physics/BlOde/OdePhysicsController.cpp index 6d4adc961c8..d403d5100fc 100644 --- a/source/gameengine/Physics/BlOde/OdePhysicsController.cpp +++ b/source/gameengine/Physics/BlOde/OdePhysicsController.cpp @@ -421,6 +421,12 @@ void ODEPhysicsController::getOrientation(float &quatImag0,float &quatImag1,floa quatReal=q[3]; } +void ODEPhysicsController::getPosition(PHY__Vector3& pos) const +{ + m_MotionState->getWorldPosition(pos[0],pos[1],pos[2]); + +} + void ODEPhysicsController::setPosition(float posX,float posY,float posZ) { if (!m_bPhantom) diff --git a/source/gameengine/Physics/BlOde/OdePhysicsController.h b/source/gameengine/Physics/BlOde/OdePhysicsController.h index d7d3ba160f7..4f4acb5cd18 100644 --- a/source/gameengine/Physics/BlOde/OdePhysicsController.h +++ b/source/gameengine/Physics/BlOde/OdePhysicsController.h @@ -62,6 +62,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); // physics methods @@ -73,6 +75,10 @@ public: virtual void SetActive(bool active){}; virtual void SuspendDynamics(); virtual void RestoreDynamics(); + virtual void resolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ) + { + //todo ? + } /** @@ -102,9 +108,13 @@ public: */ virtual bool SynchronizeMotionStates(float time); + virtual void calcXform(){} + virtual void SetMargin(float margin) {} + virtual float GetMargin() const {return 0.f;} + // clientinfo for raycasts for example - virtual void* getClientInfo() { return m_clientInfo;} - virtual void setClientInfo(void* clientinfo) {m_clientInfo = clientinfo;}; + virtual void* getNewClientInfo() { return m_clientInfo;} + virtual void setNewClientInfo(void* clientinfo) {m_clientInfo = clientinfo;}; void* m_clientInfo; struct dxBody* GetOdeBodyId() { return m_bodyId; } diff --git a/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.cpp b/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.cpp index 1316311b881..54d94351815 100644 --- a/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.cpp +++ b/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.cpp @@ -36,12 +36,13 @@ ODEPhysicsEnvironment::ODEPhysicsEnvironment() { m_OdeWorld = dWorldCreate(); - m_OdeSpace = dHashSpaceCreate(); + m_OdeSpace = dHashSpaceCreate(0); m_OdeContactGroup = dJointGroupCreate (0); dWorldSetCFM (m_OdeWorld,1e-5f); m_JointGroup = dJointGroupCreate(0); - + + setFixedTimeStep(true,1.f/60.f); } @@ -55,19 +56,60 @@ ODEPhysicsEnvironment::~ODEPhysicsEnvironment() dWorldDestroy (m_OdeWorld); } -bool ODEPhysicsEnvironment::proceed(double timeStep) -{ - // ode collision update - dSpaceCollide (m_OdeSpace,this,&ODEPhysicsEnvironment::OdeNearCallback); - int m_odeContacts = GetNumOdeContacts(); - - //physics integrator + resolver update - dWorldStep (m_OdeWorld,timeStep); - - //clear collision points - this->ClearOdeContactGroup(); - + +void ODEPhysicsEnvironment::setFixedTimeStep(bool useFixedTimeStep,float fixedTimeStep) +{ + m_useFixedTimeStep = useFixedTimeStep; + + if (useFixedTimeStep) + { + m_fixedTimeStep = fixedTimeStep; + } else + { + m_fixedTimeStep = 0.f; + } + m_currentTime = 0.f; + + //todo:implement fixed timestepping + +} +float ODEPhysicsEnvironment::getFixedTimeStep() +{ + return m_fixedTimeStep; +} + + + +bool ODEPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep1) +{ + + float deltaTime = timeStep1; + int numSteps = 1; + + if (m_useFixedTimeStep) + { + m_currentTime += timeStep1; + // equal to subSampling (might be a little smaller). + numSteps = (int)(m_currentTime / m_fixedTimeStep); + m_currentTime -= m_fixedTimeStep * (float)numSteps; + deltaTime = m_fixedTimeStep; + //todo: experiment by smoothing the remaining time over the substeps + } + + for (int i=0;iClearOdeContactGroup(); + } return true; } @@ -168,9 +210,11 @@ void ODEPhysicsEnvironment::removeConstraint(int constraintid) } } -PHY_IPhysicsController* ODEPhysicsEnvironment::rayTest(void* ignoreClient,float fromX,float fromY,float fromZ, float toX,float toY,float toZ, +PHY_IPhysicsController* ODEPhysicsEnvironment::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) { + + //m_OdeWorld //collision detection / raytesting return NULL; } diff --git a/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.h b/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.h index 828e3ff3269..2214d642d7b 100644 --- a/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.h +++ b/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.h @@ -32,20 +32,44 @@ class ODEPhysicsEnvironment : public PHY_IPhysicsEnvironment { + bool m_useFixedTimeStep; + float m_fixedTimeStep; + float m_currentTime; + public: ODEPhysicsEnvironment(); virtual ~ODEPhysicsEnvironment(); + virtual void beginFrame() {} + virtual void endFrame() {} + + // Perform an integration step of duration 'timeStep'. - virtual bool proceed(double timeStep); + 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); + + //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) {return 0;} + virtual PHY_IPhysicsController* CreateConeController(float coneradius,float coneheight) { return 0;} + + + struct dxWorld* GetOdeWorld() { return m_OdeWorld; }; struct dxSpace* GetOdeSpace() { return m_OdeSpace;}; diff --git a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.cpp b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.cpp index d0abd6e3859..a640acd9b3d 100644 --- a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.cpp +++ b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.cpp @@ -58,7 +58,9 @@ void DummyPhysicsEnvironment::endFrame() // end of logic frame: clear forces } -bool DummyPhysicsEnvironment::proceed(double timeStep) + + +bool DummyPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep) { //step physics simulation, typically perform @@ -68,6 +70,17 @@ bool DummyPhysicsEnvironment::proceed(double timeStep) // return true if an update was done. return true; } +void DummyPhysicsEnvironment::setFixedTimeStep(bool useFixedTimeStep,float fixedTimeStep) +{ +} + +float DummyPhysicsEnvironment::getFixedTimeStep() +{ + return 0.f; +} + + + void DummyPhysicsEnvironment::setGravity(float x,float y,float z) { @@ -95,7 +108,7 @@ void DummyPhysicsEnvironment::removeConstraint(int constraintid) } } -PHY_IPhysicsController* DummyPhysicsEnvironment::rayTest(void* ignoreClient,float fromX,float fromY,float fromZ, float toX,float toY,float toZ, +PHY_IPhysicsController* DummyPhysicsEnvironment::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) { //collision detection / raytesting diff --git a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h index 65f42141045..fde27e822d6 100644 --- a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h +++ b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h @@ -51,7 +51,10 @@ public: virtual void beginFrame(); virtual void endFrame(); // Perform an integration step of duration 'timeStep'. - virtual bool proceed (double timeStep); + 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, @@ -59,10 +62,21 @@ public: 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); + //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) {return 0;} + virtual PHY_IPhysicsController* CreateConeController(float coneradius,float coneheight) { return 0;} + + }; #endif //_DUMMYPHYSICSENVIRONMENT 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 #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]); } @@ -418,4 +446,52 @@ void SumoPhysicsController::setSumoTransform(bool nondynaonly) m_sumoObj->calcXform(); } } +} + + + // 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 (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 #ifdef HAVE_CONFIG_H #include #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 (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(ctrl); + SM_Object* smObject = smctrl->GetSumoObject(); + assert(smObject); + if (smObject) + { + m_sumoScene->addSensor(*smObject); + } +} +void SumoPhysicsEnvironment::removeSensor(PHY_IPhysicsController* ctrl) +{ + SumoPhysicsController* smctrl = dynamic_cast(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(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 /** * 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 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; diff --git a/source/gameengine/Physics/common/PHY_DynamicTypes.h b/source/gameengine/Physics/common/PHY_DynamicTypes.h index 336e29e827a..f800a5494cb 100644 --- a/source/gameengine/Physics/common/PHY_DynamicTypes.h +++ b/source/gameengine/Physics/common/PHY_DynamicTypes.h @@ -42,6 +42,54 @@ typedef enum PHY_ScalarType { PHY_FIXEDPOINT88 } PHY_ScalarType; +class PHY_ResponseTable; + +class PHY_Shape; + +struct PHY__Vector3 +{ + float m_vec[4]; + operator const float* () const + { + return &m_vec[0]; + } + operator float* () + { + return &m_vec[0]; + } +}; +//typedef float PHY__Vector3[4]; + +typedef enum +{ + PHY_FH_RESPONSE, + PHY_SENSOR_RESPONSE, /* Touch Sensors */ + PHY_CAMERA_RESPONSE, /* Visibility Culling */ + PHY_OBJECT_RESPONSE, /* Object Dynamic Geometry Response */ + PHY_STATIC_RESPONSE, /* Static Geometry Response */ + + PHY_NUM_RESPONSE +}; + + typedef struct PHY_CollData { + PHY__Vector3 m_point1; /* Point in object1 in world coordinates */ + PHY__Vector3 m_point2; /* Point in object2 in world coordinates */ + PHY__Vector3 m_normal; /* point2 - point1 */ + } PHY_CollData; + +/* A response callback is called by SOLID for each pair of collding objects. 'client-data' + is a pointer to an arbitrary structure in the client application. The client objects are + pointers to structures in the client application associated with the coliding objects. + 'coll_data' is the collision data computed by SOLID. +*/ + + typedef bool (*PHY_ResponseCallback)(void *client_data, + void *client_object1, + void *client_object2, + const PHY_CollData *coll_data); + + + /// PHY_PhysicsType enumerates all possible Physics Entities. /// It is mainly used to create/add Physics Objects diff --git a/source/gameengine/Physics/common/PHY_IPhysicsController.h b/source/gameengine/Physics/common/PHY_IPhysicsController.h index f517abc54ff..cdf203ac17e 100644 --- a/source/gameengine/Physics/common/PHY_IPhysicsController.h +++ b/source/gameengine/Physics/common/PHY_IPhysicsController.h @@ -32,7 +32,7 @@ #ifndef PHY_IPHYSICSCONTROLLER_H #define PHY_IPHYSICSCONTROLLER_H -#include "MT_Vector3.h" +#include "PHY_DynamicTypes.h" /** PHY_IPhysicsController is the abstract simplified Interface to a physical object. @@ -65,6 +65,7 @@ class PHY_IPhysicsController virtual void getOrientation(float &quatImag0,float &quatImag1,float &quatImag2,float &quatReal)=0; virtual void setOrientation(float quatImag0,float quatImag1,float quatImag2,float quatReal)=0; virtual void setPosition(float posX,float posY,float posZ)=0; + virtual void getPosition(PHY__Vector3& pos) const=0; virtual void setScaling(float scaleX,float scaleY,float scaleZ)=0; // physics methods @@ -72,7 +73,8 @@ class PHY_IPhysicsController virtual void ApplyForce(float forceX,float forceY,float forceZ,bool local)=0; virtual void SetAngularVelocity(float ang_velX,float ang_velY,float ang_velZ,bool local)=0; virtual void SetLinearVelocity(float lin_velX,float lin_velY,float lin_velZ,bool local)=0; - virtual void resolveCombinedVelocities(const MT_Vector3 & lin_vel, const MT_Vector3 & ang_vel ) = 0; + virtual void resolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ) = 0; + virtual void applyImpulse(float attachX,float attachY,float attachZ, float impulseX,float impulseY,float impulseZ)=0; virtual void SetActive(bool active)=0; @@ -85,8 +87,16 @@ class PHY_IPhysicsController virtual void setRigidBody(bool rigid)=0; // clientinfo for raycasts for example - virtual void* getClientInfo()=0; - virtual void setClientInfo(void* clientinfo)=0; + virtual void* getNewClientInfo()=0; + virtual void setNewClientInfo(void* clientinfo)=0; + virtual PHY_IPhysicsController* GetReplica() {return 0;} + + virtual void calcXform() =0; + virtual void SetMargin(float margin) =0; + virtual float GetMargin() const=0; + virtual float GetRadius() const { return 0.f;} + PHY__Vector3 GetWorldPosition(PHY__Vector3& localpos); + }; #endif //PHY_IPHYSICSCONTROLLER_H diff --git a/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h b/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h index 0fdac35f514..2ffcf80a62b 100644 --- a/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h +++ b/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h @@ -46,7 +46,12 @@ class PHY_IPhysicsEnvironment virtual void beginFrame() = 0; virtual void endFrame() = 0; /// Perform an integration step of duration 'timeStep'. - virtual bool proceed(double timeStep)=0; + virtual bool proceedDeltaTime(double curTime,float timeStep)=0; + virtual void setFixedTimeStep(bool useFixedTimeStep,float fixedTimeStep)=0; + //returns 0.f if no fixed timestep is used + virtual float getFixedTimeStep()=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, @@ -54,8 +59,19 @@ class PHY_IPhysicsEnvironment float axisX,float axisY,float axisZ)=0; virtual void removeConstraint(int constraintid)=0; - 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)=0; + + + //Methods for gamelogic collision/physics callbacks + //todo: + virtual void addSensor(PHY_IPhysicsController* ctrl)=0; + virtual void removeSensor(PHY_IPhysicsController* ctrl)=0; + virtual void addTouchCallback(int response_class, PHY_ResponseCallback callback, void *user)=0; + virtual void requestCollisionCallback(PHY_IPhysicsController* ctrl)=0; + virtual PHY_IPhysicsController* CreateSphereController(float radius,const PHY__Vector3& position) =0; + virtual PHY_IPhysicsController* CreateConeController(float coneradius,float coneheight)=0; + }; #endif //_IPHYSICSENVIRONMENT diff --git a/source/gameengine/PyDoc/KX_PolygonMaterial.py b/source/gameengine/PyDoc/KX_PolygonMaterial.py index c86817a40f1..cfc4257f95d 100644 --- a/source/gameengine/PyDoc/KX_PolygonMaterial.py +++ b/source/gameengine/PyDoc/KX_PolygonMaterial.py @@ -120,7 +120,7 @@ class KX_PolygonMaterial: print "Shader failed to validate" return - def Activate(self, rasty, cachingInfo, mat): + def activate(self, rasty, cachingInfo, mat): self.pass_no+=1 if (self.pass_no == 1): glDisable(GL_COLOR_MATERIAL) @@ -246,7 +246,7 @@ class KX_PolygonMaterial: Example:: class PyMaterial: def __init__(self): - self.pass_no = 0 + self.pass_no = -1 def activate(self, rasty, cachingInfo, material): # Activate the material here. @@ -262,13 +262,14 @@ class KX_PolygonMaterial: # was added to # default material properties: + self.pass_no += 1 if self.pass_no == 0: material.activate(rasty, cachingInfo) - self.pass_no = 1 # Return True to do this pass return True - self.pass_no = 0 + # clean up and return False to finish. + self.pass_no = -1 return False # Create a new Python Material and pass it to the renderer.