[Bf-blender-cvs] [7307973] master: BGE: Add property/material detection and X-Ray for mouse over any sensor

Mitchell Stokes noreply at git.blender.org
Fri Jul 18 08:06:33 CEST 2014


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. @@




More information about the Bf-blender-cvs mailing list