diff options
Diffstat (limited to 'source/gameengine/Ketsji')
21 files changed, 216 insertions, 92 deletions
diff --git a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp index 300a7906e81..e22edfd1306 100644 --- a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp +++ b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp @@ -17,8 +17,8 @@ #include "BulletSoftBody/btSoftBody.h" -KX_BulletPhysicsController::KX_BulletPhysicsController (const CcdConstructionInfo& ci, bool dyna, bool compound) -: KX_IPhysicsController(dyna,compound,(PHY_IPhysicsController*)this), +KX_BulletPhysicsController::KX_BulletPhysicsController (const CcdConstructionInfo& ci, bool dyna, bool sensor, bool compound) +: KX_IPhysicsController(dyna,sensor,compound,(PHY_IPhysicsController*)this), CcdPhysicsController(ci), m_savedCollisionFlags(0), m_savedCollisionFilterGroup(0), @@ -174,6 +174,20 @@ void KX_BulletPhysicsController::setScaling(const MT_Vector3& scaling) { CcdPhysicsController::setScaling(scaling.x(),scaling.y(),scaling.z()); } +void KX_BulletPhysicsController::SetTransform() +{ + btVector3 pos; + btVector3 scale; + float ori[12]; + m_MotionState->getWorldPosition(pos.m_floats[0],pos.m_floats[1],pos.m_floats[2]); + m_MotionState->getWorldScaling(scale.m_floats[0],scale.m_floats[1],scale.m_floats[2]); + m_MotionState->getWorldOrientation(ori); + btMatrix3x3 rot(ori[0], ori[4], ori[8], + ori[1], ori[5], ori[9], + ori[2], ori[6], ori[10]); + CcdPhysicsController::forceWorldTransform(rot, pos); +} + MT_Scalar KX_BulletPhysicsController::GetMass() { if (GetSoftBody()) @@ -262,7 +276,7 @@ void KX_BulletPhysicsController::AddCompoundChild(KX_IPhysicsController* chil // add to parent compound shapeinfo GetShapeInfo()->AddShape(proxyShapeInfo); // create new bullet collision shape from the object shapeinfo and set scaling - btCollisionShape* newChildShape = proxyShapeInfo->CreateBulletShape(); + btCollisionShape* newChildShape = proxyShapeInfo->CreateBulletShape(childCtrl->GetMargin()); newChildShape->setLocalScaling(relativeScale); // add bullet collision shape to parent compound collision shape compoundShape->addChildShape(proxyShapeInfo->m_childTrans,newChildShape); @@ -359,7 +373,7 @@ void KX_BulletPhysicsController::SetMass(MT_Scalar newmass) void KX_BulletPhysicsController::SuspendDynamics(bool ghost) { btRigidBody *body = GetRigidBody(); - if (body && !m_suspended) + if (body && !m_suspended && !IsSensor()) { btBroadphaseProxy* handle = body->getBroadphaseHandle(); m_savedCollisionFlags = body->getCollisionFlags(); @@ -445,7 +459,7 @@ SG_Controller* KX_BulletPhysicsController::GetReplica(class SG_Node* destnode) void KX_BulletPhysicsController::SetSumoTransform(bool nondynaonly) { - if (!m_bDyna) + if (!m_bDyna && !m_bSensor) { btCollisionObject* object = GetRigidBody(); object->setActivationState(ACTIVE_TAG); diff --git a/source/gameengine/Ketsji/KX_BulletPhysicsController.h b/source/gameengine/Ketsji/KX_BulletPhysicsController.h index 9d2afad1a5c..755b1cbd780 100644 --- a/source/gameengine/Ketsji/KX_BulletPhysicsController.h +++ b/source/gameengine/Ketsji/KX_BulletPhysicsController.h @@ -19,7 +19,7 @@ private: public: - KX_BulletPhysicsController (const CcdConstructionInfo& ci, bool dyna, bool compound); + KX_BulletPhysicsController (const CcdConstructionInfo& ci, bool dyna, bool sensor, bool compound); virtual ~KX_BulletPhysicsController (); /////////////////////////////////// @@ -42,6 +42,7 @@ public: virtual void setOrientation(const MT_Matrix3x3& orn); virtual void setPosition(const MT_Point3& pos); virtual void setScaling(const MT_Vector3& scaling); + virtual void SetTransform(); virtual MT_Scalar GetMass(); virtual void SetMass(MT_Scalar newmass); virtual MT_Vector3 GetLocalInertia(); diff --git a/source/gameengine/Ketsji/KX_ClientObjectInfo.h b/source/gameengine/Ketsji/KX_ClientObjectInfo.h index 7345edb054b..74d463fbf20 100644 --- a/source/gameengine/Ketsji/KX_ClientObjectInfo.h +++ b/source/gameengine/Ketsji/KX_ClientObjectInfo.h @@ -50,8 +50,8 @@ struct KX_ClientObjectInfo STATIC, ACTOR, RESERVED1, - RADAR, - NEAR + SENSOR, + OBSENSOR } m_type; KX_GameObject* m_gameobject; void* m_auxilary_info; @@ -84,6 +84,7 @@ public: } bool isActor() { return m_type <= ACTOR; } + bool isSensor() { return m_type >= SENSOR && m_type <= OBSENSOR; } }; #endif //__KX_CLIENTOBJECT_INFO_H diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h b/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h index 5b912a123fe..e48fddb30bd 100644 --- a/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h +++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h @@ -83,6 +83,7 @@ struct KX_ObjectProperties bool m_ghost; class KX_GameObject* m_dynamic_parent; bool m_isactor; + bool m_sensor; bool m_concave; bool m_isdeformable; bool m_disableSleeping; diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp index f18ffb56ccb..73693e68642 100644 --- a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp +++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp @@ -808,12 +808,12 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj, bool isbulletdyna = false; + bool isbulletsensor = false; CcdConstructionInfo ci; class PHY_IMotionState* motionstate = new KX_MotionState(gameobj->GetSGNode()); class CcdShapeConstructionInfo *shapeInfo = new CcdShapeConstructionInfo(); - if (!objprop->m_dyna) { ci.m_collisionFlags |= btCollisionObject::CF_STATIC_OBJECT; @@ -832,6 +832,7 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj, ci.m_margin = objprop->m_margin; shapeInfo->m_radius = objprop->m_radius; isbulletdyna = objprop->m_dyna; + isbulletsensor = objprop->m_sensor; ci.m_localInertiaTensor = btVector3(ci.m_mass/3.f,ci.m_mass/3.f,ci.m_mass/3.f); @@ -851,7 +852,7 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj, //bm = new MultiSphereShape(inertiaHalfExtents,,&trans.getOrigin(),&radius,1); shapeInfo->m_shapeType = PHY_SHAPE_SPHERE; - bm = shapeInfo->CreateBulletShape(); + bm = shapeInfo->CreateBulletShape(ci.m_margin); break; }; case KX_BOUNDBOX: @@ -864,7 +865,7 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj, shapeInfo->m_halfExtend /= 2.0; shapeInfo->m_halfExtend = shapeInfo->m_halfExtend.absolute(); shapeInfo->m_shapeType = PHY_SHAPE_BOX; - bm = shapeInfo->CreateBulletShape(); + bm = shapeInfo->CreateBulletShape(ci.m_margin); break; }; case KX_BOUNDCYLINDER: @@ -875,7 +876,7 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj, objprop->m_boundobject.c.m_height * 0.5f ); shapeInfo->m_shapeType = PHY_SHAPE_CYLINDER; - bm = shapeInfo->CreateBulletShape(); + bm = shapeInfo->CreateBulletShape(ci.m_margin); break; } @@ -884,18 +885,18 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj, shapeInfo->m_radius = objprop->m_boundobject.c.m_radius; shapeInfo->m_height = objprop->m_boundobject.c.m_height; shapeInfo->m_shapeType = PHY_SHAPE_CONE; - bm = shapeInfo->CreateBulletShape(); + bm = shapeInfo->CreateBulletShape(ci.m_margin); break; } case KX_BOUNDPOLYTOPE: { shapeInfo->SetMesh(meshobj, dm,true,false); - bm = shapeInfo->CreateBulletShape(); + bm = shapeInfo->CreateBulletShape(ci.m_margin); break; } case KX_BOUNDMESH: { - bool useGimpact = (ci.m_mass && !objprop->m_softbody); + bool useGimpact = ((ci.m_mass || isbulletsensor) && !objprop->m_softbody); // mesh shapes can be shared, check first if we already have a shape on that mesh class CcdShapeConstructionInfo *sharedShapeInfo = CcdShapeConstructionInfo::FindMesh(meshobj, dm, false,useGimpact); @@ -915,7 +916,7 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj, shapeInfo->setVertexWeldingThreshold1(objprop->m_soft_welding); //todo: expose this to the UI } - bm = shapeInfo->CreateBulletShape(); + bm = shapeInfo->CreateBulletShape(ci.m_margin); //should we compute inertia for dynamic shape? //bm->calculateLocalInertia(ci.m_mass,ci.m_localInertiaTensor); @@ -933,7 +934,7 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj, return; } - bm->setMargin(ci.m_margin); + //bm->setMargin(ci.m_margin); if (objprop->m_isCompoundChild) @@ -1103,26 +1104,39 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj, ci.m_soft_numclusteriterations= objprop->m_soft_numclusteriterations; /* number of iterations to refine collision clusters*/ //////////////////// - - ci.m_collisionFilterGroup = (isbulletdyna) ? short(CcdConstructionInfo::DefaultFilter) : short(CcdConstructionInfo::StaticFilter); - ci.m_collisionFilterMask = (isbulletdyna) ? short(CcdConstructionInfo::AllFilter) : short(CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::StaticFilter); + ci.m_collisionFilterGroup = + (isbulletsensor) ? short(CcdConstructionInfo::SensorFilter) : + (isbulletdyna) ? short(CcdConstructionInfo::DefaultFilter) : + short(CcdConstructionInfo::StaticFilter); + ci.m_collisionFilterMask = + (isbulletsensor) ? short(CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::SensorFilter) : + (isbulletdyna) ? short(CcdConstructionInfo::AllFilter) : + short(CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::StaticFilter); ci.m_bRigid = objprop->m_dyna && objprop->m_angular_rigidbody; ci.m_bSoft = objprop->m_softbody; + ci.m_bSensor = isbulletsensor; MT_Vector3 scaling = gameobj->NodeGetWorldScaling(); ci.m_scaling.setValue(scaling[0], scaling[1], scaling[2]); - KX_BulletPhysicsController* physicscontroller = new KX_BulletPhysicsController(ci,isbulletdyna,objprop->m_hasCompoundChildren); + KX_BulletPhysicsController* physicscontroller = new KX_BulletPhysicsController(ci,isbulletdyna,isbulletsensor,objprop->m_hasCompoundChildren); // shapeInfo is reference counted, decrement now as we don't use it anymore if (shapeInfo) shapeInfo->Release(); - if (objprop->m_in_active_layer) + gameobj->SetPhysicsController(physicscontroller,isbulletdyna); + if (isbulletsensor) + { + // use a different callback function for sensor object, + // bullet will not synchronize, we must do it explicitely + SG_Callbacks& callbacks = gameobj->GetSGNode()->GetCallBackFunctions(); + callbacks.m_updatefunc = KX_GameObject::SynchronizeTransformFunc; + // make sensor object invisible by default + gameobj->SetVisible(false, false); + } + // don't add automatically sensor object, they are added when a collision sensor is registered + else if (objprop->m_in_active_layer) { env->addCcdPhysicsController( physicscontroller); } - - - - gameobj->SetPhysicsController(physicscontroller,isbulletdyna); physicscontroller->setNewClientInfo(gameobj->getClientInfo()); { btRigidBody* rbody = physicscontroller->GetRigidBody(); @@ -1181,7 +1195,9 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj, } bool isActor = objprop->m_isactor; - gameobj->getClientInfo()->m_type = (isActor ? KX_ClientObjectInfo::ACTOR : KX_ClientObjectInfo::STATIC); + gameobj->getClientInfo()->m_type = + (isbulletsensor) ? KX_ClientObjectInfo::OBSENSOR : + (isActor) ? KX_ClientObjectInfo::ACTOR : KX_ClientObjectInfo::STATIC; // store materialname in auxinfo, needed for touchsensors if (meshobj) { diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 79519bfb491..1d7bf56f6d3 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -332,7 +332,7 @@ void KX_GameObject::ProcessReplica() } -static void setGraphicController_recursive(SG_Node* node, bool v) +static void setGraphicController_recursive(SG_Node* node) { NodeList& children = node->GetSGChildren(); @@ -341,24 +341,24 @@ static void setGraphicController_recursive(SG_Node* node, bool v) SG_Node* childnode = (*childit); KX_GameObject *clientgameobj = static_cast<KX_GameObject*>( (*childit)->GetSGClientObject()); if (clientgameobj != NULL) // This is a GameObject - clientgameobj->ActivateGraphicController(v, false); + clientgameobj->ActivateGraphicController(false); // if the childobj is NULL then this may be an inverse parent link // so a non recursive search should still look down this node. - setGraphicController_recursive(childnode, v); + setGraphicController_recursive(childnode); } } -void KX_GameObject::ActivateGraphicController(bool active, bool recurse) +void KX_GameObject::ActivateGraphicController(bool recurse) { if (m_pGraphicController) { - m_pGraphicController->Activate(active); + m_pGraphicController->Activate(m_bVisible); } if (recurse) { - setGraphicController_recursive(GetSGNode(), active); + setGraphicController_recursive(GetSGNode()); } } @@ -538,6 +538,20 @@ void KX_GameObject::UpdateTransformFunc(SG_IObject* node, void* gameobj, void* s ((KX_GameObject*)gameobj)->UpdateTransform(); } +void KX_GameObject::SynchronizeTransform() +{ + // only used for sensor object, do full synchronization as bullet doesn't do it + if (m_pPhysicsController1) + m_pPhysicsController1->SetTransform(); + if (m_pGraphicController) + m_pGraphicController->SetGraphicTransform(); +} + +void KX_GameObject::SynchronizeTransformFunc(SG_IObject* node, void* gameobj, void* scene) +{ + ((KX_GameObject*)gameobj)->SynchronizeTransform(); +} + void KX_GameObject::SetDebugColor(unsigned int bgra) { diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index e5b26539d4d..e0e78918dde 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -384,7 +384,7 @@ public: /* * @add/remove the graphic controller to the physic system */ - void ActivateGraphicController(bool active, bool recurse); + void ActivateGraphicController(bool recurse); /** * @section Coordinate system manipulation functions @@ -560,6 +560,13 @@ public: static void UpdateTransformFunc(SG_IObject* node, void* gameobj, void* scene); /** + * only used for sensor objects + */ + void SynchronizeTransform(); + + static void SynchronizeTransformFunc(SG_IObject* node, void* gameobj, void* scene); + + /** * Function to set IPO option at start of IPO */ void diff --git a/source/gameengine/Ketsji/KX_IPhysicsController.cpp b/source/gameengine/Ketsji/KX_IPhysicsController.cpp index a38222c5f7e..673acabd774 100644 --- a/source/gameengine/Ketsji/KX_IPhysicsController.cpp +++ b/source/gameengine/Ketsji/KX_IPhysicsController.cpp @@ -35,9 +35,10 @@ #include "PHY_DynamicTypes.h" -KX_IPhysicsController::KX_IPhysicsController(bool dyna, bool compound, void* userdata) +KX_IPhysicsController::KX_IPhysicsController(bool dyna, bool sensor, bool compound, void* userdata) : m_bDyna(dyna), + m_bSensor(sensor), m_bCompound(compound), m_suspendDynamics(false), m_userdata(userdata) diff --git a/source/gameengine/Ketsji/KX_IPhysicsController.h b/source/gameengine/Ketsji/KX_IPhysicsController.h index 10b66da7b76..81c01045071 100644 --- a/source/gameengine/Ketsji/KX_IPhysicsController.h +++ b/source/gameengine/Ketsji/KX_IPhysicsController.h @@ -49,11 +49,12 @@ class KX_IPhysicsController : public SG_Controller { protected: bool m_bDyna; + bool m_bSensor; bool m_bCompound; bool m_suspendDynamics; void* m_userdata; public: - KX_IPhysicsController(bool dyna,bool compound, void* userdata); + KX_IPhysicsController(bool dyna,bool sensor,bool compound, void* userdata); virtual ~KX_IPhysicsController(); @@ -74,6 +75,7 @@ public: virtual void getOrientation(MT_Quaternion& orn)=0; virtual void setOrientation(const MT_Matrix3x3& orn)=0; + virtual void SetTransform()=0; //virtual void setOrientation(const MT_Quaternion& orn)=0; virtual void setPosition(const MT_Point3& pos)=0; virtual void setScaling(const MT_Vector3& scaling)=0; @@ -100,10 +102,18 @@ public: m_bDyna = isDynamic; } + void SetSensor(bool isSensor) { + m_bSensor = isSensor; + } + bool IsDyna(void) { return m_bDyna; } + bool IsSensor(void) { + return m_bSensor; + } + bool IsCompound(void) { return m_bCompound; } diff --git a/source/gameengine/Ketsji/KX_MotionState.cpp b/source/gameengine/Ketsji/KX_MotionState.cpp index b4d58dccfdf..60455d33312 100644 --- a/source/gameengine/Ketsji/KX_MotionState.cpp +++ b/source/gameengine/Ketsji/KX_MotionState.cpp @@ -73,6 +73,11 @@ void KX_MotionState::getWorldOrientation(float* ori) mat.getValue(ori); } +void KX_MotionState::setWorldOrientation(const float* ori) +{ + m_node->SetLocalOrientation(ori); +} + void KX_MotionState::setWorldPosition(float posX,float posY,float posZ) { m_node->SetLocalPosition(MT_Point3(posX,posY,posZ)); diff --git a/source/gameengine/Ketsji/KX_MotionState.h b/source/gameengine/Ketsji/KX_MotionState.h index 7ba3ca2f85c..0e43e88fbeb 100644 --- a/source/gameengine/Ketsji/KX_MotionState.h +++ b/source/gameengine/Ketsji/KX_MotionState.h @@ -45,6 +45,7 @@ public: virtual void setWorldPosition(float posX,float posY,float posZ); virtual void setWorldOrientation(float quatIma0,float quatIma1,float quatIma2,float quatReal); virtual void getWorldOrientation(float* ori); + virtual void setWorldOrientation(const float* ori); virtual void calculateWorldTransformations(); }; diff --git a/source/gameengine/Ketsji/KX_NearSensor.cpp b/source/gameengine/Ketsji/KX_NearSensor.cpp index a3c4e95ae24..44842b7f5b3 100644 --- a/source/gameengine/Ketsji/KX_NearSensor.cpp +++ b/source/gameengine/Ketsji/KX_NearSensor.cpp @@ -36,6 +36,7 @@ #include "KX_Scene.h" // needed to create a replica #include "PHY_IPhysicsEnvironment.h" #include "PHY_IPhysicsController.h" +#include "PHY_IMotionState.h" #ifdef HAVE_CONFIG_H #include <config.h> @@ -62,7 +63,7 @@ KX_NearSensor::KX_NearSensor(SCA_EventManager* eventmgr, { gameobj->getClientInfo()->m_sensors.remove(this); - m_client_info = new KX_ClientObjectInfo(gameobj, KX_ClientObjectInfo::NEAR); + m_client_info = new KX_ClientObjectInfo(gameobj, KX_ClientObjectInfo::SENSOR); m_client_info->m_sensors.push_back(this); //DT_ShapeHandle shape = (DT_ShapeHandle) vshape; @@ -81,28 +82,14 @@ void KX_NearSensor::SynchronizeTransform() // not linked to the parent object, must synchronize it. if (m_physCtrl) { + PHY_IMotionState* motionState = m_physCtrl->GetMotionState(); KX_GameObject* parent = ((KX_GameObject*)GetParent()); - MT_Vector3 pos = parent->NodeGetWorldPosition(); - MT_Quaternion orn = parent->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(); - } -} - -void KX_NearSensor::RegisterSumo(KX_TouchEventManager *touchman) -{ - if (m_physCtrl) - { - touchman->GetPhysicsEnvironment()->addSensor(m_physCtrl); - } -} - -void KX_NearSensor::UnregisterSumo(KX_TouchEventManager* touchman) -{ - if (m_physCtrl) - { - touchman->GetPhysicsEnvironment()->removeSensor(m_physCtrl); + const MT_Point3& pos = parent->NodeGetWorldPosition(); + float ori[12]; + parent->NodeGetWorldOrientation().getValue(ori); + motionState->setWorldPosition(pos[0], pos[1], pos[2]); + motionState->setWorldOrientation(ori); + m_physCtrl->WriteMotionStateToDynamics(true); } } @@ -117,7 +104,7 @@ void KX_NearSensor::ProcessReplica() { KX_TouchSensor::ProcessReplica(); - m_client_info = new KX_ClientObjectInfo(m_client_info->m_gameobject, KX_ClientObjectInfo::NEAR); + m_client_info = new KX_ClientObjectInfo(m_client_info->m_gameobject, KX_ClientObjectInfo::SENSOR); if (m_physCtrl) { @@ -134,11 +121,11 @@ void KX_NearSensor::ProcessReplica() void KX_NearSensor::ReParent(SCA_IObject* parent) { + SCA_ISensor::ReParent(parent); m_client_info->m_gameobject = static_cast<KX_GameObject*>(parent); m_client_info->m_sensors.push_back(this); //Synchronize here with the actual parent. SynchronizeTransform(); - SCA_ISensor::ReParent(parent); } diff --git a/source/gameengine/Ketsji/KX_NearSensor.h b/source/gameengine/Ketsji/KX_NearSensor.h index 35136b79d13..d98b464a443 100644 --- a/source/gameengine/Ketsji/KX_NearSensor.h +++ b/source/gameengine/Ketsji/KX_NearSensor.h @@ -77,8 +77,8 @@ public: virtual bool NewHandleCollision(void* obj1,void* obj2, const PHY_CollData * coll_data); virtual bool BroadPhaseFilterCollision(void*obj1,void*obj2); - virtual void RegisterSumo(KX_TouchEventManager *touchman); - virtual void UnregisterSumo(KX_TouchEventManager* touchman); + virtual bool BroadPhaseSensorFilterCollision(void*obj1,void*obj2) { return false; }; + virtual sensortype GetSensorType() { return NEAR; } /* --------------------------------------------------------------------- */ /* Python interface ---------------------------------------------------- */ diff --git a/source/gameengine/Ketsji/KX_OdePhysicsController.h b/source/gameengine/Ketsji/KX_OdePhysicsController.h index 21b7e632d83..8c3974c38a3 100644 --- a/source/gameengine/Ketsji/KX_OdePhysicsController.h +++ b/source/gameengine/Ketsji/KX_OdePhysicsController.h @@ -70,6 +70,7 @@ public: virtual void setOrientation(const MT_Matrix3x3& orn); virtual void setPosition(const MT_Point3& pos); virtual void setScaling(const MT_Vector3& scaling); + virtual void SetTransform() {} virtual MT_Scalar GetMass(); virtual MT_Vector3 getReactionForce(); virtual void setRigidBody(bool rigid); diff --git a/source/gameengine/Ketsji/KX_RadarSensor.cpp b/source/gameengine/Ketsji/KX_RadarSensor.cpp index 4532224a81e..064dc9126ac 100644 --- a/source/gameengine/Ketsji/KX_RadarSensor.cpp +++ b/source/gameengine/Ketsji/KX_RadarSensor.cpp @@ -30,6 +30,7 @@ #include "KX_GameObject.h" #include "KX_PyMath.h" #include "PHY_IPhysicsController.h" +#include "PHY_IMotionState.h" #ifdef HAVE_CONFIG_H #include <config.h> @@ -66,7 +67,7 @@ KX_RadarSensor::KX_RadarSensor(SCA_EventManager* eventmgr, m_coneheight(coneheight), m_axis(axis) { - m_client_info->m_type = KX_ClientObjectInfo::RADAR; + m_client_info->m_type = KX_ClientObjectInfo::SENSOR; //m_client_info->m_clientobject = gameobj; //m_client_info->m_auxilary_info = NULL; //sumoObj->setClientObject(&m_client_info); @@ -84,12 +85,6 @@ CValue* KX_RadarSensor::GetReplica() return replica; } -void KX_RadarSensor::ProcessReplica() -{ - KX_NearSensor::ProcessReplica(); - m_client_info->m_type = KX_ClientObjectInfo::RADAR; -} - /** * Transforms the collision object. A cone is not correctly centered * for usage. */ @@ -169,11 +164,13 @@ void KX_RadarSensor::SynchronizeTransform() if (m_physCtrl) { - MT_Quaternion orn = trans.getRotation(); - MT_Point3 pos = trans.getOrigin(); - m_physCtrl->setPosition(pos[0],pos[1],pos[2]); - m_physCtrl->setOrientation(orn[0],orn[1],orn[2],orn[3]); - m_physCtrl->calcXform(); + PHY_IMotionState* motionState = m_physCtrl->GetMotionState(); + const MT_Point3& pos = trans.getOrigin(); + float ori[12]; + trans.getBasis().getValue(ori); + motionState->setWorldPosition(pos[0], pos[1], pos[2]); + motionState->setWorldOrientation(ori); + m_physCtrl->WriteMotionStateToDynamics(true); } } diff --git a/source/gameengine/Ketsji/KX_RadarSensor.h b/source/gameengine/Ketsji/KX_RadarSensor.h index b4268797f85..6779a9edffe 100644 --- a/source/gameengine/Ketsji/KX_RadarSensor.h +++ b/source/gameengine/Ketsji/KX_RadarSensor.h @@ -76,7 +76,6 @@ public: virtual ~KX_RadarSensor(); virtual void SynchronizeTransform(); virtual CValue* GetReplica(); - virtual void ProcessReplica(); /* --------------------------------------------------------------------- */ /* Python interface ---------------------------------------------------- */ @@ -93,6 +92,7 @@ public: virtual PyObject* py_getattro(PyObject *attr); virtual PyObject* py_getattro_dict(); virtual int py_setattro(PyObject *attr, PyObject* value); + virtual sensortype GetSensorType() { return RADAR; } //Deprecated -----> KX_PYMETHOD_DOC_NOARGS(KX_RadarSensor,GetConeOrigin); diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index 9502599603c..bb5e0875402 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -737,7 +737,7 @@ void KX_Scene::DupliGroupRecurse(CValue* obj, int level) replica->GetSGNode()->SetBBox(gameobj->GetSGNode()->BBox()); replica->GetSGNode()->SetRadius(gameobj->GetSGNode()->Radius()); // we can now add the graphic controller to the physic engine - replica->ActivateGraphicController(true,true); + replica->ActivateGraphicController(true); // done with replica replica->Release(); @@ -850,7 +850,7 @@ SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject, replica->GetSGNode()->SetBBox(originalobj->GetSGNode()->BBox()); replica->GetSGNode()->SetRadius(originalobj->GetSGNode()->Radius()); // the size is correct, we can add the graphic controller to the physic engine - replica->ActivateGraphicController(true,true); + replica->ActivateGraphicController(true); // now replicate logic vector<KX_GameObject*>::iterator git; diff --git a/source/gameengine/Ketsji/KX_SumoPhysicsController.h b/source/gameengine/Ketsji/KX_SumoPhysicsController.h index 083d89896f6..278994c6ae7 100644 --- a/source/gameengine/Ketsji/KX_SumoPhysicsController.h +++ b/source/gameengine/Ketsji/KX_SumoPhysicsController.h @@ -53,7 +53,7 @@ public: class SM_Object* sumoObj, class PHY_IMotionState* motionstate ,bool dyna) - : KX_IPhysicsController(dyna,false,NULL) , + : KX_IPhysicsController(dyna,false,false,NULL) , SumoPhysicsController(sumoScene,/*solidscene,*/sumoObj,motionstate,dyna) { }; @@ -83,6 +83,7 @@ public: virtual void getOrientation(MT_Quaternion& orn); virtual void setOrientation(const MT_Matrix3x3& orn); + virtual void SetTransform() {} virtual void setPosition(const MT_Point3& pos); virtual void setScaling(const MT_Vector3& scaling); diff --git a/source/gameengine/Ketsji/KX_TouchEventManager.cpp b/source/gameengine/Ketsji/KX_TouchEventManager.cpp index 8ae5fae8fa3..46927541099 100644 --- a/source/gameengine/Ketsji/KX_TouchEventManager.cpp +++ b/source/gameengine/Ketsji/KX_TouchEventManager.cpp @@ -85,14 +85,34 @@ bool KX_TouchEventManager::newBroadphaseResponse(void *client_data, PHY_IPhysicsController* ctrl = static_cast<PHY_IPhysicsController*>(object1); KX_ClientObjectInfo* info = (ctrl) ? static_cast<KX_ClientObjectInfo*>(ctrl->getNewClientInfo()) : NULL; // This call back should only be called for controllers of Near and Radar sensor - if (info && - info->m_sensors.size() == 1 && - (info->m_type == KX_ClientObjectInfo::NEAR || - info->m_type == KX_ClientObjectInfo::RADAR)) + if (!info) + return true; + + switch (info->m_type) { - // only one sensor for this type of object - KX_TouchSensor* touchsensor = static_cast<KX_TouchSensor*>(*info->m_sensors.begin()); - return touchsensor->BroadPhaseFilterCollision(object1,object2); + case KX_ClientObjectInfo::SENSOR: + if (info->m_sensors.size() == 1) + { + // only one sensor for this type of object + KX_TouchSensor* touchsensor = static_cast<KX_TouchSensor*>(*info->m_sensors.begin()); + return touchsensor->BroadPhaseFilterCollision(object1,object2); + } + break; + case KX_ClientObjectInfo::OBSENSOR: + // this object may have multiple collision sensors, + // check is any of them is interested in this object + for(std::list<SCA_ISensor*>::iterator it = info->m_sensors.begin(); + it != info->m_sensors.end(); + ++it) + { + if ((*it)->GetSensorType() == SCA_ISensor::TOUCH) + { + KX_TouchSensor* touchsensor = static_cast<KX_TouchSensor*>(*it); + if (touchsensor->BroadPhaseSensorFilterCollision(object1, object2)) + return true; + } + } + return false; } return true; } diff --git a/source/gameengine/Ketsji/KX_TouchSensor.cpp b/source/gameengine/Ketsji/KX_TouchSensor.cpp index 8c0d5596939..509fc60e9f5 100644 --- a/source/gameengine/Ketsji/KX_TouchSensor.cpp +++ b/source/gameengine/Ketsji/KX_TouchSensor.cpp @@ -173,19 +173,65 @@ void KX_TouchSensor::RegisterSumo(KX_TouchEventManager *touchman) { if (m_physCtrl) { - touchman->GetPhysicsEnvironment()->requestCollisionCallback(m_physCtrl); - // collision - // Deprecated - + if (touchman->GetPhysicsEnvironment()->requestCollisionCallback(m_physCtrl)) + { + KX_ClientObjectInfo* client_info = static_cast<KX_ClientObjectInfo*>(m_physCtrl->getNewClientInfo()); + if (client_info->isSensor()) + touchman->GetPhysicsEnvironment()->addSensor(m_physCtrl); + } } } - void KX_TouchSensor::UnregisterSumo(KX_TouchEventManager* touchman) { if (m_physCtrl) { - touchman->GetPhysicsEnvironment()->removeCollisionCallback(m_physCtrl); + if (touchman->GetPhysicsEnvironment()->removeCollisionCallback(m_physCtrl)) + { + // no more sensor on the controller, can remove it if it is a sensor object + KX_ClientObjectInfo* client_info = static_cast<KX_ClientObjectInfo*>(m_physCtrl->getNewClientInfo()); + if (client_info->isSensor()) + touchman->GetPhysicsEnvironment()->removeSensor(m_physCtrl); + } + } +} + +// this function is called only for sensor objects +// return true if the controller can collide with the object +bool KX_TouchSensor::BroadPhaseSensorFilterCollision(void*obj1,void*obj2) +{ + assert(obj1==m_physCtrl && obj2); + + KX_GameObject* myobj = (KX_GameObject*)GetParent(); + KX_GameObject* myparent = myobj->GetParent(); + KX_ClientObjectInfo* client_info = static_cast<KX_ClientObjectInfo*>(((PHY_IPhysicsController*)obj2)->getNewClientInfo()); + KX_GameObject* otherobj = ( client_info ? client_info->m_gameobject : NULL); + + // first, decrement refcount as GetParent() increases it + if (myparent) + myparent->Release(); + + // we can only check on persistent characteristic: m_link and m_suspended are not + // good candidate because they are transient. That must be handled at another level + if (!otherobj || + otherobj == myparent || // don't interact with our parent + client_info->m_type != KX_ClientObjectInfo::ACTOR) // only with actor objects + return false; + + bool found = m_touchedpropname.IsEmpty(); + if (!found) + { + if (m_bFindMaterial) + { + if (client_info->m_auxilary_info) + { + found = (!strcmp(m_touchedpropname.Ptr(), (char*)client_info->m_auxilary_info)); + } + } else + { + found = (otherobj->GetProperty(m_touchedpropname) != NULL); + } } + return found; } bool KX_TouchSensor::NewHandleCollision(void*object1,void*object2,const PHY_CollData* colldata) diff --git a/source/gameengine/Ketsji/KX_TouchSensor.h b/source/gameengine/Ketsji/KX_TouchSensor.h index 9c9c6bf5816..b62ec6eaf4d 100644 --- a/source/gameengine/Ketsji/KX_TouchSensor.h +++ b/source/gameengine/Ketsji/KX_TouchSensor.h @@ -103,7 +103,8 @@ public: // obj1 = sensor physical controller, obj2 = physical controller of second object // return value = true if collision should be checked on pair of object virtual bool BroadPhaseFilterCollision(void*obj1,void*obj2) { return true; } - + virtual bool BroadPhaseSensorFilterCollision(void*obj1,void*obj2); + virtual sensortype GetSensorType() { return TOUCH; } virtual bool IsPositiveTrigger() { |