BGE Python API
authorCampbell Barton <ideasman42@gmail.com>
Mon, 20 Apr 2009 09:13:59 +0000 (09:13 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Mon, 20 Apr 2009 09:13:59 +0000 (09:13 +0000)
- 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:
source/gameengine/GameLogic/SCA_ILogicBrick.cpp
source/gameengine/GameLogic/SCA_ILogicBrick.h
source/gameengine/GamePlayer/ghost/GPG_Application.cpp
source/gameengine/GamePlayer/ghost/GPG_Application.h
source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
source/gameengine/Ketsji/KX_CameraActuator.cpp
source/gameengine/Ketsji/KX_GameObject.cpp
source/gameengine/Ketsji/KX_GameObject.h
source/gameengine/Ketsji/KX_MeshProxy.cpp
source/gameengine/Ketsji/KX_MeshProxy.h
source/gameengine/Ketsji/KX_ParentActuator.cpp
source/gameengine/Ketsji/KX_PyMath.cpp
source/gameengine/Ketsji/KX_PyMath.h
source/gameengine/Ketsji/KX_PythonInit.cpp
source/gameengine/Ketsji/KX_PythonInit.h
source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp
source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp
source/gameengine/Ketsji/KX_Scene.cpp
source/gameengine/Ketsji/KX_SoundActuator.cpp
source/gameengine/Ketsji/KX_TrackToActuator.cpp
source/gameengine/Ketsji/KX_VehicleWrapper.cpp
source/gameengine/PyDoc/KX_VehicleWrapper.py
source/gameengine/PyDoc/SCA_ILogicBrick.py

index b304540..3cd750f 100644 (file)
@@ -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);      
index c0ff0fd..e59d05e 100644 (file)
@@ -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);
index 0ecbbea..907ba99 100644 (file)
@@ -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);
index 38408f9..845686f 100644 (file)
@@ -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;
 };
 
index a41446a..64e70ce 100644 (file)
@@ -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));
index 6cc4885..355cdbb 100644 (file)
@@ -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)
index af1dc7f..bea0fcf 100644 (file)
@@ -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;
index 89517bd..ec02dc1 100644 (file)
@@ -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.
index e2c59ab..6be1da5 100644 (file)
@@ -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;
+}
index dfc4988..aeecefc 100644 (file)
@@ -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;
index 69c0a3c..0093cf5 100644 (file)
@@ -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)
index cceb7a1..0093a72 100644 (file)
@@ -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)
 {
index 4a64063..00f7c5c 100644 (file)
@@ -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.
  */
index 097d20f..9649e50 100644 (file)
@@ -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);
index 97d23fe..1136019 100644 (file)
@@ -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); 
index f1c7b75..56d94a8 100644 (file)
@@ -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)
index 53067e9..38f8d58 100644 (file)
@@ -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;
 }
 
index 0e1572d..aa7bd65 100644 (file)
@@ -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;
 
 
index b9edd74..412be49 100644 (file)
@@ -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 ----->
index c89d883..fbf43de 100644 (file)
@@ -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)
index f77c135..1a6fb19 100644 (file)
@@ -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);
index 68240e1..087aa16 100644 (file)
@@ -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):
index 18cb900..4688ba1 100644 (file)
@@ -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--