diff options
author | Campbell Barton <ideasman42@gmail.com> | 2009-04-20 13:13:59 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2009-04-20 13:13:59 +0400 |
commit | dee32d0b3f409007f5a392668068b92c3810026a (patch) | |
tree | 3127ac9c88ea9d783282d3bf8ed5ba8f2a40eb43 | |
parent | 9078ce5da209bcfd31c60b55118076359ce7244f (diff) |
BGE Python API
- initialize pythons sys.argv in the blenderplayer
- ignore all arguments after a single " - " in the blenderplayer (like in blender), so args can be passed to the game.
- add a utility function PyOrientationTo() - to take a Py euler, quat or 3x3 matrix and convert into a C++ MT_Matrix3x3.
- add utility function ConvertPythonToMesh to get a RAS_MeshObject from a KX_MeshProxy or a name.
- Added error prefix arguments to ConvertPythonToGameObject, ConvertPythonToMesh and PyOrientationTo so the error messages can include what function they came from.
- deprecated brick.getOwner() for the "owner" attribute.
23 files changed, 215 insertions, 171 deletions
diff --git a/source/gameengine/GameLogic/SCA_ILogicBrick.cpp b/source/gameengine/GameLogic/SCA_ILogicBrick.cpp index b3045402c2c..3cd750ff63b 100644 --- a/source/gameengine/GameLogic/SCA_ILogicBrick.cpp +++ b/source/gameengine/GameLogic/SCA_ILogicBrick.cpp @@ -246,8 +246,8 @@ PyParentObject SCA_ILogicBrick::Parents[] = { PyMethodDef SCA_ILogicBrick::Methods[] = { + // --> Deprecated {"getOwner", (PyCFunction) SCA_ILogicBrick::sPyGetOwner, METH_NOARGS}, - // --> Deprecated {"getExecutePriority", (PyCFunction) SCA_ILogicBrick::sPyGetExecutePriority, METH_NOARGS}, {"setExecutePriority", (PyCFunction) SCA_ILogicBrick::sPySetExecutePriority, METH_VARARGS}, // <-- Deprecated @@ -255,6 +255,7 @@ PyMethodDef SCA_ILogicBrick::Methods[] = { }; PyAttributeDef SCA_ILogicBrick::Attributes[] = { + KX_PYATTRIBUTE_RO_FUNCTION("owner", SCA_ILogicBrick, pyattr_get_owner), KX_PYATTRIBUTE_INT_RW("executePriority",0,100000,false,SCA_ILogicBrick,m_Execute_Ueber_Priority), {NULL} //Sentinel }; @@ -291,6 +292,8 @@ int SCA_ILogicBrick::py_setattro(PyObject *attr, PyObject *value) PyObject* SCA_ILogicBrick::PyGetOwner() { + ShowDeprecationWarning("getOwner()", "the owner property"); + CValue* parent = GetParent(); if (parent) { @@ -327,6 +330,19 @@ PyObject* SCA_ILogicBrick::PyGetExecutePriority() } +/*Attribute functions */ +PyObject* SCA_ILogicBrick::pyattr_get_owner(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + SCA_ILogicBrick* self= static_cast<SCA_ILogicBrick*>(self_v); + CValue* parent = self->GetParent(); + + if (parent) + return parent->GetProxy(); + + Py_RETURN_NONE; +} + + /* Conversions for making life better. */ bool SCA_ILogicBrick::PyArgToBool(int boolArg) @@ -338,8 +354,6 @@ bool SCA_ILogicBrick::PyArgToBool(int boolArg) } } - - PyObject* SCA_ILogicBrick::BoolToPyArg(bool boolarg) { return PyInt_FromLong(boolarg? KX_TRUE: KX_FALSE); diff --git a/source/gameengine/GameLogic/SCA_ILogicBrick.h b/source/gameengine/GameLogic/SCA_ILogicBrick.h index c0ff0fd633f..e59d05ea051 100644 --- a/source/gameengine/GameLogic/SCA_ILogicBrick.h +++ b/source/gameengine/GameLogic/SCA_ILogicBrick.h @@ -90,6 +90,8 @@ public: KX_PYMETHOD_NOARGS(SCA_ILogicBrick,GetOwner); KX_PYMETHOD_VARARGS(SCA_ILogicBrick,SetExecutePriority); KX_PYMETHOD_NOARGS(SCA_ILogicBrick,GetExecutePriority); + + static PyObject* pyattr_get_owner(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); // check that attribute is a property static int CheckProperty(void *self, const PyAttributeDef *attrdef); diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp index 0ecbbea3af6..907ba99e63b 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp @@ -151,7 +151,7 @@ GPG_Application::~GPG_Application(void) -bool GPG_Application::SetGameEngineData(struct Main* maggie, Scene *scene) +bool GPG_Application::SetGameEngineData(struct Main* maggie, Scene *scene, int argc, char **argv) { bool result = false; @@ -163,6 +163,10 @@ bool GPG_Application::SetGameEngineData(struct Main* maggie, Scene *scene) m_startScene = scene; result = true; } + + /* Python needs these */ + m_argc= argc; + m_argv= argv; return result; } @@ -681,7 +685,7 @@ bool GPG_Application::startEngine(void) // some python things - PyObject* dictionaryobject = initGamePlayerPythonScripting("Ketsji", psl_Lowest, m_maggie); + PyObject* dictionaryobject = initGamePlayerPythonScripting("Ketsji", psl_Lowest, m_maggie, m_argc, m_argv); m_ketsjiengine->SetPythonDictionary(dictionaryobject); initRasterizer(m_rasterizer, m_canvas); PyObject *gameLogic = initGameLogic(m_ketsjiengine, startscene); diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.h b/source/gameengine/GamePlayer/ghost/GPG_Application.h index 38408f919b4..845686f5770 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_Application.h +++ b/source/gameengine/GamePlayer/ghost/GPG_Application.h @@ -58,7 +58,7 @@ public: GPG_Application(GHOST_ISystem* system); ~GPG_Application(void); - bool SetGameEngineData(struct Main* maggie, struct Scene* scene); + bool SetGameEngineData(struct Main* maggie, struct Scene* scene, int argc, char** argv); bool startWindow(STR_String& title, int windowLeft, int windowTop, int windowWidth, int windowHeight, const bool stereoVisual, const int stereoMode); bool startFullScreen(int width, int height, int bpp, int frequency, const bool stereoVisual, const int stereoMode); @@ -154,5 +154,9 @@ protected: */ char* m_pyGlobalDictString; int m_pyGlobalDictString_Length; + + /* argc and argv need to be passed on to python */ + int m_argc; + char** m_argv; }; diff --git a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp index a41446ad88c..64e70ce37c3 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp @@ -206,6 +206,8 @@ void usage(const char* program) printf(" blender_material 0 Enable material settings\n"); printf(" ignore_deprecation_warnings 1 Ignore deprecation warnings\n"); printf("\n"); + printf(" - : all arguments after this are ignored, allowing python to access them from sys.argv\n"); + printf("\n"); printf("example: %s -w 320 200 10 10 -g noaudio c:\\loadtest.blend\n", program); printf("example: %s -g show_framerate = 0 c:\\loadtest.blend\n", program); } @@ -293,6 +295,7 @@ static BlendFileData *load_game_data(char *progname, char *filename = NULL, char int main(int argc, char** argv) { int i; + int argc_py_clamped= argc; /* use this so python args can be added after ' - ' */ bool error = false; SYS_SystemHandle syshandle = SYS_GetSystem(); bool fullScreen = false; @@ -393,6 +396,12 @@ int main(int argc, char** argv) #endif if (argv[i][0] == '-') { + /* ignore all args after " - ", allow python to have own args */ + if (argv[i][1]=='\0') { + argc_py_clamped= i; + break; + } + switch (argv[i][1]) { case 'g': @@ -596,7 +605,7 @@ int main(int argc, char** argv) char pathname[FILE_MAXDIR + FILE_MAXFILE]; char *titlename; - get_filename(argc, argv, filename); + get_filename(argc_py_clamped, argv, filename); if(filename[0]) BLI_convertstringcwd(filename); @@ -691,7 +700,7 @@ int main(int argc, char** argv) } // GPG_Application app (system, maggie, startscenename); - app.SetGameEngineData(maggie, scene); + app.SetGameEngineData(maggie, scene, argc, argv); /* this argc cant be argc_py_clamped, since python uses it */ BLI_strncpy(pathname, maggie->name, sizeof(pathname)); BLI_strncpy(G.sce, maggie->name, sizeof(G.sce)); diff --git a/source/gameengine/Ketsji/KX_CameraActuator.cpp b/source/gameengine/Ketsji/KX_CameraActuator.cpp index 6cc48856a94..355cdbb6263 100644 --- a/source/gameengine/Ketsji/KX_CameraActuator.cpp +++ b/source/gameengine/Ketsji/KX_CameraActuator.cpp @@ -462,7 +462,7 @@ PyObject* KX_CameraActuator::PySetObject(PyObject* value) ShowDeprecationWarning("setObject()", "the object property"); - if (!ConvertPythonToGameObject(value, &gameobj, true)) + if (!ConvertPythonToGameObject(value, &gameobj, true, "actuator.setObject(value): KX_CameraActuator")) return NULL; // ConvertPythonToGameObject sets the error if (m_ob != NULL) @@ -589,7 +589,7 @@ int KX_CameraActuator::pyattr_set_object(void *self_v, const KX_PYATTRIBUTE_DEF KX_CameraActuator* self= static_cast<KX_CameraActuator*>(self_v); KX_GameObject *gameobj; - if (!ConvertPythonToGameObject(value, &gameobj, true)) + if (!ConvertPythonToGameObject(value, &gameobj, true, "actuator.object = value: KX_CameraActuator")) return 1; // ConvertPythonToGameObject sets the error if (self->m_ob) diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index af1dc7f67b2..bea0fcff2af 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -1182,22 +1182,12 @@ bool KX_GameObject::ConvertPythonVectorArgs(PyObject* args, PyObject* KX_GameObject::PyReplaceMesh(PyObject* value) { KX_Scene *scene = KX_GetActiveScene(); - char* meshname; - void* mesh_pt; - - meshname = PyString_AsString(value); - if (meshname==NULL) { - PyErr_SetString(PyExc_ValueError, "gameOb.replaceMesh(value): KX_GameObject, expected a mesh name"); - return NULL; - } - mesh_pt = SCA_ILogicBrick::m_sCurrentLogicManager->GetMeshByName(STR_String(meshname)); + RAS_MeshObject* new_mesh; - if (mesh_pt==NULL) { - PyErr_SetString(PyExc_ValueError, "gameOb.replaceMesh(value): KX_GameObject, the mesh name given does not exist"); + if (!ConvertPythonToMesh(value, &new_mesh, false, "gameOb.replaceMesh(value): KX_GameObject")) return NULL; - } - scene->ReplaceMesh(this, (class RAS_MeshObject*)mesh_pt); + scene->ReplaceMesh(this, new_mesh); Py_RETURN_NONE; } @@ -1568,49 +1558,15 @@ PyObject* KX_GameObject::pyattr_get_localOrientation(void *self_v, const KX_PYAT int KX_GameObject::pyattr_set_localOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) { KX_GameObject* self= static_cast<KX_GameObject*>(self_v); - if (!PySequence_Check(value)) { - PyErr_SetString(PyExc_AttributeError, "gameOb.orientation = [...]: KX_GameObject, expected a sequence"); - return 1; - } - + + /* if value is not a sequence PyOrientationTo makes an error */ MT_Matrix3x3 rot; + if (!PyOrientationTo(value, rot, "gameOb.orientation = sequence: KX_GameObject, ")) + return NULL; - if (PyMatTo(value, rot)) - { - self->NodeSetLocalOrientation(rot); - self->NodeUpdateGS(0.f); - return 0; - } - PyErr_Clear(); - - if (PySequence_Size(value) == 4) - { - MT_Quaternion qrot; - if (PyVecTo(value, qrot)) - { - rot.setRotation(qrot); - self->NodeSetLocalOrientation(rot); - self->NodeUpdateGS(0.f); - return 0; - } - return 1; - } - - if (PySequence_Size(value) == 3) - { - MT_Vector3 erot; - if (PyVecTo(value, erot)) - { - rot.setEuler(erot); - self->NodeSetLocalOrientation(rot); - self->NodeUpdateGS(0.f); - return 0; - } - return 1; - } - - PyErr_SetString(PyExc_AttributeError, "gameOb.orientation = [...]: KX_GameObject, could not set the orientation from a 3x3 matrix, quaternion or euler sequence"); - return 1; + self->NodeSetLocalOrientation(rot); + self->NodeUpdateGS(0.f); + return 0; } PyObject* KX_GameObject::pyattr_get_worldScaling(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) @@ -2127,7 +2083,7 @@ PyObject* KX_GameObject::PyGetParent() PyObject* KX_GameObject::PySetParent(PyObject* value) { KX_GameObject *obj; - if (!ConvertPythonToGameObject(value, &obj, false)) + if (!ConvertPythonToGameObject(value, &obj, false, "gameOb.setParent(value): KX_GameObject")) return NULL; this->SetParent(KX_GetActiveScene(), obj); @@ -2362,7 +2318,7 @@ KX_PYMETHODDEF_DOC_O(KX_GameObject, getDistanceTo, PyErr_Clear(); KX_GameObject *other; - if (ConvertPythonToGameObject(value, &other, false)) + if (ConvertPythonToGameObject(value, &other, false, "gameOb.getDistanceTo(value): KX_GameObject")) { return PyFloat_FromDouble(NodeGetWorldPosition().distance(other->NodeGetWorldPosition())); } @@ -2385,7 +2341,7 @@ KX_PYMETHODDEF_DOC_O(KX_GameObject, getVectTo, PyErr_Clear(); KX_GameObject *other; - if (ConvertPythonToGameObject(value, &other, false)) + if (ConvertPythonToGameObject(value, &other, false, "")) /* error will be overwritten */ { toPoint = other->NodeGetWorldPosition(); } else @@ -2479,7 +2435,7 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCastTo, KX_GameObject *other; PyErr_Clear(); - if (ConvertPythonToGameObject(pyarg, &other, false)) + if (ConvertPythonToGameObject(pyarg, &other, false, "")) /* error will be overwritten */ { toPoint = other->NodeGetWorldPosition(); } else @@ -2555,7 +2511,7 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCast, { PyErr_Clear(); - if (ConvertPythonToGameObject(pyto, &other, false)) + if (ConvertPythonToGameObject(pyto, &other, false, "")) /* error will be overwritten */ { toPoint = other->NodeGetWorldPosition(); } else @@ -2572,7 +2528,7 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCast, { PyErr_Clear(); - if (ConvertPythonToGameObject(pyfrom, &other, false)) + if (ConvertPythonToGameObject(pyfrom, &other, false, "")) /* error will be overwritten */ { fromPoint = other->NodeGetWorldPosition(); } else @@ -2685,10 +2641,10 @@ void KX_GameObject::Relink(GEN_Map<GEN_HashedPtr, void*> *map_parameter) } } -bool ConvertPythonToGameObject(PyObject * value, KX_GameObject **object, bool py_none_ok) +bool ConvertPythonToGameObject(PyObject * value, KX_GameObject **object, bool py_none_ok, const char *error_prefix) { if (value==NULL) { - PyErr_SetString(PyExc_TypeError, "Error in ConvertPythonToGameObject, python pointer NULL, should never happen"); + PyErr_Format(PyExc_TypeError, "%s, python pointer NULL, should never happen", error_prefix); *object = NULL; return false; } @@ -2699,7 +2655,7 @@ bool ConvertPythonToGameObject(PyObject * value, KX_GameObject **object, bool py if (py_none_ok) { return true; } else { - PyErr_SetString(PyExc_TypeError, "Expected KX_GameObject or a string for a name of a KX_GameObject, None is invalid"); + PyErr_Format(PyExc_TypeError, "%s, expected KX_GameObject or a KX_GameObject name, None is invalid", error_prefix); return false; } } @@ -2710,7 +2666,7 @@ bool ConvertPythonToGameObject(PyObject * value, KX_GameObject **object, bool py if (*object) { return true; } else { - PyErr_SetString(PyExc_ValueError, "Requested name did not match any KX_GameObject"); + PyErr_Format(PyExc_ValueError, "%s, requested name \"%s\" did not match any KX_GameObject in this scene", error_prefix, PyString_AsString(value)); return false; } } @@ -2720,7 +2676,7 @@ bool ConvertPythonToGameObject(PyObject * value, KX_GameObject **object, bool py /* sets the error */ if (*object==NULL) { - PyErr_SetString(PyExc_RuntimeError, BGE_PROXY_ERROR_MSG); + PyErr_Format(PyExc_RuntimeError, "%s, " BGE_PROXY_ERROR_MSG, error_prefix); return false; } @@ -2730,9 +2686,9 @@ bool ConvertPythonToGameObject(PyObject * value, KX_GameObject **object, bool py *object = NULL; if (py_none_ok) { - PyErr_SetString(PyExc_TypeError, "Expect a KX_GameObject, a string or None"); + PyErr_Format(PyExc_TypeError, "%s, expect a KX_GameObject, a string or None", error_prefix); } else { - PyErr_SetString(PyExc_TypeError, "Expect a KX_GameObject or a string"); + PyErr_Format(PyExc_TypeError, "%s, expect a KX_GameObject or a string", error_prefix); } return false; diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index 89517bd76ce..ec02dc17b75 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -61,7 +61,7 @@ class PHY_IPhysicsEnvironment; struct Object; /* utility conversion function */ -bool ConvertPythonToGameObject(PyObject * value, KX_GameObject **object, bool py_none_ok); +bool ConvertPythonToGameObject(PyObject * value, KX_GameObject **object, bool py_none_ok, const char *error_prefix); /** * KX_GameObject is the main class for dynamic objects. diff --git a/source/gameengine/Ketsji/KX_MeshProxy.cpp b/source/gameengine/Ketsji/KX_MeshProxy.cpp index e2c59ab4242..6be1da55ff8 100644 --- a/source/gameengine/Ketsji/KX_MeshProxy.cpp +++ b/source/gameengine/Ketsji/KX_MeshProxy.cpp @@ -304,3 +304,58 @@ PyObject * KX_MeshProxy::pyattr_get_numPolygons(void * selfv, const KX_PYATTRIBU KX_MeshProxy * self = static_cast<KX_MeshProxy *> (selfv); return PyInt_FromLong(self->m_meshobj->NumPolygons()); } + +/* a close copy of ConvertPythonToGameObject but for meshes */ +bool ConvertPythonToMesh(PyObject * value, RAS_MeshObject **object, bool py_none_ok, const char *error_prefix) +{ + if (value==NULL) { + PyErr_Format(PyExc_TypeError, "%s, python pointer NULL, should never happen", error_prefix); + *object = NULL; + return false; + } + + if (value==Py_None) { + *object = NULL; + + if (py_none_ok) { + return true; + } else { + PyErr_Format(PyExc_TypeError, "%s, expected KX_MeshProxy or a KX_MeshProxy name, None is invalid", error_prefix); + return false; + } + } + + if (PyString_Check(value)) { + *object = (RAS_MeshObject*)SCA_ILogicBrick::m_sCurrentLogicManager->GetMeshByName(STR_String( PyString_AsString(value) )); + + if (*object) { + return true; + } else { + PyErr_Format(PyExc_ValueError, "%s, requested name \"%s\" did not match any KX_MeshProxy in this scene", error_prefix, PyString_AsString(value)); + return false; + } + } + + if (PyObject_TypeCheck(value, &KX_MeshProxy::Type)) { + KX_MeshProxy *kx_mesh = static_cast<KX_MeshProxy*>BGE_PROXY_REF(value); + + /* sets the error */ + if (*object==NULL) { + PyErr_Format(PyExc_RuntimeError, "%s, " BGE_PROXY_ERROR_MSG, error_prefix); + return false; + } + + *object = kx_mesh->GetMesh(); + return true; + } + + *object = NULL; + + if (py_none_ok) { + PyErr_Format(PyExc_TypeError, "%s, expect a KX_MeshProxy, a string or None", error_prefix); + } else { + PyErr_Format(PyExc_TypeError, "%s, expect a KX_MeshProxy or a string", error_prefix); + } + + return false; +} diff --git a/source/gameengine/Ketsji/KX_MeshProxy.h b/source/gameengine/Ketsji/KX_MeshProxy.h index dfc498801a7..aeecefc09e6 100644 --- a/source/gameengine/Ketsji/KX_MeshProxy.h +++ b/source/gameengine/Ketsji/KX_MeshProxy.h @@ -31,6 +31,9 @@ #include "SCA_IObject.h" +/* utility conversion function */ +bool ConvertPythonToMesh(PyObject * value, class RAS_MeshObject **object, bool py_none_ok, const char *error_prefix); + class KX_MeshProxy : public SCA_IObject { Py_Header; diff --git a/source/gameengine/Ketsji/KX_ParentActuator.cpp b/source/gameengine/Ketsji/KX_ParentActuator.cpp index 69c0a3cd510..0093cf5f313 100644 --- a/source/gameengine/Ketsji/KX_ParentActuator.cpp +++ b/source/gameengine/Ketsji/KX_ParentActuator.cpp @@ -192,7 +192,7 @@ int KX_ParentActuator::pyattr_set_object(void *self, const struct KX_PYATTRIBUTE KX_ParentActuator* actuator = static_cast<KX_ParentActuator*>(self); KX_GameObject *gameobj; - if (!ConvertPythonToGameObject(value, &gameobj, true)) + if (!ConvertPythonToGameObject(value, &gameobj, true, "actuator.object = value: KX_ParentActuator")) return 1; // ConvertPythonToGameObject sets the error if (actuator->m_ob != NULL) @@ -226,7 +226,7 @@ PyObject* KX_ParentActuator::PySetObject(PyObject* value) { ShowDeprecationWarning("setObject()", "the object property"); - if (!ConvertPythonToGameObject(value, &gameobj, true)) + if (!ConvertPythonToGameObject(value, &gameobj, true, "actuator.setObject(value): KX_ParentActuator")) return NULL; // ConvertPythonToGameObject sets the error if (m_ob != NULL) diff --git a/source/gameengine/Ketsji/KX_PyMath.cpp b/source/gameengine/Ketsji/KX_PyMath.cpp index cceb7a12446..0093a72808e 100644 --- a/source/gameengine/Ketsji/KX_PyMath.cpp +++ b/source/gameengine/Ketsji/KX_PyMath.cpp @@ -44,6 +44,7 @@ #include "ListValue.h" #include "KX_Python.h" +#include "KX_PyMath.h" bool PyObject_IsMT_Matrix(PyObject *pymat, unsigned int rank) { @@ -74,6 +75,39 @@ bool PyObject_IsMT_Matrix(PyObject *pymat, unsigned int rank) return false; } +bool PyOrientationTo(PyObject* pyval, MT_Matrix3x3 &mat, const char *error_prefix) +{ + MT_Matrix3x3 rot; + int size= PySequence_Size(pyval); + + if (size == 4) + { + MT_Quaternion qrot; + if (PyVecTo(pyval, qrot)) + { + rot.setRotation(qrot); + return true; + } + } + else if (size == 3) { + /* 3x3 matrix or euler */ + MT_Vector3 erot; + if (PyVecTo(pyval, erot)) + { + rot.setEuler(erot); + return true; + } + PyErr_Clear(); + + if (PyMatTo(pyval, rot)) + { + return true; + } + } + + PyErr_Format(PyExc_TypeError, "%s, could not set the orientation from a 3x3 matrix, quaternion or euler sequence", error_prefix); + return false; +} PyObject* PyObjectFrom(const MT_Matrix4x4 &mat) { diff --git a/source/gameengine/Ketsji/KX_PyMath.h b/source/gameengine/Ketsji/KX_PyMath.h index 4a64063aaa1..00f7c5cad93 100644 --- a/source/gameengine/Ketsji/KX_PyMath.h +++ b/source/gameengine/Ketsji/KX_PyMath.h @@ -145,6 +145,8 @@ bool PyVecTo(PyObject* pyval, T& vec) return false; } +bool PyOrientationTo(PyObject* pyval, MT_Matrix3x3 &mat, const char *error_prefix); + /** * Converts an MT_Matrix4x4 to a python object. */ diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index 097d20fe0e5..9649e50a98b 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -1357,14 +1357,17 @@ void setSandbox(TPythonSecurityLevel level) /** * Python is not initialised. */ -PyObject* initGamePlayerPythonScripting(const STR_String& progname, TPythonSecurityLevel level, Main *maggie) +PyObject* initGamePlayerPythonScripting(const STR_String& progname, TPythonSecurityLevel level, Main *maggie, int argc, char** argv) { STR_String pname = progname; Py_SetProgramName(pname.Ptr()); Py_NoSiteFlag=1; Py_FrozenFlag=1; Py_Initialize(); - + + if(argv) /* browser plugins dont currently set this */ + PySys_SetArgv(argc, argv); + //importBlenderModules() setSandbox(level); diff --git a/source/gameengine/Ketsji/KX_PythonInit.h b/source/gameengine/Ketsji/KX_PythonInit.h index 97d23fe391c..11360197b95 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.h +++ b/source/gameengine/Ketsji/KX_PythonInit.h @@ -43,7 +43,7 @@ extern bool gUseVisibilityTemp; PyObject* initGameLogic(class KX_KetsjiEngine *engine, class KX_Scene* ketsjiscene); PyObject* initGameKeys(); PyObject* initRasterizer(class RAS_IRasterizer* rasty,class RAS_ICanvas* canvas); -PyObject* initGamePlayerPythonScripting(const STR_String& progname, TPythonSecurityLevel level, struct Main *maggie); +PyObject* initGamePlayerPythonScripting(const STR_String& progname, TPythonSecurityLevel level, struct Main *maggie, int argc, char** argv); PyObject* initMathutils(); PyObject* initBGL(); PyObject* initVideoTexture(void); diff --git a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp index f1c7b757579..56d94a8d226 100644 --- a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp +++ b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp @@ -231,7 +231,7 @@ int KX_SCA_AddObjectActuator::pyattr_set_object(void *self, const struct KX_PYAT KX_SCA_AddObjectActuator* actuator = static_cast<KX_SCA_AddObjectActuator*>(self); KX_GameObject *gameobj; - if (!ConvertPythonToGameObject(value, &gameobj, true)) + if (!ConvertPythonToGameObject(value, &gameobj, true, "actuator.object = value: KX_SCA_AddObjectActuator")) return 1; // ConvertPythonToGameObject sets the error if (actuator->m_OriginalObject != NULL) @@ -277,7 +277,7 @@ PyObject* KX_SCA_AddObjectActuator::PySetObject(PyObject* value) ShowDeprecationWarning("setObject()", "the object property"); - if (!ConvertPythonToGameObject(value, &gameobj, true)) + if (!ConvertPythonToGameObject(value, &gameobj, true, "actuator.setObject(value): KX_SCA_AddObjectActuator")) return NULL; // ConvertPythonToGameObject sets the error if (m_OriginalObject != NULL) diff --git a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp index 53067e94cd8..38f8d581d55 100644 --- a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp +++ b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp @@ -116,22 +116,12 @@ PyObject* KX_SCA_ReplaceMeshActuator::pyattr_get_mesh(void *self, const struct K int KX_SCA_ReplaceMeshActuator::pyattr_set_mesh(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) { KX_SCA_ReplaceMeshActuator* actuator = static_cast<KX_SCA_ReplaceMeshActuator*>(self); - if (value == Py_None) { - actuator->m_mesh = NULL; - } else if (PyString_Check(value)) { - void* mesh = SCA_ILogicBrick::m_sCurrentLogicManager->GetMeshByName(STR_String(PyString_AsString(value))); - if (mesh==NULL) { - PyErr_SetString(PyExc_ValueError, "actuator.mesh = string: Replace Mesh Actuator, mesh name given does not exist"); - return 1; - } - actuator->m_mesh= (class RAS_MeshObject*)mesh; - } else if PyObject_TypeCheck(value, &KX_MeshProxy::Type) { - KX_MeshProxy* proxy = (KX_MeshProxy*)value; - actuator->m_mesh= proxy->GetMesh(); - } else { - PyErr_SetString(PyExc_ValueError, "actuator.mesh = value: Replace Mesh Actuator, expected the mesh name, a KX_MeshProxy or None"); + RAS_MeshObject* new_mesh; + + if (!ConvertPythonToMesh(value, &new_mesh, true, "actuator.mesh = value: KX_SCA_ReplaceMeshActuator")) return 1; - } + + actuator->m_mesh = new_mesh; return 0; } @@ -144,23 +134,12 @@ const char KX_SCA_ReplaceMeshActuator::SetMesh_doc[] = PyObject* KX_SCA_ReplaceMeshActuator::PySetMesh(PyObject* value) { ShowDeprecationWarning("setMesh()", "the mesh property"); - if (value == Py_None) { - m_mesh = NULL; - } else { - char* meshname = PyString_AsString(value); - if (!meshname) { - PyErr_SetString(PyExc_ValueError, "Expected the name of a mesh or None"); - return NULL; - } - void* mesh = SCA_ILogicBrick::m_sCurrentLogicManager->GetMeshByName(STR_String(meshname)); - - if (mesh==NULL) { - PyErr_SetString(PyExc_ValueError, "The mesh name given does not exist"); - return NULL; - } - m_mesh= (class RAS_MeshObject*)mesh; - } + RAS_MeshObject* new_mesh; + + if (!ConvertPythonToMesh(value, &new_mesh, true, "actuator.mesh = value: KX_SCA_ReplaceMeshActuator")) + return NULL; + m_mesh = new_mesh; Py_RETURN_NONE; } diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index 0e1572da679..aa7bd65f240 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -1747,8 +1747,8 @@ KX_PYMETHODDEF_DOC(KX_Scene, addObject, if (!PyArg_ParseTuple(args, "OO|i:addObject", &pyob, &pyother, &time)) return NULL; - if (!ConvertPythonToGameObject(pyob, &ob, false) - || !ConvertPythonToGameObject(pyother, &other, false)) + if ( !ConvertPythonToGameObject(pyob, &ob, false, "scene.addObject(object, other, time): KX_Scene (first argument)") || + !ConvertPythonToGameObject(pyother, &other, false, "scene.addObject(object, other, time): KX_Scene (second argument)") ) return NULL; diff --git a/source/gameengine/Ketsji/KX_SoundActuator.cpp b/source/gameengine/Ketsji/KX_SoundActuator.cpp index b9edd7436df..412be497c5a 100644 --- a/source/gameengine/Ketsji/KX_SoundActuator.cpp +++ b/source/gameengine/Ketsji/KX_SoundActuator.cpp @@ -540,50 +540,16 @@ int KX_SoundActuator::pyattr_set_orientation(void *self, const struct KX_PYATTRI MT_Matrix3x3 rot; KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self); - if (!PySequence_Check(value)) { - PyErr_SetString(PyExc_AttributeError, "value = actuator.orientation: KX_SoundActuator, expected a sequence"); - return 1; - } - + /* if value is not a sequence PyOrientationTo makes an error */ + if (!PyOrientationTo(value, rot, "actuator.orientation = value: KX_SoundActuator")) + return NULL; + if (!actuator->m_soundObject) return 0; /* Since not having m_soundObject didn't do anything in the old version, - * it probably should be kept that way */ - - if (PyMatTo(value, rot)) - { - actuator->m_soundObject->SetOrientation(rot); - return 0; - } - PyErr_Clear(); - - - if (PySequence_Size(value) == 4) - { - MT_Quaternion qrot; - if (PyVecTo(value, qrot)) - { - rot.setRotation(qrot); - actuator->m_soundObject->SetOrientation(rot); - return 0; - } - return 1; - } - - if (PySequence_Size(value) == 3) - { - MT_Vector3 erot; - if (PyVecTo(value, erot)) - { - rot.setEuler(erot); - actuator->m_soundObject->SetOrientation(rot); - return 0; - } - return 1; - } - - PyErr_SetString(PyExc_AttributeError, "could not set the orientation from a 3x3 matrix, quaternion or euler sequence"); - return 1; - + * it probably should be kept that way */ + + actuator->m_soundObject->SetOrientation(rot); + return 0; } // Deprecated -----> diff --git a/source/gameengine/Ketsji/KX_TrackToActuator.cpp b/source/gameengine/Ketsji/KX_TrackToActuator.cpp index c89d88389c4..fbf43de6cf4 100644 --- a/source/gameengine/Ketsji/KX_TrackToActuator.cpp +++ b/source/gameengine/Ketsji/KX_TrackToActuator.cpp @@ -489,7 +489,7 @@ int KX_TrackToActuator::pyattr_set_object(void *self, const struct KX_PYATTRIBUT KX_TrackToActuator* actuator = static_cast<KX_TrackToActuator*>(self); KX_GameObject *gameobj; - if (!ConvertPythonToGameObject(value, &gameobj, true)) + if (!ConvertPythonToGameObject(value, &gameobj, true, "actuator.object = value: KX_TrackToActuator")) return 1; // ConvertPythonToGameObject sets the error if (actuator->m_object != NULL) @@ -525,7 +525,7 @@ PyObject* KX_TrackToActuator::PySetObject(PyObject* value) ShowDeprecationWarning("setObject()", "the object property"); - if (!ConvertPythonToGameObject(value, &gameobj, true)) + if (!ConvertPythonToGameObject(value, &gameobj, true, "actuator.setObject(value): KX_TrackToActuator")) return NULL; // ConvertPythonToGameObject sets the error if (m_object != NULL) diff --git a/source/gameengine/Ketsji/KX_VehicleWrapper.cpp b/source/gameengine/Ketsji/KX_VehicleWrapper.cpp index f77c135e994..1a6fb196db5 100644 --- a/source/gameengine/Ketsji/KX_VehicleWrapper.cpp +++ b/source/gameengine/Ketsji/KX_VehicleWrapper.cpp @@ -47,14 +47,15 @@ PyObject* KX_VehicleWrapper::PyAddWheel(PyObject* args) if (PyArg_ParseTuple(args,"OOOOffi:addWheel",&wheelGameObject,&pylistPos,&pylistDir,&pylistAxleDir,&suspensionRestLength,&wheelRadius,&hasSteering)) { KX_GameObject *gameOb; - if (!ConvertPythonToGameObject(wheelGameObject, &gameOb, false)) + if (!ConvertPythonToGameObject(wheelGameObject, &gameOb, false, "vehicle.addWheel(...): KX_VehicleWrapper (first argument)")) return NULL; if (gameOb->GetSGNode()) { PHY_IMotionState* motionState = new KX_MotionState(gameOb->GetSGNode()); - + + /* TODO - no error checking here! - bad juju */ MT_Vector3 attachPos,attachDir,attachAxle; PyVecTo(pylistPos,attachPos); PyVecTo(pylistDir,attachDir); diff --git a/source/gameengine/PyDoc/KX_VehicleWrapper.py b/source/gameengine/PyDoc/KX_VehicleWrapper.py index 68240e15622..087aa167475 100644 --- a/source/gameengine/PyDoc/KX_VehicleWrapper.py +++ b/source/gameengine/PyDoc/KX_VehicleWrapper.py @@ -5,15 +5,23 @@ class KX_VehicleWrapper: # (PyObjectPlus) All placeholders have a __ prefix """ - def __addWheel(val): + def addWheel(wheel, attachPos, attachDir, axleDir, suspensionRestLength, wheelRadius, hasSteering): + """ TODO - Description - @param val: the starting frame of the animation - @type val: float - - @rtype: integer - @return: TODO Description + @param wheel: The object to use as a wheel. + @type wheel: L{KX_GameObject<KX_GameObject.KX_GameObject>} or a KX_GameObject name + @param attachPos: The position that this wheel will attach to. + @type attachPos: vector of 3 floats + @param attachDir: The direction this wheel points. + @type attachDir: vector of 3 floats + @param axleDir: The direction of this wheels axle. + @type axleDir: vector of 3 floats + @param suspensionRestLength: TODO - Description + @type suspensionRestLength: float + @param wheelRadius: The size of the wheel. + @type wheelRadius: float """ def __applyBraking(val): diff --git a/source/gameengine/PyDoc/SCA_ILogicBrick.py b/source/gameengine/PyDoc/SCA_ILogicBrick.py index 18cb900f28d..4688ba12bb6 100644 --- a/source/gameengine/PyDoc/SCA_ILogicBrick.py +++ b/source/gameengine/PyDoc/SCA_ILogicBrick.py @@ -8,13 +8,17 @@ class SCA_ILogicBrick: @ivar executePriority: This determines the order controllers are evaluated, and actuators are activated (lower priority is executed first). @type executePriority: int + @ivar owner: The game object this logic brick is attached to (read only). + @type owner: L{KX_GameObject<KX_GameObject.KX_GameObject>} or None in exceptional cases. """ def getOwner(): """ Gets the game object associated with this logic brick. - @rtype: L{KX_GameObject} + Deprecated: Use the "owner" property instead. + + @rtype: L{KX_GameObject<KX_GameObject.KX_GameObject>} """ #--The following methods are deprecated-- |