diff options
-rw-r--r-- | source/gameengine/Expressions/ListValue.cpp | 15 | ||||
-rw-r--r-- | source/gameengine/Expressions/PyObjectPlus.h | 32 | ||||
-rw-r--r-- | source/gameengine/Expressions/Value.h | 31 | ||||
-rw-r--r-- | source/gameengine/GameLogic/SCA_IScene.h | 2 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_Camera.cpp | 31 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_PythonInit.cpp | 22 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp | 9 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h | 1 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_Scene.cpp | 108 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_Scene.h | 39 | ||||
-rw-r--r-- | source/gameengine/PyDoc/GameLogic.py | 7 | ||||
-rw-r--r-- | source/gameengine/PyDoc/KX_MeshProxy.py | 50 | ||||
-rw-r--r-- | source/gameengine/PyDoc/KX_SCA_ReplaceMeshActuator.py | 50 | ||||
-rw-r--r-- | source/gameengine/PyDoc/KX_Scene.py | 68 |
14 files changed, 386 insertions, 79 deletions
diff --git a/source/gameengine/Expressions/ListValue.cpp b/source/gameengine/Expressions/ListValue.cpp index 3ee8a5a3501..cd16377b5e3 100644 --- a/source/gameengine/Expressions/ListValue.cpp +++ b/source/gameengine/Expressions/ListValue.cpp @@ -53,8 +53,17 @@ PyObject* listvalue_mapping_subscript(PyObject* list,PyObject* pyindex) return (PyObject*) item; } - Py_Error(PyExc_IndexError, "Python ListIndex out of range"); - Py_Return; + if (PyInt_Check(pyindex)) + { + int index = PyInt_AsLong(pyindex); + return listvalue_buffer_item(list, index); + } + + PyObject *pyindex_str = PyObject_Repr(pyindex); /* new ref */ + STR_String index_str(PyString_AsString(pyindex_str)); + PyErr_Format(PyExc_KeyError, "'%s' not in list", index_str.Ptr()); + Py_DECREF(pyindex_str); + return NULL; } @@ -189,7 +198,7 @@ PyTypeObject CListValue::Type = { __repr, /*tp_repr*/ 0, /*tp_as_number*/ &listvalue_as_sequence, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ + &instance_as_mapping, /*tp_as_mapping*/ 0, /*tp_hash*/ 0, /*tp_call */ }; diff --git a/source/gameengine/Expressions/PyObjectPlus.h b/source/gameengine/Expressions/PyObjectPlus.h index 7c5f531f35b..8a5e8ef2d7b 100644 --- a/source/gameengine/Expressions/PyObjectPlus.h +++ b/source/gameengine/Expressions/PyObjectPlus.h @@ -82,6 +82,38 @@ inline void Py_Fatal(char *M) { else \ return rvalue +/** + * These macros are helpfull when embedding Python routines. The second + * macro is one that also requires a documentation string + */ +#define KX_PYMETHOD(class_name, method_name) \ + PyObject* Py##method_name(PyObject* self, PyObject* args, PyObject* kwds); \ + static PyObject* sPy##method_name( PyObject* self, PyObject* args, PyObject* kwds) { \ + return ((class_name*) self)->Py##method_name(self, args, kwds); \ + }; \ + +#define KX_PYMETHOD_DOC(class_name, method_name) \ + PyObject* Py##method_name(PyObject* self, PyObject* args, PyObject* kwds); \ + static PyObject* sPy##method_name( PyObject* self, PyObject* args, PyObject* kwds) { \ + return ((class_name*) self)->Py##method_name(self, args, kwds); \ + }; \ + static char method_name##_doc[]; \ + +/* The line above should remain empty */ +/** + * Method table macro (with doc) + */ +#define KX_PYMETHODTABLE(class_name, method_name) \ + {#method_name , (PyCFunction) class_name::sPy##method_name, METH_VARARGS, class_name::method_name##_doc} + +/** + * Function implementation macro + */ +#define KX_PYMETHODDEF_DOC(class_name, method_name, doc_string) \ +char class_name::method_name##_doc[] = doc_string; \ +PyObject* class_name::Py##method_name(PyObject* self, PyObject* args, PyObject* kwds) + + /*------------------------------ * PyObjectPlus diff --git a/source/gameengine/Expressions/Value.h b/source/gameengine/Expressions/Value.h index 4656e2ca5ac..d30e8a26d97 100644 --- a/source/gameengine/Expressions/Value.h +++ b/source/gameengine/Expressions/Value.h @@ -182,37 +182,6 @@ public: // // -/** - * These macros are helpfull when embedding Python routines. The second - * macro is one that also requires a documentation string - */ -#define KX_PYMETHOD(class_name, method_name) \ - PyObject* Py##method_name(PyObject* self, PyObject* args, PyObject* kwds); \ - static PyObject* sPy##method_name( PyObject* self, PyObject* args, PyObject* kwds) { \ - return ((class_name*) self)->Py##method_name(self, args, kwds); \ - }; \ - -#define KX_PYMETHOD_DOC(class_name, method_name) \ - PyObject* Py##method_name(PyObject* self, PyObject* args, PyObject* kwds); \ - static PyObject* sPy##method_name( PyObject* self, PyObject* args, PyObject* kwds) { \ - return ((class_name*) self)->Py##method_name(self, args, kwds); \ - }; \ - static char method_name##_doc[]; \ - -/* The line above should remain empty */ -/** - * Method table macro (with doc) - */ -#define KX_PYMETHODTABLE(class_name, method_name) \ - {#method_name , (PyCFunction) class_name::sPy##method_name, METH_VARARGS, class_name::method_name##_doc} - -/** - * Function implementation macro - */ -#define KX_PYMETHODDEF_DOC(class_name, method_name, doc_string) \ -char class_name::method_name##_doc[] = doc_string; \ -PyObject* class_name::Py##method_name(PyObject* self, PyObject* args, PyObject* kwds) - #ifndef NO_EXP_PYTHON_EMBEDDING diff --git a/source/gameengine/GameLogic/SCA_IScene.h b/source/gameengine/GameLogic/SCA_IScene.h index f49d4d3004c..d77c1dd6483 100644 --- a/source/gameengine/GameLogic/SCA_IScene.h +++ b/source/gameengine/GameLogic/SCA_IScene.h @@ -42,7 +42,7 @@ struct SCA_DebugProp STR_String m_name; }; -class SCA_IScene +class SCA_IScene { std::vector<SCA_DebugProp*> m_debugList; public: diff --git a/source/gameengine/Ketsji/KX_Camera.cpp b/source/gameengine/Ketsji/KX_Camera.cpp index 4ed7b1e62d0..5d455a70ed1 100644 --- a/source/gameengine/Ketsji/KX_Camera.cpp +++ b/source/gameengine/Ketsji/KX_Camera.cpp @@ -515,14 +515,14 @@ KX_PYMETHODDEF_DOC(KX_Camera, sphereInsideFrustum, MT_Point3 centre = MT_Point3FromPyList(pycentre); if (PyErr_Occurred()) { - PyErr_SetString(PyExc_TypeError, "Expected list for argument centre."); + PyErr_SetString(PyExc_TypeError, "sphereInsideFrustum: Expected list for argument centre."); Py_Return; } return PyInt_FromLong(SphereInsideFrustum(centre, radius)); /* new ref */ } - PyErr_SetString(PyExc_TypeError, "Expected arguments: (centre, radius)"); + PyErr_SetString(PyExc_TypeError, "sphereInsideFrustum: Expected arguments: (centre, radius)"); Py_Return; } @@ -558,8 +558,8 @@ KX_PYMETHODDEF_DOC(KX_Camera, boxInsideFrustum, unsigned int num_points = PySequence_Size(pybox); if (num_points != 8) { - PyErr_Format(PyExc_TypeError, "Expected eight (8) points, got %d", num_points); - Py_Return; + PyErr_Format(PyExc_TypeError, "boxInsideFrustum: Expected eight (8) points, got %d", num_points); + return NULL; } MT_Point3 box[8]; @@ -569,17 +569,14 @@ KX_PYMETHODDEF_DOC(KX_Camera, boxInsideFrustum, box[p] = MT_Point3FromPyList(item); Py_DECREF(item); if (PyErr_Occurred()) - { - Py_Return; - } + return NULL; } return PyInt_FromLong(BoxInsideFrustum(box)); /* new ref */ } - PyErr_SetString(PyExc_TypeError, "Expected argument: list of points."); - - Py_Return; + PyErr_SetString(PyExc_TypeError, "boxInsideFrustum: Expected argument: list of points."); + return NULL; } KX_PYMETHODDEF_DOC(KX_Camera, pointInsideFrustum, @@ -603,13 +600,13 @@ KX_PYMETHODDEF_DOC(KX_Camera, pointInsideFrustum, { MT_Point3 point = MT_Point3FromPyList(pypoint); if (PyErr_Occurred()) - Py_Return; + return NULL; return PyInt_FromLong(PointInsideFrustum(point)); /* new ref */ } - PyErr_SetString(PyExc_TypeError, "Expected point argument."); - Py_Return; + PyErr_SetString(PyExc_TypeError, "pointInsideFrustum: Expected point argument."); + return NULL; } KX_PYMETHODDEF_DOC(KX_Camera, getCameraToWorld, @@ -686,14 +683,12 @@ KX_PYMETHODDEF_DOC(KX_Camera, setProjectionMatrix, { MT_Matrix4x4 mat = MT_Matrix4x4FromPyObject(pymat); if (PyErr_Occurred()) - { - Py_Return; - } + return NULL; SetProjectionMatrix(mat); Py_Return; } - PyErr_SetString(PyExc_TypeError, "Expected 4x4 list as matrix argument."); - Py_Return; + PyErr_SetString(PyExc_TypeError, "setProjectionMatrix: Expected 4x4 list as matrix argument."); + return NULL; } diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index f4736f4c423..1b6d55f68e9 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -160,7 +160,7 @@ static PyObject* gPyGetSpectrum(PyObject* self, -static void gPyStartDSP(PyObject* self, +static PyObject* gPyStartDSP(PyObject* self, PyObject* args, PyObject* kwds) { @@ -172,13 +172,15 @@ static void gPyStartDSP(PyObject* self, { audiodevice->StartUsingDSP(); usedsp = true; + Py_Return; } } + return NULL; } -static void gPyStopDSP(PyObject* self, +static PyObject* gPyStopDSP(PyObject* self, PyObject* args, PyObject* kwds) { @@ -190,16 +192,32 @@ static void gPyStopDSP(PyObject* self, { audiodevice->StopUsingDSP(); usedsp = false; + Py_Return; } } + return NULL; } +static STR_String gPyGetCurrentScene_doc = +"getCurrentScene()\n" +"Gets a reference to the current scene.\n"; +static PyObject* gPyGetCurrentScene(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + Py_INCREF(gp_KetsjiScene); + return (PyObject*) gp_KetsjiScene; +} + + static struct PyMethodDef game_methods[] = { {"getCurrentController", (PyCFunction) SCA_PythonController::sPyGetCurrentController, METH_VARARGS, SCA_PythonController::sPyGetCurrentController__doc__}, + {"getCurrentScene", (PyCFunction) gPyGetCurrentScene, + METH_VARARGS, gPyGetCurrentScene_doc.Ptr()}, {"addActiveActuator",(PyCFunction) SCA_PythonController::sPyAddActiveActuator, METH_VARARGS, SCA_PythonController::sPyAddActiveActuator__doc__}, {"getRandomFloat",(PyCFunction) gPyGetRandomFloat, diff --git a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp index 2480724986b..f26e9873863 100644 --- a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp +++ b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp @@ -84,6 +84,7 @@ PyParentObject KX_SCA_ReplaceMeshActuator::Parents[] = { PyMethodDef KX_SCA_ReplaceMeshActuator::Methods[] = { {"setMesh", (PyCFunction) KX_SCA_ReplaceMeshActuator::sPySetMesh, METH_VARARGS, SetMesh_doc}, + KX_PYMETHODTABLE(KX_SCA_ReplaceMeshActuator, getMesh), {NULL,NULL} //Sentinel }; @@ -123,7 +124,13 @@ PyObject* KX_SCA_ReplaceMeshActuator::PySetMesh(PyObject* self, return NULL; } - +KX_PYMETHODDEF_DOC(KX_SCA_ReplaceMeshActuator, getMesh, +"getMesh() -> string\n" +"Returns the name of the mesh to be substituted.\n" +) +{ + return PyString_FromString(const_cast<char *>(m_mesh->GetName().ReadPtr())); +} /* ------------------------------------------------------------------------- */ /* Native functions */ diff --git a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h index cc7bd8c9c6a..e38cf412539 100644 --- a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h +++ b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h @@ -82,6 +82,7 @@ class KX_SCA_ReplaceMeshActuator : public SCA_IActuator /* 1. setMesh */ KX_PYMETHOD_DOC(KX_SCA_ReplaceMeshActuator,SetMesh); + KX_PYMETHOD_DOC(KX_SCA_ReplaceMeshActuator,getMesh); }; diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index 8f912642127..c274f05558d 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -102,7 +102,7 @@ KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice, class NG_NetworkDeviceInterface *ndi, class SND_IAudioDevice* adi, const STR_String& sceneName): - + PyObjectPlus(&KX_Scene::Type), m_keyboardmgr(NULL), m_mousemgr(NULL), m_physicsEnvironment(0), @@ -155,6 +155,8 @@ KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice, m_canvasDesignWidth = 0; m_canvasDesignHeight = 0; + + m_attrlist = PyDict_New(); /* new ref */ } @@ -202,6 +204,8 @@ KX_Scene::~KX_Scene() { delete m_bucketmanager; } + + Py_DECREF(m_attrlist); } @@ -1115,3 +1119,105 @@ void KX_Scene::SetPhysicsEnvironment(class PHY_IPhysicsEnvironment* physEnv) return; } } + +//---------------------------------------------------------------------------- +//Python + +PyMethodDef KX_Scene::Methods[] = { + KX_PYMETHODTABLE(KX_Scene, getLightList), + KX_PYMETHODTABLE(KX_Scene, getObjectList), + KX_PYMETHODTABLE(KX_Scene, getName), + + {NULL,NULL} //Sentinel +}; + +PyTypeObject KX_Scene::Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, + "KX_Scene", + sizeof(KX_Scene), + 0, + PyDestructor, + 0, + __getattr, + __setattr, + 0, //&MyPyCompare, + __repr, + 0, //&cvalue_as_number, + 0, + 0, + 0, + 0, 0, 0, 0, 0, 0 +}; + +PyParentObject KX_Scene::Parents[] = { + &KX_Scene::Type, + &CValue::Type, + NULL +}; + +PyObject* KX_Scene::_getattr(const STR_String& attr) +{ + if (attr == "name") + return PyString_FromString(GetName()); + + if (attr == "active_camera") + { + KX_Camera *camera = GetActiveCamera(); + camera->AddRef(); + return (PyObject*) camera; + } + + if (attr == "suspended") + return PyInt_FromLong(m_suspend); + + if (attr == "activity_culling") + return PyInt_FromLong(m_activity_culling); + + if (attr == "activity_culling_radius") + return PyFloat_FromDouble(m_activity_box_radius); + + PyObject* value = PyDict_GetItemString(m_attrlist, const_cast<char *>(attr.ReadPtr())); + if (value) + { + Py_INCREF(value); + return value; + } + + _getattr_up(PyObjectPlus); +} + +int KX_Scene::_setattr(const STR_String &attr, PyObject *pyvalue) +{ + + if (!PyDict_SetItemString(m_attrlist, const_cast<char *>(attr.ReadPtr()), pyvalue)) + return 0; + + return PyObjectPlus::_setattr(attr, pyvalue); +} + +KX_PYMETHODDEF_DOC(KX_Scene, getLightList, +"getLightList() -> list [KX_Light]\n" +"Returns a list of all lights in the scene.\n" +) +{ + m_lightlist->AddRef(); + return (PyObject*) m_lightlist; +} + +KX_PYMETHODDEF_DOC(KX_Scene, getObjectList, +"getObjectList() -> list [KX_GameObject]\n" +"Returns a list of all game objects in the scene.\n" +) +{ + m_objectlist->AddRef(); + return (PyObject*) m_objectlist; +} + +KX_PYMETHODDEF_DOC(KX_Scene, getName, +"getName() -> string\n" +"Returns the name of the scene.\n" +) +{ + return PyString_FromString(GetName()); +} diff --git a/source/gameengine/Ketsji/KX_Scene.h b/source/gameengine/Ketsji/KX_Scene.h index a468a8d1861..c32cd4182aa 100644 --- a/source/gameengine/Ketsji/KX_Scene.h +++ b/source/gameengine/Ketsji/KX_Scene.h @@ -49,6 +49,8 @@ #include "RAS_FramingManager.h" #include "RAS_Rect.h" +#include "PyObjectPlus.h" + /** * @section Forward declarations */ @@ -86,9 +88,9 @@ class SG_IObject; * The KX_Scene holds all data for an independent scene. It relates * KX_Objects to the specific objects in the modules. * */ -class KX_Scene : public SCA_IScene +class KX_Scene : public SCA_IScene, public PyObjectPlus { - //Py_Header; + Py_Header; protected: RAS_BucketManager* m_bucketmanager; CListValue* m_tempObjectList; @@ -245,6 +247,11 @@ protected: void MarkVisible(SG_Tree *node, RAS_IRasterizer* rasty); void MarkSubTreeVisible(SG_Tree *node, RAS_IRasterizer* rasty, bool visible); + + /** + * This stores anything from python + */ + PyObject* m_attrlist; public: KX_Scene(class SCA_IInputDevice* keyboarddevice, @@ -486,25 +493,25 @@ public: */ void SetNodeTree(SG_Tree* root); -#if 0 - KX_PYMETHOD_DOC(KX_Scene, GetLightList); - KX_PYMETHOD_DOC(KX_Scene, GetObjectList); - KX_PYMETHOD_DOC(KX_Scene, GetName); - - KX_PYMETHOD_DOC(KX_Scene, GetActiveCamera); - KX_PYMETHOD_DOC(KX_Scene, SetActiveCamera); - KX_PYMETHOD_DOC(KX_Scene, FindCamera); + KX_PYMETHOD_DOC(KX_Scene, getLightList); + KX_PYMETHOD_DOC(KX_Scene, getObjectList); + KX_PYMETHOD_DOC(KX_Scene, getName); +/* + KX_PYMETHOD_DOC(KX_Scene, getActiveCamera); + KX_PYMETHOD_DOC(KX_Scene, getActiveCamera); + KX_PYMETHOD_DOC(KX_Scene, findCamera); - KX_PYMETHOD_DOC(KX_Scene, SetGravity); + KX_PYMETHOD_DOC(KX_Scene, getGravity); - KX_PYMETHOD_DOC(KX_Scene, SetActivityCulling); - KX_PYMETHOD_DOC(KX_Scene, SetActivityCullingRadius); + KX_PYMETHOD_DOC(KX_Scene, setActivityCulling); + KX_PYMETHOD_DOC(KX_Scene, setActivityCullingRadius); - KX_PYMETHOD_DOC(KX_Scene, SetSceneViewport); - KX_PYMETHOD_DOC(KX_Scene, GetSceneViewport); + KX_PYMETHOD_DOC(KX_Scene, setSceneViewport); + KX_PYMETHOD_DOC(KX_Scene, setSceneViewport); + */ virtual PyObject* _getattr(const STR_String& attr); /* name, active_camera, gravity, suspended, viewport, framing, activity_culling, activity_culling_radius */ -#endif + virtual int KX_Scene::_setattr(const STR_String &attr, PyObject *pyvalue); }; typedef std::vector<KX_Scene*> KX_SceneList; diff --git a/source/gameengine/PyDoc/GameLogic.py b/source/gameengine/PyDoc/GameLogic.py index b372cec0481..08f71e50f97 100644 --- a/source/gameengine/PyDoc/GameLogic.py +++ b/source/gameengine/PyDoc/GameLogic.py @@ -86,6 +86,12 @@ def getCurrentController(): @rtype: L{SCA_PythonController} """ +def getCurrentScene(): + """ + Gets the current Scene. + + @rtype: L{KX_Scene} + """ def addActiveActuator(actuator, activate): """ Activates the given actuator. @@ -118,3 +124,4 @@ def stopDSP(): Only the fmod sound driver supports this. DSP can be computationally expensive. """ + diff --git a/source/gameengine/PyDoc/KX_MeshProxy.py b/source/gameengine/PyDoc/KX_MeshProxy.py index 41955c34345..f93cd5c1f7b 100644 --- a/source/gameengine/PyDoc/KX_MeshProxy.py +++ b/source/gameengine/PyDoc/KX_MeshProxy.py @@ -6,16 +6,56 @@ class KX_MeshProxy: A mesh object. You can only change the vertex properties of a mesh object, not the mesh topology. + + To use mesh objects effectively, you should know a bit about how the game engine handles them. + 1. Mesh Objects are converted from Blender at scene load. + 2. The Converter groups polygons by Material. This means they can be sent to the + renderer efficiently. A material holds: + 1. The texture. + 2. The Blender material. + 3. The Tile properties + 4. The face properties - (From the "Texture Face" panel) + 5. Transparency & z sorting + 6. Light layer + 7. Polygon shape (triangle/quad) + 8. Game Object + 3. Verticies will be split by face if necessary. Verticies can only be shared between + faces if: + 1. They are at the same position + 2. UV coordinates are the same + 3. Their normals are the same (both polygons are "Set Smooth") + 4. They are the same colour + For example: a cube has 24 verticies: 6 faces with 4 verticies per face. + + The correct method of iterating over every L{KX_VertexProxy} in a game object:: + import GameLogic + + co = GameLogic.getcurrentController() + obj = co.getOwner() + + m_i = 0 + mesh = obj.getMesh(m_i) # There can be more than one mesh... + while mesh != None: + for mat in range(mesh.getNumMaterials()): + for v_index in range(mesh.getVertexArrayLength(mat)): + vertex = mesh.getVertex(mat, v_index) + # Do something with vertex here... + # ... eg: colour the vertex red. + vertex.colour = [1.0, 0.0, 0.0, 1.0] + m_i += 1 + mesh = obj.getMesh(m_i) + + """ - def GetNumMaterials(): + def getNumMaterials(): """ Gets the number of materials associated with this object. @rtype: integer """ - def GetMaterialName(matid): + def getMaterialName(matid): """ Gets the name of the specified material. @@ -24,7 +64,7 @@ class KX_MeshProxy: @rtype: string @return: the attached material name. """ - def GetTextureName(matid): + def getTextureName(matid): """ Gets the name of the specified material's texture. @@ -33,7 +73,7 @@ class KX_MeshProxy: @rtype: string @return: the attached material's texture name. """ - def GetVertexArrayLength(matid): + def getVertexArrayLength(matid): """ Gets the length of the vertex array associated with the specified material. @@ -44,7 +84,7 @@ class KX_MeshProxy: @rtype: integer @return: the number of verticies in the vertex array. """ - def GetVertex(matid, index): + def getVertex(matid, index): """ Gets the specified vertex from the mesh object. diff --git a/source/gameengine/PyDoc/KX_SCA_ReplaceMeshActuator.py b/source/gameengine/PyDoc/KX_SCA_ReplaceMeshActuator.py index da1fbe6651e..63100e40532 100644 --- a/source/gameengine/PyDoc/KX_SCA_ReplaceMeshActuator.py +++ b/source/gameengine/PyDoc/KX_SCA_ReplaceMeshActuator.py @@ -6,13 +6,55 @@ class KX_SCA_ReplaceMeshActuator(SCA_IActuator): """ Edit Object actuator, in Replace Mesh mode. + Example:: + # Level-of-detail + # Switch a game object's mesh based on its depth in the camera view. + # +----------+ +-----------+ +-------------------------------------+ + # | Always +-----+ Python +-----+ Edit Object (Replace Mesh) LOD.Mesh | + # +----------+ +-----------+ +-------------------------------------+ + import GameLogic + + # List detail meshes here + # Mesh (name, near, far) + # Meshes overlap so that they don't 'pop' when on the edge of the distance. + meshes = ((".Hi", 0.0, -20.0), + (".Med", -15.0, -50.0), + (".Lo", -40.0, -100.0) + ) + + co = GameLogic.getCurrentController() + obj = co.getOwner() + act = co.getActuator("LOD." + obj.getName()) + cam = GameLogic.getCurrentScene().active_camera + + def Depth(pos, plane): + return pos[0]*plane[0] + pos[1]*plane[1] + pos[2]*plane[2] + plane[3] + + # Depth is negative and decreasing further from the camera + depth = Depth(obj.position, cam.world_to_camera[2]) + + newmesh = None + curmesh = None + # Find the lowest detail mesh for depth + for mesh in meshes: + if depth < mesh[1] and depth > mesh[2]: + newmesh = mesh + if "ME" + obj.getName() + mesh[0] == act.getMesh(): + curmesh = mesh + + if newmesh != None and "ME" + obj.getName() + newmesh[0] != act.getMesh(): + # The mesh is a different mesh - switch it. + # Check the current mesh is not a better fit. + if curmesh == None or curmesh[1] < depth or curmesh[2] > depth: + act.setMesh(obj.getName() + newmesh[0]) + GameLogic.addActiveActuator(act, True) + @warning: Replace mesh actuators will be ignored if at game start, the named mesh doesn't exist. This will generate a warning in the console: C{ERROR: GameObject I{OBName} ReplaceMeshActuator I{ActuatorName} without object} - """ def setMesh(name): """ @@ -20,4 +62,10 @@ class KX_SCA_ReplaceMeshActuator(SCA_IActuator): @type name: string """ + def getMesh(): + """ + Returns the name of the mesh that will replace the current one. + + @rtype: string + """ diff --git a/source/gameengine/PyDoc/KX_Scene.py b/source/gameengine/PyDoc/KX_Scene.py new file mode 100644 index 00000000000..2ba57dc9d78 --- /dev/null +++ b/source/gameengine/PyDoc/KX_Scene.py @@ -0,0 +1,68 @@ +# $Id$ +# Documentation for KX_Scene.py + +class KX_Scene: + """ + Scene. + + The activity culling stuff is supposed to disable logic bricks when their owner gets too far + from the active camera. It was taken from some code lurking at the back of KX_Scene - who knows + what it does! + + Example:: + import GameLogic + + # get the scene + scene = GameLogic.getCurrentScene() + + # print all the objects in the scene + for obj in scene.getObjectList(): + print obj.getName() + + # get an object named 'Cube' + obj = scene.getObjectList()["OBCube"] + + # get the first object in the scene. + obj = scene.getObjectList()[0] + + Example:: + # Get the depth of an object in the camera view. + import GameLogic + + obj = GameLogic.getCurrentController().getOwner() + cam = GameLogic.getCurrentScene().active_camera + + # Depth is negative and decreasing further from the camera + depth = obj.position[0]*cam.world_to_camera[2][0] + obj.position[1]*cam.world_to_camera[2][1] + obj.position[2]*cam.world_to_camera[2][2] + cam.world_to_camera[2][3] + + @ivar name: The scene's name + @type name: string + @ivar active_camera: The current active camera + @type active_camera: L{KX_Camera} + @ivar suspended: True if the scene is suspended. + @type suspended: boolean + @ivar activity_culling: True if the scene is activity culling + @type activity_culling: boolean + @ivar activity_culling_radius: The distance outside which to do activity culling. Measured in manhattan distance. + @type activity_culling_radius: float + """ + + def getLightList(): + """ + Returns the list of lights in the scene. + + @rtype: list [L{KX_Light}] + """ + def getObjectList(): + """ + Returns the list of objects in the scene. + + @rtype: list [L{KX_GameObject}] + """ + def getName(): + """ + Returns the name of the scene. + + @rtype: string + """ + |