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_SCA_AddObjectActuator.cpp')
-rw-r--r--source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp243
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;
}