diff options
author | Kester Maddock <Christopher.Maddock.1@uni.massey.ac.nz> | 2005-03-25 13:33:39 +0300 |
---|---|---|
committer | Kester Maddock <Christopher.Maddock.1@uni.massey.ac.nz> | 2005-03-25 13:33:39 +0300 |
commit | c844aa265ad4eb50ad0e18661470fa6092052728 (patch) | |
tree | c4a778ab1227e4266022fd076e8a0cb709badd13 /source/gameengine/Ketsji | |
parent | 3dd17cec3bcaa3885e14630e6a71a8486e9b2697 (diff) |
Big patches:
Erwin Coumans: Abstract the physics engine
Charlie C: Joystick fixes
Me: Moved the ray cast (shadows, mouse sensor & ray sensor)
Diffstat (limited to 'source/gameengine/Ketsji')
36 files changed, 692 insertions, 509 deletions
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; - } else + switch (objprop->m_boundclass) { + case KX_BOUNDBOX: + { - 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->setClientInfo(gameobj); - gameobj->GetSGNode()->AddSGController(physicscontroller); - - bool isActor = objprop->m_isactor; - STR_String materialname; - if (meshobj) - materialname = meshobj->GetMaterialName(0); - - const char* matname = materialname.ReadPtr(); + 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 + ); + + gameobj->SetPhysicsController(physicscontroller); + physicscontroller->setNewClientInfo(gameobj->getClientInfo()); + gameobj->GetSGNode()->AddSGController(physicscontroller); + + bool isActor = objprop->m_isactor; + STR_String materialname; + if (meshobj) + materialname = meshobj->GetMaterialName(0); + + const char* matname = materialname.ReadPtr(); + + + physicscontroller->SetObject(gameobj->GetSGNode()); + break; + } + default: + { + } + }; - physicscontroller->SetObject(gameobj->GetSGNode()); - - } } 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 <config.h> #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<SumoPhysicsEnvironment* > (m_kxscene->GetPhysicsEnvironment()); - SM_Scene *sumoScene = spe->GetSumoScene(); - KX_SumoPhysicsController *spc = dynamic_cast<KX_SumoPhysicsController*> (cam->GetPhysicsController()); - SM_Object *sumoCam = spc?spc->GetSumoObject():NULL; - MT_Vector3 todir = topoint3 - frompoint3; - if (todir.dot(todir) < MT_EPSILON) - return false; - todir.normalize(); - - 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<KX_ClientObjectInfo*>( 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; - } + KX_IPhysicsController* physics_controller = (cam->GetPhysicsController()); + PHY_IPhysicsEnvironment* physics_environment = m_kxscene->GetPhysicsEnvironment(); + +// 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<KX_SumoPhysicsController *> (static_cast<KX_GameObject*> (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<KX_MouseFocusSensor>(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<KX_ClientObjectInfo*>( 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<KX_GameObject*> (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 <config.h> #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<KX_TouchEventManager*>(m_eventmgr)->GetSumoScene()->remove(*m_sumoObj); - delete m_sumoObj; - m_sumoObj = NULL; + static_cast<KX_TouchEventManager*>(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<KX_GameObject*>(GetParent()); /*unused*/ + KX_GameObject* parent = static_cast<KX_GameObject*>(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<KX_TouchEventManager*>(m_eventmgr); /*unused*/ + KX_TouchEventManager* toucheventmgr = static_cast<KX_TouchEventManager*>(m_eventmgr); KX_GameObject* parent = static_cast<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<KX_ClientObjectInfo*> (obj1 == m_sumoObj? - ((SM_Object*)obj2)->getClientObject() : - ((SM_Object*)obj1)->getClientObject()); + KX_ClientObjectInfo* client_info =static_cast<KX_ClientObjectInfo*> (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 <config.h> #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 <config.h> @@ -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<PHY_IPhysicsController*>(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<KX_ClientObjectInfo*>(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<KX_MyClass>(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<MyClass>(this, data) + * and pass to KX_RayCast::RayTest + */ + template<class T> 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 T> 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 <config.h> @@ -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<SumoPhysicsEnvironment *>(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<KX_SumoPhysicsController *>(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<KX_SumoPhysicsController *>(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<KX_ClientObjectInfo*>(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<KX_SumoPhysicsController *> (static_cast<KX_GameObject*> (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; - } - } - - if (bFound) - { - m_rayHit = true; - m_hitObject = hitgameobj; - m_hitPosition = resultpoint; - m_hitNormal = resultnormal; - - } - } - } - else - { - ready = true; - } - } - while (!ready); - + + KX_RayCast::RayTest(physics_controller, physics_environment, frompoint, topoint, resultpoint, resultnormal, KX_RayCast::Callback<KX_RaySensor>(this)); + +// 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<KX_ClientObjectInfo*>(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<SumoPhysicsEnvironment *>(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 <config.h> #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 <config.h> #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) -{ - SM_Object * obj1 = static_cast<SM_Object*>(object1); - SM_Object * obj2 = static_cast<SM_Object*>(object2); - - m_collisions.insert(std::pair<SM_Object*, SM_Object*>(obj1, obj2)); - - return DT_CONTINUE; } -/* -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 = (SM_Object *) object1; - SM_Object * obj2 = (SM_Object *) object2; - for ( vector<SCA_ISensor*>::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); - - } + PHY_IPhysicsController* obj1 = static_cast<PHY_IPhysicsController*>(object1); + PHY_IPhysicsController* obj2 = static_cast<PHY_IPhysicsController*>(object2); - return DT_CONTINUE; + m_newCollisions.insert(std::pair<PHY_IPhysicsController*, PHY_IPhysicsController*>(obj1, obj2)); + + return false; } -*/ -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<KX_TouchSensor*>(*it)->SynchronizeTransform(); - for (std::set<Collision>::iterator cit = m_collisions.begin(); cit != m_collisions.end(); ++cit) + for (std::set<NewCollision>::iterator cit = m_newCollisions.begin(); cit != m_newCollisions.end(); ++cit) { - KX_ClientObjectInfo *client_info = static_cast<KX_ClientObjectInfo *>((*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<KX_ClientObjectInfo *>(ctrl1->getNewClientInfo()); list<SCA_ISensor*>::iterator sit; for ( sit = client_info->m_sensors.begin(); sit != client_info->m_sensors.end(); ++sit) - static_cast<KX_TouchSensor*>(*sit)->HandleCollision((*cit).first, (*cit).second, NULL); + static_cast<KX_TouchSensor*>(*sit)->NewHandleCollision((*cit).first, (*cit).second, NULL); - client_info = static_cast<KX_ClientObjectInfo *>((*cit).second->getClientObject()); + client_info = static_cast<KX_ClientObjectInfo *>((*cit).second->getNewClientInfo()); for ( sit = client_info->m_sensors.begin(); sit != client_info->m_sensors.end(); ++sit) - static_cast<KX_TouchSensor*>(*sit)->HandleCollision((*cit).second, (*cit).first, NULL); + static_cast<KX_TouchSensor*>(*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 <set> class SCA_ISensor; -class SM_Object; +class PHY_IPhysicsEnvironment; class KX_TouchEventManager : public SCA_EventManager { - typedef std::pair<SM_Object*, SM_Object*> Collision; + typedef std::pair<PHY_IPhysicsController*, PHY_IPhysicsController*> NewCollision; class SCA_LogicManager* m_logicmgr; - SM_Scene *m_scene; + PHY_IPhysicsEnvironment* m_physEnv; - std::set<Collision> m_collisions; + std::set<NewCollision> m_newCollisions; - - 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); + 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); + + + + 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 <iostream> +#include "PHY_IPhysicsEnvironment.h" #ifdef HAVE_CONFIG_H #include <config.h> @@ -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<KX_SumoPhysicsController *>(gameobj->GetPhysicsController()); - if (sphy) - m_sumoObj = sphy->GetSumoObject(); - + m_physCtrl = dynamic_cast<PHY_IPhysicsController*>(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<KX_GameObject *>(parent); - KX_SumoPhysicsController *sphy = dynamic_cast<KX_SumoPhysicsController *>(((KX_GameObject*)parent)->GetPhysicsController()); + PHY_IPhysicsController *sphy = dynamic_cast<PHY_IPhysicsController*>(((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<KX_ClientObjectInfo*> (obj1 == m_sumoObj? - ((SM_Object*)obj2)->getClientObject() : - ((SM_Object*)obj1)->getClientObject()); + KX_ClientObjectInfo* client_info = static_cast<KX_ClientObjectInfo*> (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<KX_SumoPhysicsController*>(gameob->GetPhysicsController()); - SM_Object* smob = spc?spc->GetSumoObject():NULL; + PHY_IPhysicsController* spc = dynamic_cast<PHY_IPhysicsController*>(gameob->GetPhysicsController()); - if (smob) { - KX_ClientObjectInfo* cl_inf = static_cast<KX_ClientObjectInfo*>(smob->getClientObject()); + if (spc) { + KX_ClientObjectInfo* cl_inf = static_cast<KX_ClientObjectInfo*>(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 <SOLID/SOLID.h> -#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); - SM_Object* GetSumoObject() { return m_sumoObj; }; + virtual bool NewHandleCollision(void*obj1,void*obj2,const PHY_CollData* colldata); + 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', |