diff options
Diffstat (limited to 'source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp')
-rw-r--r-- | source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp | 243 |
1 files changed, 156 insertions, 87 deletions
diff --git a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp index b31fe16d05d..5777f54b799 100644 --- a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp +++ b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp @@ -39,6 +39,8 @@ #include "KX_GameObject.h" #include "KX_IPhysicsController.h" +#include "PyObjectPlus.h" + #ifdef HAVE_CONFIG_H #include <config.h> #endif @@ -48,19 +50,28 @@ /* ------------------------------------------------------------------------- */ KX_SCA_AddObjectActuator::KX_SCA_AddObjectActuator(SCA_IObject *gameobj, - CValue* original, + SCA_IObject *original, int time, SCA_IScene* scene, const MT_Vector3& linvel, - bool local, + bool linv_local, + const MT_Vector3& angvel, + bool angv_local, PyTypeObject* T) : SCA_IActuator(gameobj, T), m_OriginalObject(original), m_scene(scene), + m_linear_velocity(linvel), - m_localFlag(local) + m_localLinvFlag(linv_local), + + m_angular_velocity(angvel), + m_localAngvFlag(angv_local) { + if (m_OriginalObject) + m_OriginalObject->RegisterActuator(this); + m_lastCreatedObject = NULL; m_timeProp = time; } @@ -69,6 +80,8 @@ KX_SCA_AddObjectActuator::KX_SCA_AddObjectActuator(SCA_IObject *gameobj, KX_SCA_AddObjectActuator::~KX_SCA_AddObjectActuator() { + if (m_OriginalObject) + m_OriginalObject->UnregisterActuator(this); if (m_lastCreatedObject) m_lastCreatedObject->Release(); } @@ -108,12 +121,40 @@ CValue* KX_SCA_AddObjectActuator::GetReplica() // this will copy properties and so on... replica->ProcessReplica(); - replica->m_lastCreatedObject=NULL; CValue::AddDataToReplica(replica); return replica; } +void KX_SCA_AddObjectActuator::ProcessReplica() +{ + if (m_OriginalObject) + m_OriginalObject->RegisterActuator(this); + m_lastCreatedObject=NULL; + SCA_IActuator::ProcessReplica(); +} + +bool KX_SCA_AddObjectActuator::UnlinkObject(SCA_IObject* clientobj) +{ + if (clientobj == m_OriginalObject) + { + // this object is being deleted, we cannot continue to track it. + m_OriginalObject = NULL; + return true; + } + return false; +} + +void KX_SCA_AddObjectActuator::Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map) +{ + void **h_obj = (*obj_map)[m_OriginalObject]; + if (h_obj) { + if (m_OriginalObject) + m_OriginalObject->UnregisterActuator(this); + m_OriginalObject = (SCA_IObject*)(*h_obj); + m_OriginalObject->RegisterActuator(this); + } +} /* ------------------------------------------------------------------------- */ @@ -147,14 +188,16 @@ PyParentObject KX_SCA_AddObjectActuator::Parents[] = { NULL }; PyMethodDef KX_SCA_AddObjectActuator::Methods[] = { - {"setObject", (PyCFunction) KX_SCA_AddObjectActuator::sPySetObject, METH_VARARGS, SetObject_doc}, - {"setTime", (PyCFunction) KX_SCA_AddObjectActuator::sPySetTime, METH_VARARGS, SetTime_doc}, - {"getObject", (PyCFunction) KX_SCA_AddObjectActuator::sPyGetObject, METH_VARARGS, GetObject_doc}, - {"getTime", (PyCFunction) KX_SCA_AddObjectActuator::sPyGetTime, METH_VARARGS, GetTime_doc}, - {"getLinearVelocity", (PyCFunction) KX_SCA_AddObjectActuator::sPyGetLinearVelocity, METH_VARARGS, GetLinearVelocity_doc}, - {"setLinearVelocity", (PyCFunction) KX_SCA_AddObjectActuator::sPySetLinearVelocity, METH_VARARGS, SetLinearVelocity_doc}, - {"getLastCreatedObject", (PyCFunction) KX_SCA_AddObjectActuator::sPyGetLastCreatedObject, METH_VARARGS,"getLastCreatedObject() : get the object handle to the last created object\n"}, - {"instantAddObject", (PyCFunction) KX_SCA_AddObjectActuator::sPyInstantAddObject, METH_VARARGS,"instantAddObject() : immediately add object without delay\n"}, + {"setObject", (PyCFunction) KX_SCA_AddObjectActuator::sPySetObject, METH_O, (PY_METHODCHAR)SetObject_doc}, + {"setTime", (PyCFunction) KX_SCA_AddObjectActuator::sPySetTime, METH_O, (PY_METHODCHAR)SetTime_doc}, + {"getObject", (PyCFunction) KX_SCA_AddObjectActuator::sPyGetObject, METH_VARARGS, (PY_METHODCHAR)GetObject_doc}, + {"getTime", (PyCFunction) KX_SCA_AddObjectActuator::sPyGetTime, METH_NOARGS, (PY_METHODCHAR)GetTime_doc}, + {"getLinearVelocity", (PyCFunction) KX_SCA_AddObjectActuator::sPyGetLinearVelocity, METH_NOARGS, (PY_METHODCHAR)GetLinearVelocity_doc}, + {"setLinearVelocity", (PyCFunction) KX_SCA_AddObjectActuator::sPySetLinearVelocity, METH_VARARGS, (PY_METHODCHAR)SetLinearVelocity_doc}, + {"getAngularVelocity", (PyCFunction) KX_SCA_AddObjectActuator::sPyGetAngularVelocity, METH_NOARGS, (PY_METHODCHAR)GetAngularVelocity_doc}, + {"setAngularVelocity", (PyCFunction) KX_SCA_AddObjectActuator::sPySetAngularVelocity, METH_VARARGS, (PY_METHODCHAR)SetAngularVelocity_doc}, + {"getLastCreatedObject", (PyCFunction) KX_SCA_AddObjectActuator::sPyGetLastCreatedObject, METH_NOARGS,"getLastCreatedObject() : get the object handle to the last created object\n"}, + {"instantAddObject", (PyCFunction) KX_SCA_AddObjectActuator::sPyInstantAddObject, METH_NOARGS,"instantAddObject() : immediately add object without delay\n"}, {NULL,NULL} //Sentinel }; @@ -166,114 +209,101 @@ PyObject* KX_SCA_AddObjectActuator::_getattr(const STR_String& attr) } /* 1. setObject */ -char KX_SCA_AddObjectActuator::SetObject_doc[] = -"setObject(name)\n" -"\t- name: string\n" +const char KX_SCA_AddObjectActuator::SetObject_doc[] = +"setObject(object)\n" +"\t- object: KX_GameObject, string or None\n" "\tSets the object that will be added. There has to be an object\n" "\tof this name. If not, this function does nothing.\n"; - - - -PyObject* KX_SCA_AddObjectActuator::PySetObject(PyObject* self, - PyObject* args, - PyObject* kwds) -{ - PyObject* gameobj; - if (PyArg_ParseTuple(args, "O!", &KX_GameObject::Type, &gameobj)) - { - m_OriginalObject = (CValue*)gameobj; - Py_Return; - } - PyErr_Clear(); +PyObject* KX_SCA_AddObjectActuator::PySetObject(PyObject* self, PyObject* value) +{ + KX_GameObject *gameobj; - char* objectname; - if (PyArg_ParseTuple(args, "s", &objectname)) - { - m_OriginalObject= (CValue*)SCA_ILogicBrick::m_sCurrentLogicManager->GetGameObjectByName(STR_String(objectname));; - - Py_Return; - } + if (!ConvertPythonToGameObject(value, &gameobj, true)) + return NULL; // ConvertPythonToGameObject sets the error + + if (m_OriginalObject != NULL) + m_OriginalObject->UnregisterActuator(this); + + m_OriginalObject = (SCA_IObject*)gameobj; + if (m_OriginalObject) + m_OriginalObject->RegisterActuator(this); - return NULL; + Py_RETURN_NONE; } /* 2. setTime */ -char KX_SCA_AddObjectActuator::SetTime_doc[] = +const char KX_SCA_AddObjectActuator::SetTime_doc[] = "setTime(duration)\n" "\t- duration: integer\n" "\tSets the lifetime of the object that will be added, in frames. \n" "\tIf the duration is negative, it is set to 0.\n"; -PyObject* KX_SCA_AddObjectActuator::PySetTime(PyObject* self, - PyObject* args, - PyObject* kwds) +PyObject* KX_SCA_AddObjectActuator::PySetTime(PyObject* self, PyObject* value) { - int deltatime; - - if (!PyArg_ParseTuple(args, "i", &deltatime)) + int deltatime = PyInt_AsLong(value); + if (deltatime==-1 && PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, "expected an int"); return NULL; + } m_timeProp = deltatime; if (m_timeProp < 0) m_timeProp = 0; - Py_Return; + Py_RETURN_NONE; } /* 3. getTime */ -char KX_SCA_AddObjectActuator::GetTime_doc[] = +const char KX_SCA_AddObjectActuator::GetTime_doc[] = "GetTime()\n" "\tReturns the lifetime of the object that will be added.\n"; -PyObject* KX_SCA_AddObjectActuator::PyGetTime(PyObject* self, - PyObject* args, - PyObject* kwds) +PyObject* KX_SCA_AddObjectActuator::PyGetTime(PyObject* self) { return PyInt_FromLong(m_timeProp); } /* 4. getObject */ -char KX_SCA_AddObjectActuator::GetObject_doc[] = -"getObject()\n" +const char KX_SCA_AddObjectActuator::GetObject_doc[] = +"getObject(name_only = 1)\n" +"name_only - optional arg, when true will return the KX_GameObject rather then its name\n" "\tReturns the name of the object that will be added.\n"; - - - -PyObject* KX_SCA_AddObjectActuator::PyGetObject(PyObject* self, - PyObject* args, - PyObject* kwds) +PyObject* KX_SCA_AddObjectActuator::PyGetObject(PyObject* self, PyObject* args) { + int ret_name_only = 1; + if (!PyArg_ParseTuple(args, "|i", &ret_name_only)) + return NULL; + if (!m_OriginalObject) - Py_Return; - - return PyString_FromString(m_OriginalObject->GetName()); + Py_RETURN_NONE; + + if (ret_name_only) + return PyString_FromString(m_OriginalObject->GetName()); + else + return m_OriginalObject->AddRef(); } /* 5. getLinearVelocity */ -char KX_SCA_AddObjectActuator::GetLinearVelocity_doc[] = +const char KX_SCA_AddObjectActuator::GetLinearVelocity_doc[] = "GetLinearVelocity()\n" "\tReturns the linear velocity that will be assigned to \n" "\tthe created object.\n"; - - -PyObject* KX_SCA_AddObjectActuator::PyGetLinearVelocity(PyObject* self, - PyObject* args, - PyObject* kwds) +PyObject* KX_SCA_AddObjectActuator::PyGetLinearVelocity(PyObject* self) { PyObject *retVal = PyList_New(3); - PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_linear_velocity[0])); - PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_linear_velocity[1])); - PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_linear_velocity[2])); + PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_linear_velocity[0])); + PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_linear_velocity[1])); + PyList_SET_ITEM(retVal, 2, PyFloat_FromDouble(m_linear_velocity[2])); return retVal; } @@ -281,17 +311,15 @@ PyObject* KX_SCA_AddObjectActuator::PyGetLinearVelocity(PyObject* self, /* 6. setLinearVelocity */ -char KX_SCA_AddObjectActuator::SetLinearVelocity_doc[] = +const char KX_SCA_AddObjectActuator::SetLinearVelocity_doc[] = "setLinearVelocity(vx, vy, vz)\n" "\t- vx: float\n" "\t- vy: float\n" "\t- vz: float\n" +"\t- local: bool\n" "\tAssign this velocity to the created object. \n"; - -PyObject* KX_SCA_AddObjectActuator::PySetLinearVelocity(PyObject* self, - PyObject* args, - PyObject* kwds) +PyObject* KX_SCA_AddObjectActuator::PySetLinearVelocity(PyObject* self, PyObject* args) { float vecArg[3]; @@ -299,7 +327,46 @@ PyObject* KX_SCA_AddObjectActuator::PySetLinearVelocity(PyObject* self, return NULL; m_linear_velocity.setValue(vecArg); - Py_Return; + Py_RETURN_NONE; +} + +/* 7. getAngularVelocity */ +const char KX_SCA_AddObjectActuator::GetAngularVelocity_doc[] = +"GetAngularVelocity()\n" +"\tReturns the angular velocity that will be assigned to \n" +"\tthe created object.\n"; + +PyObject* KX_SCA_AddObjectActuator::PyGetAngularVelocity(PyObject* self) +{ + PyObject *retVal = PyList_New(3); + + PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_angular_velocity[0])); + PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_angular_velocity[1])); + PyList_SET_ITEM(retVal, 2, PyFloat_FromDouble(m_angular_velocity[2])); + + return retVal; +} + + + +/* 8. setAngularVelocity */ +const char KX_SCA_AddObjectActuator::SetAngularVelocity_doc[] = +"setAngularVelocity(vx, vy, vz)\n" +"\t- vx: float\n" +"\t- vy: float\n" +"\t- vz: float\n" +"\t- local: bool\n" +"\tAssign this angular velocity to the created object. \n"; + +PyObject* KX_SCA_AddObjectActuator::PySetAngularVelocity(PyObject* self, PyObject* args) +{ + + float vecArg[3]; + if (!PyArg_ParseTuple(args, "fff", &vecArg[0], &vecArg[1], &vecArg[2])) + return NULL; + + m_angular_velocity.setValue(vecArg); + Py_RETURN_NONE; } void KX_SCA_AddObjectActuator::InstantAddObject() @@ -310,8 +377,9 @@ void KX_SCA_AddObjectActuator::InstantAddObject() // Now it needs to be added to the current scene. SCA_IObject* replica = m_scene->AddReplicaObject(m_OriginalObject,GetParent(),m_timeProp ); KX_GameObject * game_obj = static_cast<KX_GameObject *>(replica); - game_obj->setLinearVelocity(m_linear_velocity,m_localFlag); - game_obj->ResolveCombinedVelocities(m_linear_velocity, MT_Vector3(0., 0., 0.), m_localFlag, false); + game_obj->setLinearVelocity(m_linear_velocity,m_localLinvFlag); + game_obj->setAngularVelocity(m_angular_velocity,m_localAngvFlag); + game_obj->ResolveCombinedVelocities(m_linear_velocity, m_angular_velocity, m_localLinvFlag, m_localAngvFlag); // keep a copy of the last object, to allow python scripters to change it if (m_lastCreatedObject) @@ -323,36 +391,37 @@ void KX_SCA_AddObjectActuator::InstantAddObject() m_lastCreatedObject = replica; m_lastCreatedObject->AddRef(); + // finished using replica? then release it + replica->Release(); } } -PyObject* KX_SCA_AddObjectActuator::PyInstantAddObject(PyObject* self, - PyObject* args, - PyObject* kwds) +PyObject* KX_SCA_AddObjectActuator::PyInstantAddObject(PyObject* self) { InstantAddObject(); - Py_Return; + Py_RETURN_NONE; } /* 7. GetLastCreatedObject */ -char KX_SCA_AddObjectActuator::GetLastCreatedObject_doc[] = +const char KX_SCA_AddObjectActuator::GetLastCreatedObject_doc[] = "getLastCreatedObject()\n" "\tReturn the last created object. \n"; -PyObject* KX_SCA_AddObjectActuator::PyGetLastCreatedObject(PyObject* self, - PyObject* args, - PyObject* kwds) +PyObject* KX_SCA_AddObjectActuator::PyGetLastCreatedObject(PyObject* self) { SCA_IObject* result = this->GetLastCreatedObject(); - if (result) + + // if result->GetSGNode() is NULL + // it means the object has ended, The BGE python api crashes in many places if the object is returned. + if (result && (static_cast<KX_GameObject *>(result))->GetSGNode()) { result->AddRef(); return result; } // don't return NULL to python anymore, it gives trouble in the scripts - Py_Return; + Py_RETURN_NONE; } |