00001
00006
00007 #include "KX_RaySensor.h"
00008 #include "SCA_EventManager.h"
00009 #include "SCA_RandomEventManager.h"
00010 #include "SCA_LogicManager.h"
00011 #include "SCA_IObject.h"
00012 #include "SM_Scene.h"
00013 #include "SM_Object.h"
00014 #include "SM_ClientObjectInfo.h"
00015 #include "KX_GameObject.h"
00016
00017
00018 KX_RaySensor::KX_RaySensor(class SCA_EventManager* eventmgr,
00019 SCA_IObject* gameobj,
00020 const CCString& propname,
00021 bool bFindMaterial,
00022 double distance,
00023 SM_Scene* sumoScene,
00024 PyTypeObject* T)
00025 : SCA_ISensor(gameobj,eventmgr, T),
00026 m_propertyname(propname),
00027 m_bFindMaterial(bFindMaterial),
00028 m_distance(distance),
00029 m_sumoScene(sumoScene),
00030 m_rayHit(false),
00031 m_bTriggered(false),
00032 m_hitObject(NULL)
00033
00034
00035 {
00036
00037 }
00038
00039
00040 KX_RaySensor::~KX_RaySensor()
00041 {
00042
00043 }
00044
00045 bool KX_RaySensor::Evaluate(CValue* event)
00046 {
00047 bool result = false;
00048 m_rayHit = false;
00049 KX_GameObject* obj = (KX_GameObject*) GetParent();
00050 MT_Point3 frompoint = obj->NodeGetWorldPosition();
00051 MT_Matrix3x3 matje = obj->NodeGetWorldOrientation();
00052
00053 MT_Matrix3x3 invmat = matje.inverse();
00054
00055 MT_Vector3 todir(invmat[1][0],invmat[1][1],invmat[1][2]);
00056 todir.normalize();
00057
00058 MT_Point3 topoint = frompoint + (m_distance) * todir;
00059
00060
00061 MT_Point3 resultpoint;
00062 MT_Vector3 resultnormal;
00063 bool ready=false;
00064
00065 do {
00066 SM_Object* hitObj = m_sumoScene->rayTest(frompoint,topoint,
00067 resultpoint, resultnormal);
00068 if (hitObj)
00069 {
00070 SM_ClientObjectInfo* info = (SM_ClientObjectInfo*)hitObj->getClientObject();
00071
00072 SCA_IObject* hitgameobj = (SCA_IObject*)info->m_clientobject;
00073
00074 bool bFound = false;
00075
00076 if (hitgameobj == obj)
00077 {
00078
00079 frompoint = resultpoint + 0.0001 * todir;
00080 } else
00081 {
00082 ready = true;
00083 if (m_propertyname.Length() == 0)
00084 {
00085 bFound = true;
00086 } else
00087 {
00088 if (m_bFindMaterial)
00089 {
00090 if (info->m_auxilary_info)
00091 {
00092 CCString matname = "MA"+m_propertyname;
00093 bFound = (matname == ((char*)info->m_auxilary_info));
00094 }
00095
00096 } else
00097 {
00098 if (hitgameobj->GetProperty(m_propertyname) != NULL)
00099 {
00100 bFound = true;
00101 }
00102 }
00103 }
00104
00105 if (bFound)
00106 {
00107 m_rayHit = true;
00108 m_hitObject = hitgameobj;
00109 m_hitPosition = resultpoint;
00110 m_hitNormal = resultnormal;
00111 }
00112 }
00113 } else
00114 {
00115 ready = true;
00116 }
00117 }
00118 while (!ready);
00119
00120
00121
00122 if (m_rayHit)
00123 {
00124 if (!m_bTriggered)
00125 {
00126
00127 result = true;
00128 m_bTriggered = true;
00129 } else
00130 {
00131
00132 }
00133 } else
00134 {
00135 if (m_bTriggered)
00136 {
00137 m_bTriggered = false;
00138
00139 result = true;
00140 }
00141 }
00142
00143 return result;
00144
00145 }
00146
00147
00148
00149
00150
00151 PyTypeObject KX_RaySensor::Type = {
00152 PyObject_HEAD_INIT(&PyType_Type)
00153 0,
00154 "KX_RaySensor",
00155 sizeof(KX_RaySensor),
00156 0,
00157 PyDestructor,
00158 0,
00159 __getattr,
00160 __setattr,
00161 0,
00162 __repr,
00163 0,
00164 0,
00165 0,
00166 0,
00167 0
00168 };
00169
00170 PyParentObject KX_RaySensor::Parents[] = {
00171 &KX_RaySensor::Type,
00172 &SCA_ISensor::Type,
00173 &SCA_ILogicBrick::Type,
00174 &CValue::Type,
00175 NULL
00176 };
00177
00178 PyMethodDef KX_RaySensor::Methods[] = {
00179 {"getHitObject",(PyCFunction) KX_RaySensor::sPyGetHitObject,METH_VARARGS, GetHitObject_doc},
00180 {"getHitPosition",(PyCFunction) KX_RaySensor::sPyGetHitPosition,METH_VARARGS, GetHitPosition_doc},
00181 {"getHitNormal",(PyCFunction) KX_RaySensor::sPyGetHitNormal,METH_VARARGS, GetHitNormal_doc},
00182
00183 {NULL,NULL}
00184 };
00185
00186 char KX_RaySensor::GetHitObject_doc[] =
00187 "getHitObject()\n"
00188 "\tReturns the name of the object that was hit by this ray.\n";
00189 PyObject* KX_RaySensor::PyGetHitObject(PyObject* self,
00190 PyObject* args,
00191 PyObject* kwds)
00192 {
00193 if (m_hitObject)
00194 {
00195 return m_hitObject->AddRef();
00196 }
00197 Py_Return;
00198 }
00199
00200
00201 char KX_RaySensor::GetHitPosition_doc[] =
00202 "getHitPosition()\n"
00203 "\tReturns the position (in worldcoordinates) where the object was hit by this ray.\n";
00204 PyObject* KX_RaySensor::PyGetHitPosition(PyObject* self,
00205 PyObject* args,
00206 PyObject* kwds)
00207 {
00208
00209 float x=0,y=0,z=0;
00210
00211 MT_Point3 pos = m_hitPosition;
00212
00213 PyObject* resultlist = PyList_New(3);
00214 int index;
00215 for (index=0;index<3;index++)
00216 {
00217 PyList_SetItem(resultlist,index,PyFloat_FromDouble(pos[index]));
00218 }
00219 return resultlist;
00220
00221 }
00222
00223 char KX_RaySensor::GetHitNormal_doc[] =
00224 "getHitNormal()\n"
00225 "\tReturns the normal (in worldcoordinates) of the object at the location where the object was hit by this ray.\n";
00226 PyObject* KX_RaySensor::PyGetHitNormal(PyObject* self,
00227 PyObject* args,
00228 PyObject* kwds)
00229 {
00230
00231 float x=0,y=0,z=0;
00232
00233 MT_Vector3 pos = m_hitNormal;
00234
00235 PyObject* resultlist = PyList_New(3);
00236 int index;
00237 for (index=0;index<3;index++)
00238 {
00239 PyList_SetItem(resultlist,index,PyFloat_FromDouble(pos[index]));
00240 }
00241 return resultlist;
00242
00243 }
00244
00245
00246
00247 PyObject* KX_RaySensor::_getattr(char* attr) {
00248 _getattr_up(SCA_ISensor);
00249 }