diff options
Diffstat (limited to 'source/gameengine/Ketsji/KX_RaySensor.cpp')
-rw-r--r-- | source/gameengine/Ketsji/KX_RaySensor.cpp | 96 |
1 files changed, 65 insertions, 31 deletions
diff --git a/source/gameengine/Ketsji/KX_RaySensor.cpp b/source/gameengine/Ketsji/KX_RaySensor.cpp index 4ccb02d34ec..e24fb773eac 100644 --- a/source/gameengine/Ketsji/KX_RaySensor.cpp +++ b/source/gameengine/Ketsji/KX_RaySensor.cpp @@ -51,6 +51,7 @@ KX_RaySensor::KX_RaySensor(class SCA_EventManager* eventmgr, SCA_IObject* gameobj, const STR_String& propname, bool bFindMaterial, + bool bXRay, double distance, int axis, KX_Scene* ketsjiScene, @@ -58,19 +59,23 @@ KX_RaySensor::KX_RaySensor(class SCA_EventManager* eventmgr, : SCA_ISensor(gameobj,eventmgr, T), m_propertyname(propname), m_bFindMaterial(bFindMaterial), + m_bXRay(bXRay), m_distance(distance), m_scene(ketsjiScene), - m_bTriggered(false), - m_axis(axis), - m_rayHit(false), - m_hitObject(NULL) + m_axis(axis) { - + Init(); } - +void KX_RaySensor::Init() +{ + m_bTriggered = (m_invert)?true:false; + m_rayHit = false; + m_hitObject = NULL; + m_reset = true; +} KX_RaySensor::~KX_RaySensor() { @@ -81,9 +86,10 @@ KX_RaySensor::~KX_RaySensor() CValue* KX_RaySensor::GetReplica() { - CValue* replica = new KX_RaySensor(*this); + KX_RaySensor* replica = new KX_RaySensor(*this); // this will copy properties and so on... CValue::AddDataToReplica(replica); + replica->Init(); return replica; } @@ -100,16 +106,10 @@ bool KX_RaySensor::IsPositiveTrigger() return result; } -bool KX_RaySensor::RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_Vector3& hit_normal, void * const data) +bool KX_RaySensor::RayHit(KX_ClientObjectInfo* client, KX_RayCast* result, void * const data) { KX_GameObject* hitKXObj = client->m_gameobject; - - if (client->m_type > KX_ClientObjectInfo::ACTOR) - { - // false hit - return false; - } bool bFound = false; if (m_propertyname.Length() == 0) @@ -135,20 +135,48 @@ bool KX_RaySensor::RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_ { m_rayHit = true; m_hitObject = hitKXObj; - m_hitPosition = hit_point; - m_hitNormal = hit_normal; + m_hitPosition = result->m_hitPoint; + m_hitNormal = result->m_hitNormal; } - + // no multi-hit search yet return true; - } - +/* this function is used to pre-filter the object before casting the ray on them. + This is useful for "X-Ray" option when we want to see "through" unwanted object. + */ +bool KX_RaySensor::NeedRayCast(KX_ClientObjectInfo* client) +{ + if (client->m_type > KX_ClientObjectInfo::ACTOR) + { + // Unknown type of object, skip it. + // Should not occur as the sensor objects are filtered in RayTest() + printf("Invalid client type %d found ray casting\n", client->m_type); + return false; + } + if (m_bXRay && m_propertyname.Length() != 0) + { + if (m_bFindMaterial) + { + // not quite correct: an object may have multiple material + // should check all the material and not only the first one + if (!client->m_auxilary_info || (m_propertyname != ((char*)client->m_auxilary_info))) + return false; + } + else + { + if (client->m_gameobject->GetProperty(m_propertyname) == NULL) + return false; + } + } + return true; +} bool KX_RaySensor::Evaluate(CValue* event) { bool result = false; + bool reset = m_reset && m_level; m_rayHit = false; m_hitObject = NULL; m_hitPosition = MT_Vector3(0,0,0); @@ -160,6 +188,7 @@ bool KX_RaySensor::Evaluate(CValue* event) MT_Matrix3x3 invmat = matje.inverse(); MT_Vector3 todir; + m_reset = false; switch (m_axis) { case 1: // X @@ -209,8 +238,6 @@ bool KX_RaySensor::Evaluate(CValue* event) m_rayDirection = todir; MT_Point3 topoint = frompoint + (m_distance) * todir; - MT_Point3 resultpoint; - MT_Vector3 resultnormal; PHY_IPhysicsEnvironment* pe = m_scene->GetPhysicsEnvironment(); if (!pe) @@ -232,7 +259,8 @@ bool KX_RaySensor::Evaluate(CValue* event) PHY_IPhysicsEnvironment* physics_environment = this->m_scene->GetPhysicsEnvironment(); - result = KX_RayCast::RayTest(spc, physics_environment, frompoint, topoint, resultpoint, resultnormal, KX_RayCast::Callback<KX_RaySensor>(this)); + KX_RayCast::Callback<KX_RaySensor> callback(this, spc); + KX_RayCast::RayTest(physics_environment, frompoint, topoint, callback); /* now pass this result to some controller */ @@ -259,9 +287,15 @@ bool KX_RaySensor::Evaluate(CValue* event) // notify logicsystem that ray JUST left the Object result = true; } + else + { + result = false; + } } - + if (reset) + // force an event + result = true; return result; } @@ -301,14 +335,14 @@ PyParentObject KX_RaySensor::Parents[] = { }; PyMethodDef KX_RaySensor::Methods[] = { - {"getHitObject",(PyCFunction) KX_RaySensor::sPyGetHitObject,METH_VARARGS, GetHitObject_doc}, - {"getHitPosition",(PyCFunction) KX_RaySensor::sPyGetHitPosition,METH_VARARGS, GetHitPosition_doc}, - {"getHitNormal",(PyCFunction) KX_RaySensor::sPyGetHitNormal,METH_VARARGS, GetHitNormal_doc}, - {"getRayDirection",(PyCFunction) KX_RaySensor::sPyGetRayDirection,METH_VARARGS, GetRayDirection_doc}, + {"getHitObject",(PyCFunction) KX_RaySensor::sPyGetHitObject,METH_VARARGS, (PY_METHODCHAR)GetHitObject_doc}, + {"getHitPosition",(PyCFunction) KX_RaySensor::sPyGetHitPosition,METH_VARARGS, (PY_METHODCHAR)GetHitPosition_doc}, + {"getHitNormal",(PyCFunction) KX_RaySensor::sPyGetHitNormal,METH_VARARGS, (PY_METHODCHAR)GetHitNormal_doc}, + {"getRayDirection",(PyCFunction) KX_RaySensor::sPyGetRayDirection,METH_VARARGS, (PY_METHODCHAR)GetRayDirection_doc}, {NULL,NULL} //Sentinel }; -char KX_RaySensor::GetHitObject_doc[] = +const char KX_RaySensor::GetHitObject_doc[] = "getHitObject()\n" "\tReturns the name of the object that was hit by this ray.\n"; PyObject* KX_RaySensor::PyGetHitObject(PyObject* self, @@ -323,7 +357,7 @@ PyObject* KX_RaySensor::PyGetHitObject(PyObject* self, } -char KX_RaySensor::GetHitPosition_doc[] = +const char KX_RaySensor::GetHitPosition_doc[] = "getHitPosition()\n" "\tReturns the position (in worldcoordinates) where the object was hit by this ray.\n"; PyObject* KX_RaySensor::PyGetHitPosition(PyObject* self, @@ -343,7 +377,7 @@ PyObject* KX_RaySensor::PyGetHitPosition(PyObject* self, } -char KX_RaySensor::GetRayDirection_doc[] = +const char KX_RaySensor::GetRayDirection_doc[] = "getRayDirection()\n" "\tReturns the direction from the ray (in worldcoordinates) .\n"; PyObject* KX_RaySensor::PyGetRayDirection(PyObject* self, @@ -363,7 +397,7 @@ PyObject* KX_RaySensor::PyGetRayDirection(PyObject* self, } -char KX_RaySensor::GetHitNormal_doc[] = +const char KX_RaySensor::GetHitNormal_doc[] = "getHitNormal()\n" "\tReturns the normal (in worldcoordinates) of the object at the location where the object was hit by this ray.\n"; PyObject* KX_RaySensor::PyGetHitNormal(PyObject* self, |