Commit: 73079730638f1f21c04b075839d87377315e8f86
Author: Mitchell Stokes
Date:   Thu Jul 17 23:00:30 2014 -0700
https://developer.blender.org/rB73079730638f1f21c04b075839d87377315e8f86

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

===================================================================

M       doc/python_api/rst/bge_types/bge.types.KX_MouseFocusSensor.rst
M       source/blender/editors/space_logic/logic_window.c
M       source/blender/makesdna/DNA_sensor_types.h
M       source/blender/makesrna/intern/rna_sensor.c
M       source/gameengine/Converter/KX_ConvertSensors.cpp
M       source/gameengine/Ketsji/KX_MouseFocusSensor.cpp
M       source/gameengine/Ketsji/KX_MouseFocusSensor.h

===================================================================

diff --git a/doc/python_api/rst/bge_types/bge.types.KX_MouseFocusSensor.rst 
b/doc/python_api/rst/bge_types/bge.types.KX_MouseFocusSensor.rst
index dda73ea..0600a4b 100644
--- a/doc/python_api/rst/bge_types/bge.types.KX_MouseFocusSensor.rst
+++ b/doc/python_api/rst/bge_types/bge.types.KX_MouseFocusSensor.rst
@@ -64,3 +64,20 @@ base class --- :class:`SCA_MouseSensor`
 
       :type: boolean
 
+   .. attribute:: useXRay
+
+      If enabled it allows the sensor to see through game objects that don't 
have the selected property or material.
+
+     :type: boolean
+
+   .. attribute:: propName
+
+      The property or material the sensor is looking for.
+
+     :type: string
+
+   .. attribute:: useMaterial
+
+      Determines if the sensor is looking for a property or material. KX_True 
= Find material; KX_False = Find property.
+
+     :type: boolean
diff --git a/source/blender/editors/space_logic/logic_window.c 
b/source/blender/editors/space_logic/logic_window.c
index 3254727..1a0aab7 100644
--- a/source/blender/editors/space_logic/logic_window.c
+++ b/source/blender/editors/space_logic/logic_window.c
@@ -1144,15 +1144,35 @@ static void draw_sensor_message(uiLayout *layout, 
PointerRNA *ptr)
        uiItemR(layout, ptr, "subject", 0, NULL, ICON_NONE);
 }
 
-static void draw_sensor_mouse(uiLayout *layout, PointerRNA *ptr)
+static void draw_sensor_mouse(uiLayout *layout, PointerRNA *ptr, bContext *C)
 {
-       uiLayout *split;
+       uiLayout *split, *split2;
+
+       Object *ob = (Object *)ptr->id.data;
+       PointerRNA main_ptr;
 
        split = uiLayoutSplit(layout, 0.8f, false);
        uiItemR(split, ptr, "mouse_event", 0, NULL, ICON_NONE);
 
        if (RNA_enum_get(ptr, "mouse_event") == BL_SENS_MOUSE_MOUSEOVER_ANY)
+       {
                uiItemR(split, ptr, "use_pulse", UI_ITEM_R_TOGGLE, NULL, 
ICON_NONE);
+
+               split = uiLayoutSplit(layout, 0.3f, false);
+               uiItemR(split, ptr, "use_material", 0, "", ICON_NONE);
+
+               split2 = uiLayoutSplit(split, 0.7f, false);
+               if (RNA_enum_get(ptr, "use_material") == SENS_RAY_PROPERTY)
+               {
+                       uiItemR(split2, ptr, "property", 0, "", ICON_NONE);
+               }
+               else
+               {
+                       RNA_main_pointer_create(CTX_data_main(C), &main_ptr);
+                       uiItemPointerR(split2, ptr, "material", &main_ptr, 
"materials", "", ICON_MATERIAL_DATA);
+               }
+               uiItemR(split2, ptr, "use_x_ray", UI_ITEM_R_TOGGLE, NULL, 
ICON_NONE);
+       }
 }
 
 static void draw_sensor_near(uiLayout *layout, PointerRNA *ptr)
@@ -1273,7 +1293,7 @@ static void draw_brick_sensor(uiLayout *layout, 
PointerRNA *ptr, bContext *C)
                        draw_sensor_message(box, ptr);
                        break;
                case SENS_MOUSE:
-                       draw_sensor_mouse(box, ptr);
+                       draw_sensor_mouse(box, ptr, C);
                        break;
                case SENS_NEAR:
                        draw_sensor_near(box, ptr);
diff --git a/source/blender/makesdna/DNA_sensor_types.h 
b/source/blender/makesdna/DNA_sensor_types.h
index cd1977c..8d59a13 100644
--- a/source/blender/makesdna/DNA_sensor_types.h
+++ b/source/blender/makesdna/DNA_sensor_types.h
@@ -57,7 +57,9 @@ typedef struct bMouseSensor {
        short type;
        short flag;
        short pad1;
-       short pad2;
+       short mode;                     /* flag to choose material or property 
*/
+       char propname[64];
+       char matname[64];
 } bMouseSensor;
 
 /* DEPRECATED */
diff --git a/source/blender/makesrna/intern/rna_sensor.c 
b/source/blender/makesrna/intern/rna_sensor.c
index aeef04f..3944b59 100644
--- a/source/blender/makesrna/intern/rna_sensor.c
+++ b/source/blender/makesrna/intern/rna_sensor.c
@@ -405,6 +405,12 @@ static void rna_def_mouse_sensor(BlenderRNA *brna)
                {0, NULL, 0, NULL, NULL}
        };
 
+       static const EnumPropertyItem prop_mouse_type_items[] = {
+               {SENS_COLLISION_PROPERTY, "PROPERTY", ICON_LOGIC, "Property", 
"Use a material for ray intersections"},
+               {SENS_COLLISION_MATERIAL, "MATERIAL", ICON_MATERIAL_DATA, 
"Material", "Use a property for ray intersections"},
+               {0, NULL, 0, NULL, NULL}
+       };
+
        srna = RNA_def_struct(brna, "MouseSensor", "Sensor");
        RNA_def_struct_ui_text(srna, "Mouse Sensor", "Sensor to detect mouse 
events");
        RNA_def_struct_sdna_from(srna, "bMouseSensor", "data");
@@ -419,6 +425,27 @@ static void rna_def_mouse_sensor(BlenderRNA *brna)
        RNA_def_property_boolean_sdna(prop, NULL, "flag", 
SENS_MOUSE_FOCUS_PULSE);
        RNA_def_property_ui_text(prop, "Pulse", "Moving the mouse over a 
different object generates a pulse");
        RNA_def_property_update(prop, NC_LOGIC, NULL);
+       
+       prop = RNA_def_property(srna, "use_material", PROP_ENUM, PROP_NONE);
+       RNA_def_property_enum_bitflag_sdna(prop, NULL, "mode");
+       RNA_def_property_enum_items(prop, prop_mouse_type_items);
+       RNA_def_property_ui_text(prop, "M/P", "Toggle collision on material or 
property");
+       RNA_def_property_update(prop, NC_LOGIC, NULL);
+
+       prop = RNA_def_property(srna, "property", PROP_STRING, PROP_NONE);
+       RNA_def_property_string_sdna(prop, NULL, "propname");
+       RNA_def_property_ui_text(prop, "Property", "Only look for objects with 
this property (blank = all objects)");
+       RNA_def_property_update(prop, NC_LOGIC, NULL);
+
+       prop = RNA_def_property(srna, "material", PROP_STRING, PROP_NONE);
+       RNA_def_property_string_sdna(prop, NULL, "matname");
+       RNA_def_property_ui_text(prop, "Material", "Only look for objects with 
this material (blank = all objects)");
+       RNA_def_property_update(prop, NC_LOGIC, NULL);  
+
+       prop = RNA_def_property(srna, "use_x_ray", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", SENS_RAY_XRAY);
+       RNA_def_property_ui_text(prop, "X-Ray", "Toggle X-Ray option (see 
through objects that don't have the property)");
+       RNA_def_property_update(prop, NC_LOGIC, NULL);
 }
 
 static void rna_def_keyboard_sensor(BlenderRNA *brna)
diff --git a/source/gameengine/Converter/KX_ConvertSensors.cpp 
b/source/gameengine/Converter/KX_ConvertSensors.cpp
index 93a5ee1..0d706fc 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 2dbafda..e21ac38 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_MouseFocu

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to