Python updates:
authorKester Maddock <Christopher.Maddock.1@uni.massey.ac.nz>
Mon, 7 Jun 2004 11:03:12 +0000 (11:03 +0000)
committerKester Maddock <Christopher.Maddock.1@uni.massey.ac.nz>
Mon, 7 Jun 2004 11:03:12 +0000 (11:03 +0000)
Added scene module

14 files changed:
source/gameengine/Expressions/ListValue.cpp
source/gameengine/Expressions/PyObjectPlus.h
source/gameengine/Expressions/Value.h
source/gameengine/GameLogic/SCA_IScene.h
source/gameengine/Ketsji/KX_Camera.cpp
source/gameengine/Ketsji/KX_PythonInit.cpp
source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp
source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h
source/gameengine/Ketsji/KX_Scene.cpp
source/gameengine/Ketsji/KX_Scene.h
source/gameengine/PyDoc/GameLogic.py
source/gameengine/PyDoc/KX_MeshProxy.py
source/gameengine/PyDoc/KX_SCA_ReplaceMeshActuator.py
source/gameengine/PyDoc/KX_Scene.py [new file with mode: 0644]

index 3ee8a5a3501f98bc4f0655f4051a6e642c1ed85a..cd16377b5e33d5c43eadd49ef00dbb93e727b937 100644 (file)
@@ -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 */
 };
index 7c5f531f35b336b77778f053ae9c9f7d6f747b30..8a5e8ef2d7bbabaf08f4f8a61924e22f83c2e236 100644 (file)
@@ -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
index 4656e2ca5ac3e3cb8eca6fc543ecc4322b061379..d30e8a26d97548a40f6e6be93c40718f8cdb5f33 100644 (file)
@@ -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
index f49d4d3004c358bf63ab37a9a7472076d92dc2c2..d77c1dd648341220aa16367907c4b2ed96683e63 100644 (file)
@@ -42,7 +42,7 @@ struct SCA_DebugProp
        STR_String              m_name;
 };
 
-class SCA_IScene
+class SCA_IScene 
 {
        std::vector<SCA_DebugProp*> m_debugList;
 public:
index 4ed7b1e62d071193eaef9b40808ceb6d33454079..5d455a70ed18d9f937381bc50f6059e77ac1f1c4 100644 (file)
@@ -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;
 }
index f4736f4c4239cfda7869452dc73a31eedf92f2c2..1b6d55f68e9dbcc09f7b313e3c8bdcadf0a0a854 100644 (file)
@@ -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,
index 2480724986bd2e627bbdd3ef9422c739da240069..f26e9873863e8ac222cdd8e56d1988585f4e6e1f 100644 (file)
@@ -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                                                          */
index cc7bd8c9c6a7e8f46cde6765b66dcd53353d62e5..e38cf412539c4852c4199f4c0844163993c31928 100644 (file)
@@ -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);
 
 }; 
 
index 8f912642127d8be1120b1c5511b728d7284e1e8c..c274f05558d35488350eb0aba922dfab7a513c9c 100644 (file)
@@ -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());
+}
index a468a8d18619b285e6dd8bbd7dfdcf750e4e281c..c32cd4182aa087b5c45d8ea94a6fab9d757bdd7e 100644 (file)
@@ -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;
index b372cec0481d8d21790ac1e04b7c165295bef055..08f71e50f97bc7be57d0886106d494a453843f76 100644 (file)
@@ -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.
        """
+
index 41955c34345410cbf1facdb4330d06f936584b09..f93cd5c1f7ba63e3a2d27c4c4c2a05809d5201ad 100644 (file)
@@ -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.
                
index da1fbe6651e505e32eb00fc610478df0ab4f4324..63100e40532f6e8118aa8a9651130e91b5f03b76 100644 (file)
@@ -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 (file)
index 0000000..2ba57dc
--- /dev/null
@@ -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
+               """
+