BGE patch: add rayCastToEx(), an extended version of rayCastTo() for use in game script
This commit is contained in:
parent
459b4ea5be
commit
cc6dac8c42
@ -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
|
||||
* --------------------------------------------------------------------- */
|
||||
|
@ -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 :
|
||||
|
||||
|
@ -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)
|
||||
"""
|
||||
|
Loading…
Reference in New Issue
Block a user