From 73079730638f1f21c04b075839d87377315e8f86 Mon Sep 17 00:00:00 2001 From: Mitchell Stokes Date: Thu, 17 Jul 2014 23:00:30 -0700 Subject: BGE: Add property/material detection and X-Ray for mouse over any sensor This patch adds a Property/Material detection and a X-Ray mode to the mouse over any sensor like on the ray sensor. Proposal: http://blenderartists.org/forum/showthread.php?261847-BGE-proposal-Mouse-Over-Any-sensor-with-Property-and-X-Ray&highlight=proposal Reviewers: moguri Reviewed By: moguri Differential Revision: https://developer.blender.org/D653 --- source/gameengine/Converter/KX_ConvertSensors.cpp | 7 ++ source/gameengine/Ketsji/KX_MouseFocusSensor.cpp | 88 +++++++++++++++++++---- source/gameengine/Ketsji/KX_MouseFocusSensor.h | 20 +++++- 3 files changed, 101 insertions(+), 14 deletions(-) (limited to 'source/gameengine') diff --git a/source/gameengine/Converter/KX_ConvertSensors.cpp b/source/gameengine/Converter/KX_ConvertSensors.cpp index 93a5ee11366..0d706fcd924 100644 --- a/source/gameengine/Converter/KX_ConvertSensors.cpp +++ b/source/gameengine/Converter/KX_ConvertSensors.cpp @@ -329,12 +329,19 @@ void BL_ConvertSensors(struct Object* blenderobject, gameobj); } else { /* give us a focus-aware sensor */ + bool bFindMaterial = (bmouse->mode & SENS_COLLISION_MATERIAL); + bool bXRay = (bmouse->flag & SENS_RAY_XRAY); + STR_String checkname = (bFindMaterial? bmouse->matname : bmouse->propname); + gamesensor = new KX_MouseFocusSensor(eventmgr, startx, starty, keytype, trackfocus, (bmouse->flag & SENS_MOUSE_FOCUS_PULSE) ? true:false, + checkname, + bFindMaterial, + bXRay, kxscene, kxengine, gameobj); diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp index 2dbafdad3d9..e21ac386bc8 100644 --- a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp +++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp @@ -60,15 +60,21 @@ KX_MouseFocusSensor::KX_MouseFocusSensor(SCA_MouseManager* eventmgr, int startx, int starty, - short int mousemode, - int focusmode, - bool bTouchPulse, - KX_Scene* kxscene, - KX_KetsjiEngine *kxengine, - SCA_IObject* gameobj) + short int mousemode, + int focusmode, + bool bTouchPulse, + const STR_String& propname, + bool bFindMaterial, + bool bXRay, + KX_Scene* kxscene, + KX_KetsjiEngine *kxengine, + SCA_IObject* gameobj) : SCA_MouseSensor(eventmgr, startx, starty, mousemode, gameobj), m_focusmode(focusmode), m_bTouchPulse(bTouchPulse), + m_propertyname(propname), + m_bFindMaterial(bFindMaterial), + m_bXRay(bXRay), m_kxscene(kxscene), m_kxengine(kxengine) { @@ -146,20 +152,73 @@ bool KX_MouseFocusSensor::RayHit(KX_ClientObjectInfo *client_info, KX_RayCast *r * self-hits are excluded by setting the correct ignore-object.) * Hitspots now become valid. */ KX_GameObject* thisObj = (KX_GameObject*) GetParent(); + + bool bFound = false; + if ((m_focusmode == 2) || hitKXObj == thisObj) { - m_hitObject = hitKXObj; - m_hitPosition = result->m_hitPoint; - m_hitNormal = result->m_hitNormal; - m_hitUV = result->m_hitUV; - return true; + if (m_propertyname.Length() == 0) + { + bFound = true; + } + else + { + if (m_bFindMaterial) + { + if (client_info->m_auxilary_info) + { + bFound = (m_propertyname== ((char*)client_info->m_auxilary_info)); + } + } + else + { + bFound = hitKXObj->GetProperty(m_propertyname) != NULL; + } + } + + if (bFound) + { + m_hitObject = hitKXObj; + m_hitPosition = result->m_hitPoint; + m_hitNormal = result->m_hitNormal; + m_hitUV = result->m_hitUV; + return true; + } } return true; // object must be visible to trigger //return false; // occluded objects can trigger } - +/* 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_MouseFocusSensor::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_MouseFocusSensor::ParentObjectHasFocusCamera(KX_Camera *cam) { @@ -384,7 +443,10 @@ PyAttributeDef KX_MouseFocusSensor::Attributes[] = { KX_PYATTRIBUTE_RO_FUNCTION("hitPosition", KX_MouseFocusSensor, pyattr_get_hit_position), KX_PYATTRIBUTE_RO_FUNCTION("hitNormal", KX_MouseFocusSensor, pyattr_get_hit_normal), KX_PYATTRIBUTE_RO_FUNCTION("hitUV", KX_MouseFocusSensor, pyattr_get_hit_uv), - KX_PYATTRIBUTE_BOOL_RW("usePulseFocus", KX_MouseFocusSensor,m_bTouchPulse), + KX_PYATTRIBUTE_BOOL_RW("usePulseFocus", KX_MouseFocusSensor, m_bTouchPulse), + KX_PYATTRIBUTE_BOOL_RW("useXRay", KX_MouseFocusSensor, m_bXRay), + KX_PYATTRIBUTE_BOOL_RW("useMaterial", KX_MouseFocusSensor, m_bFindMaterial), + KX_PYATTRIBUTE_STRING_RW("propName", 0, MAX_PROP_NAME, false, KX_MouseFocusSensor, m_propertyname), { NULL } //Sentinel }; diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.h b/source/gameengine/Ketsji/KX_MouseFocusSensor.h index 1f7809831e7..903c3c03571 100644 --- a/source/gameengine/Ketsji/KX_MouseFocusSensor.h +++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.h @@ -57,6 +57,9 @@ class KX_MouseFocusSensor : public SCA_MouseSensor short int mousemode, int focusmode, bool bTouchPulse, + const STR_String& propname, + bool bFindMaterial, + bool bXRay, KX_Scene* kxscene, KX_KetsjiEngine* kxengine, SCA_IObject* gameobj); @@ -88,7 +91,7 @@ class KX_MouseFocusSensor : public SCA_MouseSensor }; bool RayHit(KX_ClientObjectInfo* client, KX_RayCast* result, void * const data); - bool NeedRayCast(KX_ClientObjectInfo* client) { return true; } + bool NeedRayCast(KX_ClientObjectInfo* client); const MT_Point3& RaySource() const; const MT_Point3& RayTarget() const; @@ -133,6 +136,21 @@ class KX_MouseFocusSensor : public SCA_MouseSensor */ bool m_bTouchPulse; + /** + * Flags get trought other objects + */ + bool m_bXRay; + + /** + * Flags material + */ + bool m_bFindMaterial; + + /** + * Property or material name + */ + STR_String m_propertyname; + /** * Flags whether the previous test evaluated positive. */ -- cgit v1.2.3