New rayCastTo() python method for KX_GameObject:

rayCastTo(other,dist,prop)

Look towards another point/KX_GameObject and return first object hit within dist with a property that match prop, None if no object found or if it does not match prop.

Parameters:
  other = 3-tuple (xyz coordinates) or object reference (target=center of object)
          (type = list [x,y,z] or object reference)
  dist = max distance of detection (can be negative => look behind)
         If 0 or omitted => detect up to other
	 (type=float)
  prop = property name that object must have
         If empty or omitted => detect any object
         (type=string)
This commit is contained in:
Benoit Bolsee
2008-03-15 17:08:58 +00:00
parent d0b36bfeaa
commit 435a49dfe7
3 changed files with 105 additions and 2 deletions

View File

@@ -1670,7 +1670,7 @@ static KX_GameObject *gameobject_from_blenderobject(
break;
}
}
gameobj->SetPhysicsEnvironment(kxscene->GetPhysicsEnvironment());
return gameobj;
}

View File

@@ -61,6 +61,7 @@ typedef unsigned long uint_ptr;
#include "SG_Controller.h"
#include "KX_ClientObjectInfo.h"
#include "RAS_BucketManager.h"
#include "KX_RayCast.h"
#include "KX_PyMath.h"
@@ -80,7 +81,9 @@ KX_GameObject::KX_GameObject(
m_bUseObjectColor(false),
m_bVisible(true),
m_pPhysicsController1(NULL),
m_isDeformable(false)
m_pPhysicsEnvironment(NULL),
m_isDeformable(false),
m_pHitObject(NULL)
{
m_ignore_activity_culling = false;
m_pClient_info = new KX_ClientObjectInfo(this, KX_ClientObjectInfo::ACTOR);
@@ -657,6 +660,7 @@ PyMethodDef KX_GameObject::Methods[] = {
{"getMesh", (PyCFunction)KX_GameObject::sPyGetMesh,METH_VARARGS},
{"getPhysicsId", (PyCFunction)KX_GameObject::sPyGetPhysicsId,METH_VARARGS},
KX_PYMETHODTABLE(KX_GameObject, getDistanceTo),
KX_PYMETHODTABLE(KX_GameObject, rayCastTo),
{NULL,NULL} //Sentinel
};
@@ -1176,6 +1180,83 @@ KX_PYMETHODDEF_DOC(KX_GameObject, getDistanceTo,
return NULL;
}
bool KX_GameObject::RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_Vector3& hit_normal, void * const data)
{
KX_GameObject* hitKXObj = client->m_gameobject;
if (client->m_type > KX_ClientObjectInfo::ACTOR)
{
// false hit
return false;
}
if (m_testPropName.Length() == 0 || hitKXObj->GetProperty(m_testPropName) != NULL)
{
m_pHitObject = hitKXObj;
return true;
}
return false;
}
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"
" 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")
{
MT_Point3 toPoint;
PyObject* pyarg;
float dist = 0.0f;
char *propName = NULL;
if (!PyArg_ParseTuple(args,"O|fs", &pyarg, &dist, &propName))
return NULL;
if (!PyVecTo(pyarg, toPoint))
{
KX_GameObject *other;
PyErr_Clear();
if (!PyType_IsSubtype(pyarg->ob_type, &KX_GameObject::Type))
return NULL;
other = static_cast<KX_GameObject*>(pyarg);
toPoint = other->NodeGetWorldPosition();
}
MT_Point3 fromPoint = 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)
{
m_pHitObject->AddRef();
return m_pHitObject;
}
Py_Return;
}
/* ---------------------------------------------------------------------
* Some stuff taken from the header
* --------------------------------------------------------------------- */

View File

@@ -57,6 +57,7 @@
struct KX_ClientObjectInfo;
class RAS_MeshObject;
class KX_IPhysicsController;
class PHY_IPhysicsEnvironment;
/**
@@ -82,6 +83,11 @@ protected:
bool m_bVisible;
KX_IPhysicsController* m_pPhysicsController1;
// used for ray casting
PHY_IPhysicsEnvironment* m_pPhysicsEnvironment;
STR_String m_testPropName;
KX_GameObject* m_pHitObject;
SG_Node* m_pSGNode;
MT_CmMatrix4x4 m_OpenGL_4x4Matrix;
@@ -261,6 +267,19 @@ public:
);
/**
* @return a pointer to the physics environment in use during the game, for rayCasting
*/
PHY_IPhysicsEnvironment* GetPhysicsEnvironment()
{
return m_pPhysicsEnvironment;
}
void SetPhysicsEnvironment(PHY_IPhysicsEnvironment* physicsEnvironment)
{
m_pPhysicsEnvironment = physicsEnvironment;
}
/**
* @return a pointer to the physics controller owned by this class.
*/
@@ -341,6 +360,8 @@ public:
return m_bDyna;
}
bool RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_Vector3& hit_normal, void * const data);
/**
* @section Physics accessors for this node.
@@ -608,6 +629,7 @@ public:
KX_PYMETHOD(KX_GameObject,GetMesh);
KX_PYMETHOD(KX_GameObject,GetParent);
KX_PYMETHOD(KX_GameObject,GetPhysicsId);
KX_PYMETHOD_DOC(KX_GameObject,rayCastTo);
KX_PYMETHOD_DOC(KX_GameObject,getDistanceTo);
private :