diff options
author | Campbell Barton <ideasman42@gmail.com> | 2009-06-16 18:21:58 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2009-06-16 18:21:58 +0400 |
commit | a1cf7988c1d71b5b0a975eff1e5de1d744143606 (patch) | |
tree | 18b885d0d35b583b2ee7e90eb79ae26675f20fa1 /source/gameengine | |
parent | 2d40b8d56ff100b71dac7c4694f6115dcc0b01b5 (diff) | |
parent | 1025b750ee873edee48b03653ab0e6a7988245d0 (diff) |
svn merge https://svn.blender.org/svnroot/bf-blender/trunk/blender -r20855:20928
Sequencer changes from source/blender/src coming next
Diffstat (limited to 'source/gameengine')
-rw-r--r-- | source/gameengine/Converter/SConscript | 1 | ||||
-rw-r--r-- | source/gameengine/Expressions/InputParser.cpp | 60 | ||||
-rw-r--r-- | source/gameengine/Expressions/Value.cpp | 48 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_PyConstraintBinding.cpp | 1 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_PythonInit.cpp | 47 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_PythonSeq.cpp | 133 | ||||
-rw-r--r-- | source/gameengine/Physics/Bullet/CcdPhysicsController.cpp | 1 | ||||
-rw-r--r-- | source/gameengine/PyDoc/API_intro.py | 29 | ||||
-rw-r--r-- | source/gameengine/PyDoc/GameLogic.py | 21 | ||||
-rw-r--r-- | source/gameengine/VideoTexture/blendVideoTex.cpp | 1 |
10 files changed, 183 insertions, 159 deletions
diff --git a/source/gameengine/Converter/SConscript b/source/gameengine/Converter/SConscript index af0d39771de..3e0929e605a 100644 --- a/source/gameengine/Converter/SConscript +++ b/source/gameengine/Converter/SConscript @@ -19,6 +19,7 @@ incs += ' #source/gameengine/Physics/Dummy' incs += ' #source/gameengine/Network/LoopBackNetwork' incs += ' #source/blender/misc #source/blender/blenloader #source/blender/gpu' incs += ' #source/blender/windowmanager' +incs += ' #source/blender/makesrna' if env['WITH_BF_SOLID']: incs += ' #source/gameengine/Physics/Sumo #source/gameengine/Physics/Sumo/Fuzzics/include' diff --git a/source/gameengine/Expressions/InputParser.cpp b/source/gameengine/Expressions/InputParser.cpp index b15b206a38a..96a52aec028 100644 --- a/source/gameengine/Expressions/InputParser.cpp +++ b/source/gameengine/Expressions/InputParser.cpp @@ -636,63 +636,3 @@ void CParser::SetContext(CValue* context) } m_identifierContext = context; } - - - - -PyObject* CParserPyMake(PyObject* ignored,PyObject* args) -{ - char* txt; - if (!PyArg_ParseTuple(args,"s",&txt)) - return NULL; - CParser parser; - CExpression* expr = parser.ProcessText(txt); - CValue* val = expr->Calculate(); - expr->Release(); - return val->GetProxy(); -} - -static PyMethodDef CParserMethods[] = -{ - { "calc", CParserPyMake , METH_VARARGS}, - { NULL,NULL} // Sentinel -}; - - -#if (PY_VERSION_HEX >= 0x03000000) -static struct PyModuleDef Expression_module_def = { - {}, /* m_base */ - "Expression", /* m_name */ - 0, /* m_doc */ - 0, /* m_size */ - CParserMethods, /* m_methods */ - 0, /* m_reload */ - 0, /* m_traverse */ - 0, /* m_clear */ - 0, /* m_free */ -}; -#endif - -extern "C" { - void initExpressionModule(void) - { - PyObject *m; - /* Use existing module where possible - * be careful not to init any runtime vars after this */ - m = PyImport_ImportModule( "Expression" ); - if(m) { - Py_DECREF(m); - //return m; - } - else { - PyErr_Clear(); - -#if (PY_VERSION_HEX >= 0x03000000) - PyModule_Create(&Expression_module_def); -#else - Py_InitModule("Expression",CParserMethods); -#endif - } - } -} - diff --git a/source/gameengine/Expressions/Value.cpp b/source/gameengine/Expressions/Value.cpp index e6ef9733da8..61dabff510b 100644 --- a/source/gameengine/Expressions/Value.cpp +++ b/source/gameengine/Expressions/Value.cpp @@ -725,54 +725,6 @@ PyObject* CValue::ConvertKeysToPython( void ) return pylist; } -/* -PyObject* CValue::PyMake(PyObject* ignored,PyObject* args) -{ - - //if (!PyArg_ParseTuple(args,"s:make",&name)) return NULL; - Py_RETURN_NONE;//new CValue(); -} -*/ - -#if (PY_VERSION_HEX >= 0x03000000) -static struct PyModuleDef CValue_module_def = { - {}, /* m_base */ - "CValue", /* m_name */ - 0, /* m_doc */ - 0, /* m_size */ - CValueMethods, /* m_methods */ - 0, /* m_reload */ - 0, /* m_traverse */ - 0, /* m_clear */ - 0, /* m_free */ -}; -#endif - -extern "C" { - void initCValue(void) - { - PyObject *m; - /* Use existing module where possible - * be careful not to init any runtime vars after this */ - m = PyImport_ImportModule( "CValue" ); - if(m) { - Py_DECREF(m); - //return m; - } - else { - PyErr_Clear(); - -#if (PY_VERSION_HEX >= 0x03000000) - PyModule_Create(&CValue_module_def); -#else - Py_InitModule("CValue",CValueMethods); -#endif - } - } -} - - - #endif //NO_EXP_PYTHON_EMBEDDING /////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp index a098d99864f..4ec901a2f5e 100644 --- a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp +++ b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp @@ -630,6 +630,7 @@ PyObject* initPythonConstraintBinding() #if (PY_VERSION_HEX >= 0x03000000) m = PyModule_Create(&PhysicsConstraints_module_def); + PyDict_SetItemString(PySys_GetObject("modules"), PhysicsConstraints_module_def.m_name, m); #else m = Py_InitModule4("PhysicsConstraints", physicsconstraints_methods, PhysicsConstraints_module_documentation, diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index a3d464f0d5d..24fd0a512fb 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -70,6 +70,7 @@ #include "MT_Vector3.h" #include "MT_Point3.h" #include "ListValue.h" +#include "InputParser.h" #include "KX_Scene.h" #include "SND_DeviceManager.h" @@ -501,6 +502,32 @@ static PyObject *pyPrintExt(PyObject *,PyObject *,PyObject *) } +static PyObject *gEvalExpression(PyObject*, PyObject* value) +{ + char* txt= PyString_AsString(value); + + if (txt==NULL) { + PyErr_SetString(PyExc_TypeError, "Expression.calc(text): expects a single string argument"); + return NULL; + } + + CParser parser; + CExpression* expr = parser.ProcessText(txt); + CValue* val = expr->Calculate(); + expr->Release(); + + if (val) { + PyObject* pyobj = val->ConvertValueToPython(); + if (pyobj) + return pyobj; + else + return val->GetProxy(); + } + + Py_RETURN_NONE; +} + + static struct PyMethodDef game_methods[] = { {"expandPath", (PyCFunction)gPyExpandPath, METH_VARARGS, (PY_METHODCHAR)gPyExpandPath_doc}, {"sendMessage", (PyCFunction)gPySendMessage, METH_VARARGS, (PY_METHODCHAR)gPySendMessage_doc}, @@ -529,6 +556,7 @@ static struct PyMethodDef game_methods[] = { {"getAverageFrameRate", (PyCFunction) gPyGetAverageFrameRate, METH_NOARGS, (PY_METHODCHAR)"Gets the estimated average frame rate"}, {"getBlendFileList", (PyCFunction)gPyGetBlendFileList, METH_VARARGS, (PY_METHODCHAR)"Gets a list of blend files in the same directory as the current blend file"}, {"PrintGLInfo", (PyCFunction)pyPrintExt, METH_NOARGS, (PY_METHODCHAR)"Prints GL Extension Info"}, + {"EvalExpression", (PyCFunction)gEvalExpression, METH_O, (PY_METHODCHAR)"Evaluate a string as a game logic expression"}, {NULL, (PyCFunction) NULL, 0, NULL } }; @@ -1035,6 +1063,7 @@ PyObject* initGameLogic(KX_KetsjiEngine *engine, KX_Scene* scene) // quick hack // Create the module and add the functions #if (PY_VERSION_HEX >= 0x03000000) m = PyModule_Create(&GameLogic_module_def); + PyDict_SetItemString(PySys_GetObject("modules"), GameLogic_module_def.m_name, m); #else m = Py_InitModule4("GameLogic", game_methods, GameLogic_module_documentation, @@ -1701,6 +1730,7 @@ PyObject* initRasterizer(RAS_IRasterizer* rasty,RAS_ICanvas* canvas) // Create the module and add the functions #if (PY_VERSION_HEX >= 0x03000000) m = PyModule_Create(&Rasterizer_module_def); + PyDict_SetItemString(PySys_GetObject("modules"), Rasterizer_module_def.m_name, m); #else m = Py_InitModule4("Rasterizer", rasterizer_methods, Rasterizer_module_documentation, @@ -1835,6 +1865,7 @@ PyObject* initGameKeys() // Create the module and add the functions #if (PY_VERSION_HEX >= 0x03000000) m = PyModule_Create(&GameKeys_module_def); + PyDict_SetItemString(PySys_GetObject("modules"), GameKeys_module_def.m_name, m); #else m = Py_InitModule4("GameKeys", gamekeys_methods, GameKeys_module_documentation, @@ -1990,6 +2021,8 @@ PyObject* initGeometry() {Py_INCREF(Py_None);return Py_None;} PyObject* initBGL() {Py_INCREF(Py_None);return Py_None;} #endif + + void KX_SetActiveScene(class KX_Scene* scene) { gp_KetsjiScene = scene; @@ -2021,11 +2054,17 @@ int saveGamePythonConfig( char **marshal_buffer) if (pyGlobalDictMarshal) { // for testing only // PyObject_Print(pyGlobalDictMarshal, stderr, 0); - + char *marshal_cstring; + +#if PY_VERSION_HEX < 0x03000000 + marshal_cstring = PyString_AsString(pyGlobalDictMarshal); marshal_length= PyString_Size(pyGlobalDictMarshal); +#else // py3 uses byte arrays + marshal_cstring = PyBytes_AsString(pyGlobalDictMarshal); + marshal_length= PyBytes_Size(pyGlobalDictMarshal); +#endif *marshal_buffer = new char[marshal_length + 1]; - memcpy(*marshal_buffer, PyString_AsString(pyGlobalDictMarshal), marshal_length); - + memcpy(*marshal_buffer, marshal_cstring, marshal_length); Py_DECREF(pyGlobalDictMarshal); } else { printf("Error, GameLogic.globalDict could not be marshal'd\n"); @@ -2102,5 +2141,5 @@ void setGamePythonPath(char *path) // engine but loading blend files within the BGE wont overwrite gp_GamePythonPathOrig void resetGamePythonPath() { - gp_GamePythonPathOrig[0] == '\0'; + gp_GamePythonPathOrig[0] = '\0'; } diff --git a/source/gameengine/Ketsji/KX_PythonSeq.cpp b/source/gameengine/Ketsji/KX_PythonSeq.cpp index f2bc4671f4e..524d957a80c 100644 --- a/source/gameengine/Ketsji/KX_PythonSeq.cpp +++ b/source/gameengine/Ketsji/KX_PythonSeq.cpp @@ -57,7 +57,7 @@ static Py_ssize_t KX_PythonSeq_len( PyObject * self ) PyObjectPlus *self_plus= BGE_PROXY_REF(((KX_PythonSeq *)self)->base); if(self_plus==NULL) { - PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG); + PyErr_SetString(PyExc_SystemError, "len(seq): "BGE_PROXY_ERROR_MSG); return -1; } @@ -84,7 +84,7 @@ static PyObject *KX_PythonSeq_getIndex(PyObject* self, int index) PyObjectPlus *self_plus= BGE_PROXY_REF(((KX_PythonSeq *)self)->base); if(self_plus==NULL) { - PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG); + PyErr_SetString(PyExc_SystemError, "val = seq[i]: "BGE_PROXY_ERROR_MSG); return NULL; } @@ -145,25 +145,9 @@ static PyObject *KX_PythonSeq_getIndex(PyObject* self, int index) return NULL; } - -static PyObject * KX_PythonSeq_subscript(PyObject * self, PyObject *key) +static PyObjectPlus * KX_PythonSeq_subscript__internal(PyObject *self, char *key) { PyObjectPlus *self_plus= BGE_PROXY_REF(((KX_PythonSeq *)self)->base); - char *name = NULL; - - if(self_plus==NULL) { - PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG); - return NULL; - } - - if (PyInt_Check(key)) { - return KX_PythonSeq_getIndex(self, PyInt_AS_LONG( key )); - } else if ( PyString_Check(key) ) { - name = PyString_AsString( key ); - } else { - PyErr_SetString( PyExc_TypeError, "expected a string or an index" ); - return NULL; - } switch(((KX_PythonSeq *)self)->type) { case KX_PYGENSEQ_CONT_TYPE_SENSORS: @@ -172,8 +156,9 @@ static PyObject * KX_PythonSeq_subscript(PyObject * self, PyObject *key) SCA_ISensor* sensor; for (unsigned int index=0;index<linkedsensors.size();index++) { sensor = linkedsensors[index]; - if (sensor->GetName() == name) - return sensor->GetProxy(); + if (sensor->GetName() == key) + return static_cast<PyObjectPlus *>(sensor); + } break; } @@ -183,8 +168,8 @@ static PyObject * KX_PythonSeq_subscript(PyObject * self, PyObject *key) SCA_IActuator* actuator; for (unsigned int index=0;index<linkedactuators.size();index++) { actuator = linkedactuators[index]; - if (actuator->GetName() == name) - return actuator->GetProxy(); + if (actuator->GetName() == key) + return static_cast<PyObjectPlus *>(actuator); } break; } @@ -194,8 +179,8 @@ static PyObject * KX_PythonSeq_subscript(PyObject * self, PyObject *key) SCA_ISensor *sensor; for (unsigned int index=0;index<linkedsensors.size();index++) { sensor= linkedsensors[index]; - if (sensor->GetName() == name) - return sensor->GetProxy(); + if (sensor->GetName() == key) + return static_cast<PyObjectPlus *>(sensor); } break; } @@ -205,8 +190,8 @@ static PyObject * KX_PythonSeq_subscript(PyObject * self, PyObject *key) SCA_IController *controller; for (unsigned int index=0;index<linkedcontrollers.size();index++) { controller= linkedcontrollers[index]; - if (controller->GetName() == name) - return controller->GetProxy(); + if (controller->GetName() == key) + return static_cast<PyObjectPlus *>(controller); } break; } @@ -216,23 +201,105 @@ static PyObject * KX_PythonSeq_subscript(PyObject * self, PyObject *key) SCA_IActuator *actuator; for (unsigned int index=0;index<linkedactuators.size();index++) { actuator= linkedactuators[index]; - if (actuator->GetName() == name) - return actuator->GetProxy(); + if (actuator->GetName() == key) + return static_cast<PyObjectPlus *>(actuator); } break; } } - PyErr_Format( PyExc_KeyError, "requested item \"%s\" does not exist", name); return NULL; } + +static PyObject * KX_PythonSeq_subscript(PyObject * self, PyObject *key) +{ + PyObjectPlus *self_plus= BGE_PROXY_REF(((KX_PythonSeq *)self)->base); + + if(self_plus==NULL) { + PyErr_SetString(PyExc_SystemError, "val = seq[key], KX_PythonSeq: "BGE_PROXY_ERROR_MSG); + return NULL; + } + + if (PyInt_Check(key)) { + return KX_PythonSeq_getIndex(self, PyInt_AS_LONG( key )); + } + else if ( PyString_Check(key) ) { + char *name = PyString_AsString(key); + PyObjectPlus *ret = KX_PythonSeq_subscript__internal(self, name); + + if(ret) { + return ret->GetProxy(); + } else { + PyErr_Format( PyExc_KeyError, "requested item \"%s\" does not exist", name); + return NULL; + } + } + else { + PyErr_SetString( PyExc_TypeError, "expected a string or an index" ); + return NULL; + } +} + + +static int KX_PythonSeq_contains(PyObject *self, PyObject *key) +{ + PyObjectPlus *self_plus= BGE_PROXY_REF(((KX_PythonSeq *)self)->base); + + if(self_plus==NULL) { + PyErr_SetString(PyExc_SystemError, "key in seq, KX_PythonSeq: "BGE_PROXY_ERROR_MSG); + return -1; + } + if(!PyString_Check(key)) { + PyErr_SetString(PyExc_SystemError, "key in seq, KX_PythonSeq: key must be a string"); + return -1; + } + + if(KX_PythonSeq_subscript__internal(self, PyString_AsString(key))) + return 1; + + return 0; +} + +/* Matches python dict.get(key, [default]) */ +PyObject* KX_PythonSeq_get(PyObject * self, PyObject *args) +{ + char *key; + PyObject* def = Py_None; + PyObjectPlus* ret_plus; + + if (!PyArg_ParseTuple(args, "s|O:get", &key, &def)) + return NULL; + + if((ret_plus = KX_PythonSeq_subscript__internal(self, key))) + return ret_plus->GetProxy(); + + Py_INCREF(def); + return def; +} + +PySequenceMethods KX_PythonSeq_as_sequence = { + NULL, /* Cant set the len otherwise it can evaluate as false */ + NULL, /* sq_concat */ + NULL, /* sq_repeat */ + NULL, /* sq_item */ + NULL, /* sq_slice */ + NULL, /* sq_ass_item */ + NULL, /* sq_ass_slice */ + (objobjproc)KX_PythonSeq_contains, /* sq_contains */ +}; + static PyMappingMethods KX_PythonSeq_as_mapping = { KX_PythonSeq_len, /* mp_length */ KX_PythonSeq_subscript, /* mp_subscript */ 0, /* mp_ass_subscript */ }; +PyMethodDef KX_PythonSeq_methods[] = { + // dict style access for props + {"get",(PyCFunction) KX_PythonSeq_get, METH_VARARGS}, + {NULL,NULL} //Sentinel +}; /* * Initialize the interator index @@ -241,7 +308,7 @@ static PyMappingMethods KX_PythonSeq_as_mapping = { static PyObject *KX_PythonSeq_getIter(KX_PythonSeq *self) { if(BGE_PROXY_REF(self->base)==NULL) { - PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG); + PyErr_SetString(PyExc_SystemError, "for i in seq: "BGE_PROXY_ERROR_MSG); return NULL; } @@ -323,7 +390,7 @@ PyTypeObject KX_PythonSeq_Type = { /* Method suites for standard classes */ NULL, /* PyNumberMethods *tp_as_number; */ - NULL, /* PySequenceMethods *tp_as_sequence; */ + &KX_PythonSeq_as_sequence, /* PySequenceMethods *tp_as_sequence; */ &KX_PythonSeq_as_mapping, /* PyMappingMethods *tp_as_mapping; */ /* More standard operations (here for binary compatibility) */ @@ -361,7 +428,7 @@ PyTypeObject KX_PythonSeq_Type = { ( iternextfunc ) KX_PythonSeq_nextIter, /* iternextfunc tp_iternext; */ /*** Attribute descriptor and subclassing stuff ***/ - NULL, /* struct PyMethodDef *tp_methods; */ + KX_PythonSeq_methods, /* struct PyMethodDef *tp_methods; */ NULL, /* struct PyMemberDef *tp_members; */ NULL, /* struct PyGetSetDef *tp_getset; */ NULL, /* struct _typeobject *tp_base; */ diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp index 3e20203a4cc..3c41a856660 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp @@ -979,6 +979,7 @@ void CcdPhysicsController::setScaling(float scaleX,float scaleY,float scaleZ) if (m_object && m_object->getCollisionShape()) { + m_object->activate(true); // without this, sleeping objects scale wont be applied in bullet if python changes the scale - Campbell. m_object->getCollisionShape()->setLocalScaling(m_cci.m_scaling); //printf("no inertia recalc for fixed objects with mass=0\n"); diff --git a/source/gameengine/PyDoc/API_intro.py b/source/gameengine/PyDoc/API_intro.py index ad37e34fbac..578b56eb2b0 100644 --- a/source/gameengine/PyDoc/API_intro.py +++ b/source/gameengine/PyDoc/API_intro.py @@ -6,22 +6,29 @@ The Blender Game Engine Python API Reference See U{release notes<http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.49/Game_Engine>} for updates, changes and new functionality in the Game Engine Python API. - Top Module: - ----------- - - - L{GameLogic} - - L{GameKeys} - - L{GameTypes} - - L{Mathutils} - - L{Geometry} - - L{BGL} + Blender Game Engine Modules: + ---------------------------- + + Modules that include methods for accessing GameEngine data and functions. + + - L{GameLogic} utility functons for game logic. + - L{GameKeys} keyboard input and event conversion. + - L{Rasterizer} display and rendering. + - L{GameTypes} contains all the python types spesific to the GameEngine. Undocumented modules: --------------------- - VideoTexture - - CValue - - Expression - PhysicsConstraints + + Additional Modules: + ------------------- + + These modules have no GameEngine spesific functionality but are useful in many cases. + + - L{Mathutils} + - L{Geometry} + - L{BGL} Introduction: diff --git a/source/gameengine/PyDoc/GameLogic.py b/source/gameengine/PyDoc/GameLogic.py index 3ec30a63c58..46f00fa7ea6 100644 --- a/source/gameengine/PyDoc/GameLogic.py +++ b/source/gameengine/PyDoc/GameLogic.py @@ -271,7 +271,7 @@ Documentation for the GameLogic Module. @var KX_PARENT_REMOVE: @var KX_PARENT_SET: -@group Shader: MODELMATRIX*, MODELVIEWMATRIX*, VIEWMATRIX*, CAM_POS, CONSTANT_TIMER +@group Shader: MODELMATRIX*, MODELVIEWMATRIX*, VIEWMATRIX*, CAM_POS, CONSTANT_TIMER, SHD_TANGENT @var VIEWMATRIX: @var VIEWMATRIX_INVERSE: @var VIEWMATRIX_INVERSETRANSPOSE: @@ -285,8 +285,8 @@ Documentation for the GameLogic Module. @var MODELVIEWMATRIX_INVERSETRANSPOSE: @var MODELVIEWMATRIX_TRANSPOSE: @var CAM_POS: Current camera position -@var CONSTANT_TIMER: Current camera position -@var SHD_TANGENT: Current camera position +@var CONSTANT_TIMER: User a timer for the uniform value. +@var SHD_TANGENT: Not yet documented. @group Blender Material: BL_* @var BL_DST_ALPHA: @@ -302,6 +302,13 @@ Documentation for the GameLogic Module. @var BL_ZERO: @group Deprecated: addActiveActuator + +@var globalDict: A dictionary that is saved between loading blend files so you can use + it to store inventory and other variables you want to store between + scenes and blend files. It can also be written to a file and loaded + later on with the game load/save actuators. + note: only python built in types such as int/string/bool/float/tuples/lists + can be saved, GameObjects, Actuators etc will not work as expectred. """ import GameTypes @@ -441,6 +448,14 @@ def setPhysicsTicRate(ticrate): @type ticrate: float """ +def EvalExpression(text): + """ + Evaluate the string as an expression, similar to the expression controller logic brick. + @param text: The expression to evaluate. + @type text: string + @return: The result of the expression. The type depends on the expression. + """ + #{ Utility functions def getAverageFrameRate(): """ diff --git a/source/gameengine/VideoTexture/blendVideoTex.cpp b/source/gameengine/VideoTexture/blendVideoTex.cpp index 1dcc72c8f7d..dad52a426b6 100644 --- a/source/gameengine/VideoTexture/blendVideoTex.cpp +++ b/source/gameengine/VideoTexture/blendVideoTex.cpp @@ -204,6 +204,7 @@ PyObject* initVideoTexture(void) #if (PY_VERSION_HEX >= 0x03000000) m = PyModule_Create(&VideoTexture_module_def); + PyDict_SetItemString(PySys_GetObject("modules"), VideoTexture_module_def.m_name, m); #else m = Py_InitModule4("VideoTexture", moduleMethods, "Module that allows to play video files on textures in GameBlender.", |