Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenoit Bolsee <benoit.bolsee@online.be>2008-05-24 22:06:58 +0400
committerBenoit Bolsee <benoit.bolsee@online.be>2008-05-24 22:06:58 +0400
commitcc6dac8c425bf0914df1cf3422577c28c617fbc4 (patch)
tree95b1d840c1e5821e0c3701c60772a88aca130cc6
parent459b4ea5be5471eac9d20c13d8dc35f6b81b90ee (diff)
BGE patch: add rayCastToEx(), an extended version of rayCastTo() for use in game script
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp86
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.h1
-rw-r--r--source/gameengine/PyDoc/KX_GameObject.py31
3 files changed, 116 insertions, 2 deletions
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp
index fb636b23082..6b4fd565495 100644
--- a/source/gameengine/Ketsji/KX_GameObject.cpp
+++ b/source/gameengine/Ketsji/KX_GameObject.cpp
@@ -743,6 +743,7 @@ PyMethodDef KX_GameObject::Methods[] = {
{"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 @@ bool KX_GameObject::RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT
}
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 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCastTo,
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
* --------------------------------------------------------------------- */
diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h
index 5dae59d1d63..9e35e45270c 100644
--- a/source/gameengine/Ketsji/KX_GameObject.h
+++ b/source/gameengine/Ketsji/KX_GameObject.h
@@ -665,6 +665,7 @@ public:
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 :
diff --git a/source/gameengine/PyDoc/KX_GameObject.py b/source/gameengine/PyDoc/KX_GameObject.py
index 8ef82b4943b..b0f55b4ad7a 100644
--- a/source/gameengine/PyDoc/KX_GameObject.py
+++ b/source/gameengine/PyDoc/KX_GameObject.py
@@ -174,9 +174,10 @@ class KX_GameObject:
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 @@ class KX_GameObject:
@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