diff options
author | Hans Lambermont <hans@lambermont.dyndns.org> | 2002-10-12 15:37:38 +0400 |
---|---|---|
committer | Hans Lambermont <hans@lambermont.dyndns.org> | 2002-10-12 15:37:38 +0400 |
commit | 12315f4d0e0ae993805f141f64cb8c73c5297311 (patch) | |
tree | 59b45827cd8293cfb727758989c7a74b40183974 /source/gameengine/Ketsji/KX_TouchSensor.cpp |
Initial revisionv2.25
Diffstat (limited to 'source/gameengine/Ketsji/KX_TouchSensor.cpp')
-rw-r--r-- | source/gameengine/Ketsji/KX_TouchSensor.cpp | 393 |
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 */ |