[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [14949] trunk/blender/source/gameengine: BGE patch: add rayCastToEx(), an extended version of rayCastTo() for use in game script

Benoit Bolsee benoit.bolsee at online.be
Sat May 24 20:06:58 CEST 2008


Revision: 14949
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=14949
Author:   ben2610
Date:     2008-05-24 20:06:58 +0200 (Sat, 24 May 2008)

Log Message:
-----------
BGE patch: add rayCastToEx(), an extended version of rayCastTo() for use in game script

Modified Paths:
--------------
    trunk/blender/source/gameengine/Ketsji/KX_GameObject.cpp
    trunk/blender/source/gameengine/Ketsji/KX_GameObject.h
    trunk/blender/source/gameengine/PyDoc/KX_GameObject.py

Modified: trunk/blender/source/gameengine/Ketsji/KX_GameObject.cpp
===================================================================
--- trunk/blender/source/gameengine/Ketsji/KX_GameObject.cpp	2008-05-24 12:22:53 UTC (rev 14948)
+++ trunk/blender/source/gameengine/Ketsji/KX_GameObject.cpp	2008-05-24 18:06:58 UTC (rev 14949)
@@ -743,6 +743,7 @@
 	{"getPhysicsId", (PyCFunction)KX_GameObject::sPyGetPhysicsId,METH_VARARGS},
 	KX_PYMETHODTABLE(KX_GameObject, getDistanceTo),
 	KX_PYMETHODTABLE(KX_GameObject, rayCastTo),
+	KX_PYMETHODTABLE(KX_GameObject, rayCastToEx),
 	{NULL,NULL} //Sentinel
 };
 
@@ -1325,7 +1326,7 @@
 }
 
 KX_PYMETHODDEF_DOC(KX_GameObject, rayCastTo,
-"rayCastTo(other,dist,prop): look towards another point/KX_GameObject and return first object hit within dist that match prop\n"
+"rayCastTo(other,dist,prop): look towards another point/KX_GameObject and return first object hit within dist that matches prop\n"
 " prop = property name that object must have; can be omitted => detect any object\n"
 " dist = max distance to look (can be negative => look behind); 0 or omitted => detect up to other\n"
 " other = 3-tuple or object reference")
@@ -1380,6 +1381,89 @@
 	Py_Return;
 }
 
+KX_PYMETHODDEF_DOC(KX_GameObject, rayCastToEx,
+"rayCastToEx(to,from,dist,prop): cast a ray and return tuple (object,hit,normal) of contact point with object within dist that matches prop or None if no hit\n"
+" prop = property name that object must have; can be omitted => detect any object\n"
+" dist = max distance to look (can be negative => look behind); 0 or omitted => detect up to to\n"
+" from = 3-tuple or object reference for origin of ray (if object, use center of object)\n"
+"        Can None or omitted => start from self object center\n"
+" to = 3-tuple or object reference for destination of ray (if object, use center of object)\n"
+"Note: the object on which you call this method matters: the ray will ignore it if it goes through it\n")
+{
+	MT_Point3 toPoint;
+	MT_Point3 fromPoint;
+	PyObject* pyto;
+	PyObject* pyfrom = NULL;
+	float dist = 0.0f;
+	char *propName = NULL;
+	KX_GameObject *other;
+
+	if (!PyArg_ParseTuple(args,"O|Ofs", &pyto, &pyfrom, &dist, &propName))
+		return NULL;
+
+	if (!PyVecTo(pyto, toPoint))
+	{
+		PyErr_Clear();
+		if (!PyType_IsSubtype(pyto->ob_type, &KX_GameObject::Type))
+			return NULL;
+		other = static_cast<KX_GameObject*>(pyto);
+		toPoint = other->NodeGetWorldPosition();
+	}
+	if (!pyfrom || pyfrom == Py_None)
+	{
+		fromPoint = NodeGetWorldPosition();
+	}
+	else if (!PyVecTo(pyfrom, fromPoint))
+	{
+		PyErr_Clear();
+		if (!PyType_IsSubtype(pyfrom->ob_type, &KX_GameObject::Type))
+			return NULL;
+		other = static_cast<KX_GameObject*>(pyfrom);
+		fromPoint = other->NodeGetWorldPosition();
+	}
+
+	if (dist != 0.0f)
+	{
+		MT_Vector3 toDir = toPoint-fromPoint;
+		toDir.normalize();
+		toPoint = fromPoint + (dist) * toDir;
+	}
+
+	MT_Point3 resultPoint;
+	MT_Vector3 resultNormal;
+	PHY_IPhysicsEnvironment* pe = GetPhysicsEnvironment();
+	KX_IPhysicsController *spc = GetPhysicsController();
+	KX_GameObject *parent = GetParent();
+	if (!spc && parent)
+		spc = parent->GetPhysicsController();
+	if (parent)
+		parent->Release();
+	
+	m_pHitObject = NULL;
+	if (propName)
+		m_testPropName = propName;
+	else
+		m_testPropName.SetLength(0);
+	KX_RayCast::RayTest(spc, pe, fromPoint, toPoint, resultPoint, resultNormal, KX_RayCast::Callback<KX_GameObject>(this));
+
+    if (m_pHitObject)
+	{
+		PyObject* returnValue = PyTuple_New(3);
+		if (!returnValue)
+			return NULL;
+		PyTuple_SET_ITEM(returnValue, 0, m_pHitObject->AddRef());
+		PyTuple_SET_ITEM(returnValue, 1, PyObjectFrom(resultPoint));
+		PyTuple_SET_ITEM(returnValue, 2, PyObjectFrom(resultNormal));
+		return returnValue;
+		//return Py_BuildValue("(O,(fff),(fff))", 
+		//	m_pHitObject->AddRef(),		// trick: KX_GameObject are not true Python object, they use a difference reference count system
+		//	resultPoint[0], resultPoint[1], resultPoint[2],
+		//	resultNormal[0], resultNormal[1], resultNormal[2]);
+	}
+	return Py_BuildValue("OOO", Py_None, Py_None, Py_None);
+	//Py_Return;
+}
+
 /* --------------------------------------------------------------------- 
  * Some stuff taken from the header
  * --------------------------------------------------------------------- */

Modified: trunk/blender/source/gameengine/Ketsji/KX_GameObject.h
===================================================================
--- trunk/blender/source/gameengine/Ketsji/KX_GameObject.h	2008-05-24 12:22:53 UTC (rev 14948)
+++ trunk/blender/source/gameengine/Ketsji/KX_GameObject.h	2008-05-24 18:06:58 UTC (rev 14949)
@@ -665,6 +665,7 @@
 	KX_PYMETHOD(KX_GameObject,RemoveParent);
 	KX_PYMETHOD(KX_GameObject,GetPhysicsId);
 	KX_PYMETHOD_DOC(KX_GameObject,rayCastTo);
+	KX_PYMETHOD_DOC(KX_GameObject,rayCastToEx);
 	KX_PYMETHOD_DOC(KX_GameObject,getDistanceTo);
 private :
 

Modified: trunk/blender/source/gameengine/PyDoc/KX_GameObject.py
===================================================================
--- trunk/blender/source/gameengine/PyDoc/KX_GameObject.py	2008-05-24 12:22:53 UTC (rev 14948)
+++ trunk/blender/source/gameengine/PyDoc/KX_GameObject.py	2008-05-24 18:06:58 UTC (rev 14949)
@@ -174,9 +174,10 @@
 
 		The ray is always casted from the center of the object, ignoring the object itself.
 		The ray is casted towards the center of another object or an explicit [x,y,z] point.
+		Use rayCastToEx() if you need to retrieve the hit point 
 
 		@param other: [x,y,z] or object towards which the ray is casted
-		@type other: L{KX_GameObject} or string
+		@type other: L{KX_GameObject} or 3-tuple
 		@param dist: max distance to look (can be negative => look behind); 0 or omitted => detect up to other
 		@type dist: float
 		@param prop: property name that object must have; can be omitted => detect any object
@@ -184,4 +185,32 @@
 		@rtype: L{KX_GameObject}
 		@return: the first object hit or None if no object or object does not match prop
 		"""
+	def rayCastToEx(to,from,dist,prop):
+		"""
+		Look from a point/object to another point/object and find first object hit within dist that matches prop.
+		Returns a 3-tuple with object reference, hit point and hit normal or (None,None,None) if no object hit.
+		Ex:
+			# shoot along the axis gun-gunAim (gunAim should be collision-free)
+			ob,point,normal = gun.rayCastToEx(gunAim,None,50)
+			if ob:
+				# hit something
+
+		Notes:				
+		The ray ignores the object on which the method is called.
+		If is casted from/to object center or explicit [x,y,z] points.
+		The ray does not have X-Ray capability: the first object hit (other than self object) stops the ray
+		If a property was specified and the first object hit does not have that property, there is no hit
+		The	ray ignores collision-free objects
+
+		@param to: [x,y,z] or object to which the ray is casted
+		@type to: L{KX_GameObject} or 3-tuple
+		@param from: [x,y,z] or object from which the ray is casted; None or omitted => use self object center
+		@type from: L{KX_GameObject} or 3-tuple or None
+		@param dist: max distance to look (can be negative => look behind); 0 or omitted => detect up to to
+		@type dist: float
+		@param prop: property name that object must have; can be omitted => detect any object
+		@type prop: string
+		@rtype: 3-tuple (L{KX_GameObject}, 3-tuple (x,y,z), 3-tuple (nx,ny,nz))
+		@return: (object,hitpoint,hitnormal) or (None,None,None)
+		"""
 	
\ No newline at end of file





More information about the Bf-blender-cvs mailing list