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:
Diffstat (limited to 'source/gameengine/Ketsji/KX_TouchSensor.cpp')
-rw-r--r--source/gameengine/Ketsji/KX_TouchSensor.cpp393
1 files changed, 393 insertions, 0 deletions
diff --git a/source/gameengine/Ketsji/KX_TouchSensor.cpp b/source/gameengine/Ketsji/KX_TouchSensor.cpp
new file mode 100644
index 00000000000..daf344999fc
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_TouchSensor.cpp
@@ -0,0 +1,393 @@
+/**
+ * Senses touch and collision events
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include "KX_TouchSensor.h"
+#include "SCA_EventManager.h"
+#include "SCA_LogicManager.h"
+#include "KX_GameObject.h"
+#include "KX_TouchEventManager.h"
+#include <iostream>
+
+#ifdef PHYSICS_NOT_YET
+
+/* ------------------------------------------------------------------------- */
+/* Native functions */
+/* ------------------------------------------------------------------------- */
+
+void KX_TouchSensor::SynchronizeTransform()
+{
+
+ if (m_sumoObj)
+ {
+ m_sumoObj->setPosition(((KX_GameObject*)GetParent())->NodeGetWorldPosition());
+ m_sumoObj->setOrientation(
+ ((KX_GameObject*)GetParent())->NodeGetWorldOrientation().getRotation()
+ );
+ m_sumoObj->calcXform();
+ }
+
+}
+
+
+void KX_TouchSensor::EndFrame() {
+ m_colliders->ReleaseAndRemoveAll();
+ m_bTriggered = false;
+}
+
+bool KX_TouchSensor::Evaluate(CValue* event)
+{
+ bool result = false;
+
+ if (m_bTriggered != m_bLastTriggered)
+ {
+ m_bLastTriggered = m_bTriggered;
+ if (!m_bTriggered)
+ m_hitObject = NULL;
+ result = true;
+ }
+
+ return result;
+}
+
+KX_TouchSensor::KX_TouchSensor(SCA_EventManager* eventmgr,KX_GameObject* gameobj,SM_Object* sumoObj,bool bFindMaterial,const STR_String& touchedpropname,PyTypeObject* T)
+:SCA_ISensor(gameobj,eventmgr,T),
+m_touchedpropname(touchedpropname),
+m_bFindMaterial(bFindMaterial),
+m_sumoObj(sumoObj),
+m_bCollision(false),
+m_bTriggered(false),
+m_bLastTriggered(false)
+{
+ m_eventmgr = eventmgr;
+ KX_TouchEventManager* touchmgr = (KX_TouchEventManager*) eventmgr;
+
+ m_resptable = touchmgr->GetResponseTable();
+
+ m_solidHandle = m_sumoObj->getObjectHandle();
+
+ m_hitObject = NULL;
+ m_colliders = new CListValue();
+}
+
+
+KX_TouchSensor::~KX_TouchSensor()
+{
+ DT_ClearObjectResponse(m_resptable,m_solidHandle);
+ m_colliders->Release();
+}
+
+void KX_TouchSensor::ReParent(SCA_IObject* parent)
+{
+
+ m_sumoObj = ((KX_GameObject*)parent)->GetSumoObject();
+ m_solidHandle = m_sumoObj->getObjectHandle();
+
+ m_client_info.m_clientobject = NULL;//parent;
+ m_client_info.m_auxilary_info = NULL;
+ SCA_ISensor::ReParent(parent);
+}
+
+
+void KX_TouchSensor::RegisterSumo()
+{
+
+ if (m_sumoObj)
+ {
+ // collision
+ DT_SetObjectResponse(
+ m_resptable,
+ m_solidHandle,
+ collisionResponse,
+ DT_SIMPLE_RESPONSE,
+ this);
+
+ }
+
+}
+
+void KX_TouchSensor::HandleCollision(void* obj1,void* obj2,const DT_CollData * coll_data)
+{
+ KX_TouchEventManager* toucheventmgr = (KX_TouchEventManager*)m_eventmgr;
+ KX_GameObject* parent = (KX_GameObject*)GetParent();
+
+ // need the mapping from SM_Objects to gameobjects now
+
+ SM_ClientObjectInfo* client_info =(SM_ClientObjectInfo*) (obj1 == m_sumoObj?
+ ((SM_Object*)obj2)->getClientObject() :
+ ((SM_Object*)obj1)->getClientObject());
+
+
+ KX_GameObject* gameobj = ( client_info ?
+ (KX_GameObject*)client_info->m_clientobject :
+ NULL);
+
+ if (gameobj && (gameobj != parent))
+ {
+ if (!m_colliders->SearchValue(gameobj))
+ m_colliders->Add(gameobj->AddRef());
+
+ bool found = m_touchedpropname.IsEmpty();
+ if (!found)
+ {
+ if (m_bFindMaterial)
+ {
+ if (client_info->m_auxilary_info)
+ {
+ found = (m_touchedpropname == ((char*)client_info->m_auxilary_info));
+ }
+
+ if (found)
+ {
+ int i=0;
+ }
+
+ } else
+ {
+ found = (gameobj->GetProperty(m_touchedpropname) != NULL);
+ }
+ }
+ if (found)
+ {
+ m_bTriggered = true;
+ m_hitObject = gameobj;
+ }
+
+ }
+
+}
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject KX_TouchSensor::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "KX_TouchSensor",
+ sizeof(KX_TouchSensor),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject KX_TouchSensor::Parents[] = {
+ &KX_TouchSensor::Type,
+ &SCA_ISensor::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef KX_TouchSensor::Methods[] = {
+ {"setProperty",
+ (PyCFunction) KX_TouchSensor::sPySetProperty, METH_VARARGS, SetProperty_doc},
+ {"getProperty",
+ (PyCFunction) KX_TouchSensor::sPyGetProperty, METH_VARARGS, GetProperty_doc},
+ {"getHitObject",
+ (PyCFunction) KX_TouchSensor::sPyGetHitObject, METH_VARARGS, GetHitObject_doc},
+ {"getHitObjectList",
+ (PyCFunction) KX_TouchSensor::sPyGetHitObjectList, METH_VARARGS, GetHitObjectList_doc},
+ {NULL,NULL} //Sentinel
+};
+
+PyObject* KX_TouchSensor::_getattr(char* attr) {
+ _getattr_up(SCA_ISensor);
+}
+
+/* Python API */
+
+/* 1. setProperty */
+char KX_TouchSensor::SetProperty_doc[] =
+"setProperty(name)\n"
+"\t- name: string\n"
+"\tSet the property or material to collide with. Use\n"
+"\tsetTouchMaterial() to switch between properties and\n"
+"\tmaterials.";
+PyObject* KX_TouchSensor::PySetProperty(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ char *nameArg;
+ if (!PyArg_ParseTuple(args, "s", &nameArg)) {
+ return NULL;
+ }
+
+ CValue* prop = GetParent()->FindIdentifier(nameArg);
+
+ if (!prop->IsError()) {
+ m_touchedpropname = nameArg;
+ prop->Release();
+ } else {
+ ; /* not found ... */
+ }
+
+ Py_Return;
+}
+/* 2. getProperty */
+char KX_TouchSensor::GetProperty_doc[] =
+"getProperty(name)\n"
+"\tReturns the property or material to collide with. Use\n"
+"\tgetTouchMaterial() to find out whether this sensor\n"
+"\tlooks for properties or materials.";
+PyObject* KX_TouchSensor::PyGetProperty(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ return PyString_FromString(m_touchedpropname);
+}
+
+char KX_TouchSensor::GetHitObject_doc[] =
+"getHitObject()\n"
+;
+PyObject* KX_TouchSensor::PyGetHitObject(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ /* to do: do Py_IncRef if the object is already known in Python */
+ /* otherwise, this leaks memory */
+ if (m_hitObject)
+ {
+ return m_hitObject->AddRef();
+ }
+ Py_Return;
+}
+
+char KX_TouchSensor::GetHitObjectList_doc[] =
+"getHitObjectList()\n"
+"\tReturn a list of the objects this object collided with,\n"
+"\tbut only those matching the property/material condition.\n";
+PyObject* KX_TouchSensor::PyGetHitObjectList(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+
+ /* to do: do Py_IncRef if the object is already known in Python */
+ /* otherwise, this leaks memory */
+
+ if ( m_touchedpropname.IsEmpty() ) {
+ return m_colliders->AddRef();
+ } else {
+ CListValue* newList = new CListValue();
+ int i = 0;
+ while (i < m_colliders->GetCount()) {
+ if (m_bFindMaterial) {
+ /* need to associate the CValues from the list to material
+ * names. The collider list _should_ contains only
+ * KX_GameObjects. I am loathe to cast them, though... The
+ * material name must be retrieved from Sumo. To a Sumo
+ * object, a client-info block is attached. This block
+ * contains the material name.
+ * - this also doesn't work (obviously) for multi-materials...
+ */
+ KX_GameObject* gameob = (KX_GameObject*) m_colliders->GetValue(i);
+ SM_Object* smob = (SM_Object*) gameob->GetSumoObject();
+
+ if (smob) {
+ SM_ClientObjectInfo* cl_inf = (SM_ClientObjectInfo*) smob->getClientObject();
+
+ if (m_touchedpropname == ((char*)cl_inf->m_auxilary_info)) {
+ newList->Add(m_colliders->GetValue(i)->AddRef());
+ }
+ }
+
+ } else {
+ CValue* val = m_colliders->GetValue(i)->FindIdentifier(m_touchedpropname);
+ if (!val->IsError()) {
+ newList->Add(m_colliders->GetValue(i)->AddRef());
+ val->Release();
+ }
+ }
+
+ i++;
+ }
+ return newList->AddRef();
+ }
+
+}
+
+/* 5. getTouchMaterial */
+char KX_TouchSensor::GetTouchMaterial_doc[] =
+"getTouchMaterial()\n"
+"\tReturns KX_TRUE if this sensor looks for a specific material,\n"
+"\tKX_FALSE if it looks for a specific property.\n" ;
+PyObject* KX_TouchSensor::PyGetTouchMaterial(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ int retval = 0;
+
+ if (m_bFindMaterial) {
+ retval = KX_TRUE;
+ } else {
+ retval = KX_FALSE;
+ }
+
+ return PyInt_FromLong(retval);
+}
+
+/* 6. setTouchMaterial */
+char KX_TouchSensor::SetTouchMaterial_doc[] =
+"setTouchMaterial(flag)\n"
+"\t- flag: KX_TRUE or KX_FALSE.\n"
+"\tSet flag to KX_TRUE to switch on positive pulse mode,\n"
+"\tKX_FALSE to switch off positive pulse mode.\n" ;
+PyObject* KX_TouchSensor::PySetTouchMaterial(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ int pulseArg = 0;
+
+ if(!PyArg_ParseTuple(args, "i", &pulseArg)) {
+ return NULL;
+ }
+
+ if (pulseArg == KX_TRUE) {
+ m_bFindMaterial = true;
+ } else if (pulseArg == KX_FALSE){
+ m_bFindMaterial = false;
+ } else {
+ ; /* internal error */
+ }
+
+ Py_Return;
+}
+
+#endif //#ifdef PHYSICS_NOT_YET
+
+/* eof */