Commits

Alberto Torres committed 171229c Draft

GameObjects and Entities can be created from Python code. Improved and
simplified syntax of singletons and object wrappings. More documentation.

Comments (0)

Files changed (21)

     collision.pxi
     controller.pxi
     engine.pxi
+    entity.pxd
+    entity.pxi
     sensor.pxi
     gamekit.pyx
     gameobject.pxd
     input.pxi
     mathutils.pxd
     mathutils.pyx
-    mesh.pxd
-    mesh.pxi
     prerequisites.pxd
     pywrap.pxd
     pywrap.pxi
 endif()
 
 find_program(CYTHON_EXECUTABLE cython)
+if (CYTHON_EXECUTABLE MATCHES "NOTFOUND")
+    set (CYTHON_EXECUTABLE cython)
+endif()
 
 # Cython integratin into gdb
 if (CMAKE_BUILD_TYPE MATCHES "Deb")
         ret = {}
         
         while it.hasMoreElements():
-            a = Animation().P(it.peekNextValue())
+            a = wrap(Animation, it.peekNextValue())
             a.ob = <gkGameObject*>self._p
             ret[it.peekNextKey().str().c_str()] = a
             it.next()
         cdef Animation a
         cdef gkAnimationPlayer *ap
         ap = (<gkGameObject*>self._p).getAnimationPlayer(gkString(item))
-        if ap==NULL:
+        if ap == NULL:
             ap = (<gkGameObject*>self._p).addAnimation(gkString(item))
-            if ap==NULL:
+            if ap == NULL:
                 return None
-        a = Animation().P(ap)
+        a = wrap(Animation, ap)
         a.ob = <gkGameObject*>self._p
         return a
 
         gkScene* getMainScene()
     
 cdef extern from "Loaders/Blender2/gkBlendLoader.h":
-    #cdef cppclass gkBlendLoader:
-    #    gkBlendFile* loadFile(gkString&, int, gkString&, gkString&)
-        
-    #glBlendLoader gkBlendLoaderGS "gkBlendLoader::getSingleton"()
-    # TODO: report this bug
-    
-    cdef gkBlendFile* loadFile "gkBlendLoader::getSingleton().loadFile"(gkString&, int, gkString&, gkString&)
+    cdef cppclass gkBlendLoader "gkBlendLoader::getSingleton":
+        gkBlendLoader()
+        gkBlendFile* loadFile(gkString&, int, gkString&, gkString&)
         
 
 ONLY_ACTIVE_SCENE        = 1 << 0   # Load only the active scene found.
 
     def load(self, filename, options = ONLY_ACTIVE_SCENE, scene = "", group = "", seek = 0):
         
-        self.bfile = loadFile(gkUtils_getFile(gkString(filename)), options, gkString(scene), gkString(group))
+        self.bfile = gkBlendLoader().loadFile(gkUtils_getFile(gkString(filename)), options, gkString(scene), gkString(group))
 
 
 
     property hit_objects:
         
         def __get__(self):
-            return GameObjectArray().P(self.objlist)
+            return wrap(GameObjectArray, self.objlist)
             
     def __str__(self):
         if self._test(): return "<Collision Active>"
 Welcome to PyGamekit's documentation!
 =====================================
 
+The Gamekit Python module has everything needed to make a game with Python.
+
+Report any missing feature to dithi (at) universodegoma.net.
+
 Contents:
 
 .. note::
         int                     sceneManager       # TODO scene manager to use
         gkString                log                # Main log file name
         bool                    verbose            # Enable/Disable Ogre print-out
-        gkVector2          winsize            # Window width & height
+        gkVector2               winsize            # Window width & height
         gkString                wintitle           # Window title
         gkString                extWinhandle       # External Window Handle
         bool                    fullscreen         # Fullscreen mode
         void addListener(pyEngineListener* listener)
         void removeListener(pyEngineListener* listener)
 
-    gkEngine* gkEngine_getSingleton "&(gkEngine::getSingleton)"()
+    gkEngine* gkEngine_getSingleton "&gkEngine::getSingleton"()
 
 
 #cdef extern from "gkApplication.h":
         gkString& getText()
 
 cdef extern from "gkTextManager.h":
-    void* gkTextManager_getByName "gkTextManager::getSingleton().getByName"(gkString&)
-    bool gkTextManager_exists "gkTextManager::getSingleton().exists"(gkString&)
+    cppclass gkTextManager "gkTextManager::getSingleton":
+        gkTextManager()
+        gkTextFile* getByName "getByName<gkTextFile>"(gkString&)
+        bool exists(gkString&)
 
 #----------------------------------------------------------------------------
 # Globals
 cdef bool initialized = False
 cdef Engine current_engine
     
-
-    
 cdef class Engine:
     cdef gkEngine *eng
     cdef gkClock *timer
     #cdef gkHUDManager* mgr
+    
+    cdef Scene _act_scene
 
     def __init__(self, bfile=None, cfgfile=None, initialize=True, seek=0):
         
         global initialized, current_engine
         
         if initialize:
-            if cfgfile:
-                prefs.load(gkString(cfgfile))
-                
-            self.eng = new gkEngine(prefs)
-            self.eng.initialize()
-            if not self.eng.isInitialized():
-                print("Failed to initialize enigne.")
-                sys.exit(1)
-            #self.mgr = new gkHUDManager()
+            if PLATFORM!="ANDROID":
+                if cfgfile:
+                    prefs.load(gkString(cfgfile))
+                    
+                self.eng = new gkEngine(prefs)
+                self.eng.initialize()
+                if not self.eng.isInitialized():
+                    print("Failed to initialize enigne.")
+                    sys.exit(1)
+                #self.mgr = new gkHUDManager()
 
-            if bfile:
-                self.load_blend(bfile, seek)
-                
-            self.eng.initializeStepLoop()
+                if bfile:
+                    self.load_blend(bfile, seek)
+                    
+                self.eng.initializeStepLoop()
+            else:
+                self.eng = gkEngine_getSingleton()
             
             self.timer = new gkClock()
             self.timer.reset()
             initialized = True
             current_engine = self
             
+            
     def __del__(self):
         self.eng.requestExit()
 
     property active_scene:
         def __get__(self):
-            return Scene().P(self.eng.getActiveScene())
+            cdef gkScene* s = self.eng.getActiveScene()
+            if self._act_scene is None or self._act_scene._p != <void*>s:
+                self._act_scene = wrap(Scene, s)
+            return self._act_scene
 
     def _step_one_frame(self):
         #try:
         scn = self.eng.getActiveScene()
         
         if scn:
-            copyObjects(b.bfile.getMainScene(), scn, OBJ_CAMERA | OBJ_LIGHT)
+            gkSceneManager().copyObjects(b.bfile.getMainScene(), scn, OBJ_CAMERA | OBJ_LIGHT)
         else:
             scn = b.bfile.getMainScene()
             
         evaluate_timer_callbacks()
         evaluate_tick_callbacks()
         
-def get_engine():
+cpdef public get_engine():
+    global current_engine
+    if current_engine is None:
+        current_engine = Engine()
+    return current_engine
+    
+    
+def get_act_scene():
     if current_engine!=None:
-        return current_engine
-    
-def get_active_scene():
-    cdef gkEngine* e = gkEngine_getSingleton()
-    return Scene().P(e.getActiveScene())
+        return current_engine.active_scene
 
 class TextBlockImporter(object):
     def find_module(self, module_name, package_path):
         if package_path: return
         module_name += '.py'
-        if initialized and gkTextManager_exists(gkString(module_name)):
+        if initialized and gkTextManager().exists(gkString(module_name)):
             return self
             
     def load_module(self, module_name):
         mod = imp.new_module(module_name)
         sys.modules[module_name] = mod
         module_name += '.py'
-        code = str((<gkTextFile*>gkTextManager_getByName(gkString(module_name))).getText().c_str())
+        code = str(gkTextManager().getByName(gkString(module_name)).getText().c_str())
         exec code in mod.__dict__
         return mod
 
 del TextBlockImporter
 
 def has_text_block(name):
-    if initialized: return gkTextManager_exists(gkString(name))
+    if initialized: return gkTextManager().exists(gkString(name))
     
 def get_text_block(name):
     if initialized:
-        return str((<gkTextFile*>gkTextManager_getByName(gkString(name))).getText().c_str())
+        return str(gkTextManager().getByName(gkString(name)).getText().c_str())
     
 def reload_init():
     pass
+
+
+from prerequisites cimport *
+from gameobject cimport *
+from gkmath cimport *
+
+cdef extern from "OgreMovableObject.h":
+
+    cdef cppclass Ogre_MovableObject "Ogre::MovableObject":
+        gkString& getMovableType()
+        
+    Ogre_Entity *cast_entity "static_cast<Ogre::Entity *>" (void *)
+    
+cdef extern from "OgreEntity.h":
+    enum:
+        VES_TANGENT "Ogre::VES_TANGENT"
+        
+    cdef cppclass Ogre_Entity "Ogre::Entity":
+        void buildTangentVectors "getMesh()->buildTangentVectors"(
+            int, unsigned short sourceTexCoordSet, unsigned short index, bool splitMirrored, bool splitRotated, bool storeParityInW)
+        
+        void reload "getMesh()->reload"()
+
+
+cdef extern from "gkEntity.h":
+    cppclass gkEntity(gkGameObject):
+        gkEntityProperties&  getEntityProperties()
+        gkMesh* getMesh()
+        gkSkeleton* getSkeleton()
+        void setSkeleton(gkSkeleton* skel)
+        void _resetPose()
+        void _destroyAsStaticGeometry()
+
+    cppclass gkEntityProperties:
+        gkMesh*         m_mesh
+        bool            m_casts
+        gkString        m_source
+        gkString        m_startPose
+
+cdef extern from "gkMesh.h":
+    cppclass btTriangleMesh
+    cppclass gkMeshLoader
+    
+    cppclass gkDeformVertex:
+        int      group
+        gkScalar weight
+        int      vertexId
+    
+    cppclass gkVertex:
+        gkVertex()
+        gkVertex(gkVertex &)
+        gkVertex&    assign "operator="(gkVertex &)
+        gkVector3    co
+        gkVector3    no
+        unsigned int vcol
+        gkVector2    *uv  # actually uv[GK_UV_MAK] = uv[8]
+        int          vba
+    
+    cdef enum TriFlag:
+        TRI_INVISIBLE "gkTriangle::TRI_INVISIBLE"
+        TRI_COLLIDER "gkTriangle::TRI_COLLIDER"
+        
+    struct gkTriangle:
+        unsigned int i0
+        unsigned int i1
+        unsigned int i2
+        int          flag
+    
+    struct gkTriFace:
+        gkVector3    *p  # actually p[3]
+        unsigned int i[3]
+        gkTriFace()
+        gkVector3    normal()
+    
+    cppclass gkSubMeshIndexer
+    
+    cppclass Verticies
+    cppclass Triangles
+    cppclass DeformVerts
+    
+    cppclass gkSubMesh:
+        gkSubMesh()
+        Verticies&            getVertexBuffer()
+        Triangles&            getIndexBuffer()
+        DeformVerts&          getDeformVertexBuffer()
+        gkString              getMaterialName()
+        void                  setMaterialName(gkString &)
+        void                  setTotalLayers(int)
+        int                   getUvLayerCount()
+        void                  setVertexColors(bool)
+        bool                  hasVertexColors()
+        #gkBoundingBox&        getBoundingBox()
+        #gkMaterialProperties& getMaterial()
+        gkSubMesh*            clone()
+        void                  addTriangle(gkVertex &, unsigned int, gkVertex &, unsigned int, gkVertex &, unsigned int, int)
+        void                  addDeformVert(gkDeformVertex &)
+    
+    cppclass gkVertexGroup:
+        gkVertexGroup(gkString &, int)
+        int       getIndex()
+        gkString& getName()
+    
+    ctypedef utArray[gkSubMesh*]             SubMeshArray "gkMesh::SubMeshArray"
+    ctypedef utArrayIterator[SubMeshArray]   SubMeshIterator "gkMesh::SubMeshIterator"
+    ctypedef utArray[gkVertexGroup*]         VertexGroups "gkMesh::VertexGroups"
+    
+    cppclass gkMesh:
+        #gkMesh(gkResourceManager *, gkResourceName &, gkResourceHandle &)
+        void                  addSubMesh(gkSubMesh *)
+        #void                  _setSkeleton(gkSkeletonResource *)
+        #gkSkeletonResource*   getSkeleton()
+        #gkBoundingBox&        getBoundingBox()
+        btTriangleMesh*       getTriMesh()
+        #gkMaterialProperties& getFirstMaterial()
+        gkVertexGroup*        createVertexGroup(gkString &)
+        VertexGroups&         getGroups()
+        gkVertexGroup*        findVertexGroup(gkString &)
+        gkVertexGroup*        findVertexGroup(int)
+        SubMeshIterator       getSubMeshIterator()
+        gkMeshLoader*         getLoader()
+        int                   getMeshVertexCount()
+        gkVertex&             getMeshVertex(int)
+        int                   getMeshTriFaceCount()
+        gkTriFace             getMeshTriFace(int)
+    
+cdef extern from "gkMeshManager.h":
+    cppclass gkMeshManager "gkMeshManager::getSingleton":
+        gkMeshManager()
+        gkMesh* create "create<gkMesh>"(gkString& name)
+        
+        
+        
+        
+
+from entity cimport *
+from gkmath cimport *
+
+cdef class Entity(GameObject):
+
+    def __init__(self, name='Unnamed'):
+        cdef gkEntity* ob
+        ob = gkGameObjectManager().createEntity(gkString(name))
+        if ob == NULL:
+            ob = gkGameObjectManager()\
+                .createEntity(getUniqueName(gkString(name)))
+        ob.getEntityProperties().m_mesh = gkMeshManager().create(ob.getName())
+        self._p = ob
+
+        
+    def buildTangentVectors(self, sourceTexCoordSet):
+        # (<gkEntity*>self._p).getNode().getAttachedObject(0).getMovableType().c_str() == "Entity"
+        cast_entity((<gkEntity*>self._p).getNode().getAttachedObject(0)).buildTangentVectors(VES_TANGENT, sourceTexCoordSet, 0, True, False, True)
+
+    def test(self):
+        cdef gkMesh *me = (<gkEntity*>self._p).getMesh()
+        #cdef SubMeshIterator smi = me.getSubMeshIterator()
+        #cdef gkSubMesh *sm = <gkSubMesh*>smi.getNext()
+        cdef gkSubMesh *sm = new gkSubMesh()
+        me.addSubMesh(sm)
+        sm.setMaterialName(gkString("Material"))
+        cdef gkVertex v0, v1, v2
+        i = me.getMeshVertexCount()
+        v0.co = gkVector3(2, 2, 0)
+        v2.co = gkVector3(2, -2, 0)
+        v1.co = gkVector3(-2, -2, 0)
+        v0.no = v1.no = v2.no = gkVector3(0,0,1)
+        v0.vba = i
+        v1.vba = i+1
+        v2.vba = i+2
+        sm.addTriangle(v0, i, v1, i+1, v2, i+2, TRI_COLLIDER)
+        
+        cast_entity((<gkEntity*>self._p).getNode().getAttachedObject(0)).reload()
+
+cdef class Mesh:
+
+    pass
+    
 include "actuator.pxi"
 include "gameobject.pxi"
 include "camera.pxi"
-include "mesh.pxi"
+include "entity.pxi"
 include "animation.pxi"
 include "collision.pxi"
 include "scene.pxi"
 from scene cimport *
 from collision cimport *
 from animation cimport *
-from mesh cimport *
 from gkmath cimport *
 
 #cdef class GameObject(pywrap):
     #pass
 
 cdef extern from "OgreSceneNode.h":
+    cppclass Ogre_MovableObject
+    
     cdef cppclass Ogre_SceneNode "Ogre::SceneNode":
         gkString& getName()
         void setVisible(bool,bool)
     cppclass gkScene
     
 cdef extern from "gkGameObject.h":
+
+    cppclass gkEntity
+    cppclass gkSkeleton
     
     cdef enum gkGameObjectTypes:
         GK_OB_NULL = 0
         GK_OBJECT
         GK_SKELETON
         GK_PARTICLES
+        
+    cppclass gkInstancedObject:
+        void createInstance(bool queue=*)
+        void destroyInstance(bool queue=*)
+        void reinstance(bool queue=*)
 
-    cdef cppclass gkGameObject:
+    cdef cppclass gkGameObject(gkInstancedObject):
+    
+        gkString&   getName()
+        gkString&   getGroupName()
         
         Ogre_SceneNode*          getNode()
         int getType()
         gkGameObjectProperties&   getProperties()
         
+        #void            setOwner(gkScene*)  # use scene methos instead
         gkScene*        getOwner()
         
         gkEntity*       getEntity()
         
         gkAnimations& getAnimations()
     
-    cppclass gkSkeleton
-    
-    cppclass gkEntity(gkGameObject):
-        void createInstance()
-        #gkEntityProperties&  getEntityProperties()
-        gkMesh* getMesh()
-        gkSkeleton* getSkeleton()
-        void setSkeleton(gkSkeleton* skel)
-        void _resetPose()
-        void _destroyAsStaticGeometry()
-
     enum gkGameObjectMode:
             GK_GHOST
             GK_ACTOR
         gkAnimationsIterator iterator()
         unsigned int size()
         
+cdef extern from "gkLight.h":
+    cppclass gkLight(gkGameObject)
         
+cdef extern from "Particles/gkParticleObject.h":
+    cppclass gkParticleObject(gkGameObject)
+        
+cdef extern from "gkGameObjectManager.h":
+    cppclass gkGameObjectManager "gkGameObjectManager::getSingleton":
+        gkGameObjectManager()
+        gkGameObject* createObject(gkString&)
+        gkLight* createLight(gkString&)
+        gkCamera* createCamera(gkString&)
+        gkEntity* createEntity(gkString&)
+        gkSkeleton* createSkeleton(gkString&)
+        gkParticleObject* createParticleObject(gkString&)
+
+        gkGameObject* getObject(gkString&)
+        gkLight* getLight(gkString&)
+        gkCamera* getCamera(gkString&)
+        gkEntity* getEntity(gkString&)
+        gkSkeleton* getSkeleton(gkString&)
+        gkParticleObject* getParticleObject(gkString&)
+        
+        void destroy(gkGameObject*)
+
+cdef extern from "gkResourceName.h":
+    cppclass gkResourceName:
+        gkResourceName()
+        gkResourceName(char* inName, char* inGroup=*)
+        gkResourceName(gkString& inName, gkString& inGroup=*)
+        #gkResourceName(gkHashedString& inName, gkHashedString& inGroup=*)
+
 
 from gkmath cimport *
 
-OBJECT_TYPES = 'NULL', 'CAMERA', 'LIGHT', 'ENTITY', 'OBJECT', 'SKELETON', 'PARTICLES'
+OBJECT_TYPES = (
+    'NULL',
+    'CAMERA',
+    'LIGHT',
+    'ENTITY',
+    'OBJECT',
+    'SKELETON',
+    'PARTICLES'
+)
 
 cdef to_GameObject(gkGameObject *ob):
     if ob!=NULL:
         t = ob.getType()
         if t == GK_ENTITY:
-            return Entity().P(ob)
+            return wrap(Entity, ob)
         elif t == GK_SKELETON:
-            return Skeleton().P(ob)
+            return wrap(Skeleton, ob)
         elif t == GK_CAMERA:
-            return Camera().P(ob)
+            return wrap(Camera, ob)
         else:
-            return GameObject().P(ob)
+            return wrap(GameObject, ob)
     else:
         return None
 
-cdef gkGameObject* cloneRecursiveImpl(gkGameObject* ob, int lifespan=0, bool instance=True):
+cdef gkGameObject* cloneRecursiveImpl(gkGameObject* ob,
+                                      int lifespan=0,
+                                      bool instance=True):
     
     cdef gkScene *scn = ob.getOwner()
     cdef gkGameObjectArrayIterator it = ob.getChildren().iterator()
     while it.hasMoreElements():
         c = it.getNext()
         ob2.removeChild(c)
-        # warning: assumes every mesh child of skeleton has skeletal animation
-        if ob.getType() == GK_SKELETON and c.getType() == GK_ENTITY and instance:
+        # Assumes every mesh child of skeleton has skeletal animation
+        # (Until we get parent-to-bone in gamekit)
+        if ob.getType() == GK_SKELETON and c.getType() == GK_ENTITY \
+                and instance:
             c2 = cloneRecursiveImpl(c, lifespan, False)
             e = <gkEntity *>c2
             e.setSkeleton(ob2.getSkeleton())
         ob2.addChild(c2)
         c2.setTransform(c.getTransform())
         
-        
     return ob2
 
+    
 cdef class GameObject(pywrap):
     '''
     All game objects are derived from this class.
     Properties can be read, assigned or deleted from game objects as items::
     
         my_object['my_property'] = 3
-        del(my_object['my_property'])
+        del my_object['my_property']
     
-    Properties can be booleans, integers, floats, strings, vectors or quaternions.
+    Properties can be booleans, integers, floats, strings, vectors or
+    quaternions.
     
+    You can create any object type and add it to a scene::
+    
+        ob = GameObject("some_name")
+        ob.scene = my_scene
+        # or:
+        my_scene.add_object(ob)
+        
+    If there is an object with the same name (globally), it will be assigned
+    a different name.
+        
+    Objects that aren't in a scene are destroyed when unallocated. Therefore
+    you may destroy objects when you remove them from the scene::
+        ob.scene = None
+        # or:
+        my_scene.remove_object(ob)
+        # now, if ob is unallocated, it will be destroyed
+        del ob
+        
+    If you must ensure an object is destroyed, use this instead::
+    
+        ob.destroy()
+        # or:
+        scene.destroy_object(ob)
+        
+    Any Python references to that object will become invalid.
+
     .. warning::
-        Accessing deleted objects will crash gamekit. In the future it will throw an error instead.
+        Accessing deleted objects will crash gamekit. In the future it will
+        throw an error instead.
     '''
     
+    # TODO: make this __cinit__, but not being executed with __new__?
+    def __init__(self, name='Unnamed'):
+        cdef gkGameObject* ob
+        ob = gkGameObjectManager().createObject(gkString(name))
+        if ob == NULL:
+            ob = gkGameObjectManager()\
+                .createObject(getUniqueName(gkString(name)))
+        self._p = ob
+            
+    def __dealloc__(self):
+        if (<gkGameObject*>self._p).getOwner() == NULL:
+            gkGameObjectManager().destroy(<gkGameObject*>self._p)
+            # TODO: mark as invalid
+            # TODO: detect non-python deallocations
+            
+    def destroy(self):
+        cdef gkGameObject* ob = <gkGameObject*>self._p
+        cdef gkScene* scn = ob.getOwner()
+        if scn != NULL:
+            scn.destroyObject(ob)
+        else:
+            gkGameObjectManager().destroy(<gkGameObject*>self._p)
+    
     @property
     def type(self):
         '''
         
         return OBJECT_TYPES[(<gkGameObject*>self._p).getType()]
             
-    @property
-    def name(self):
+    property name:
         '''
-        The name of the object. If it comes from a single .blend,
-        it can be assumed to be unique
+        The name of the object. It's guaranteed to be unique.
         '''
-        
-        cdef Ogre_SceneNode *n = (<gkGameObject*>self._p).getNode()
-        if n!=NULL: return str(n.getName().c_str())
-        return ""
+        def __get__(self):
+            return (<gkGameObject*>self._p).getName().c_str()
     
     def __getitem__(self,item):
         cdef gkVariable *v
     def __hash__(self):
         return str(self).__hash__()
         
-    def clone(self, name):
-        cdef gkString *s = new gkString()
-        return GameObject().P((<gkGameObject*>self._p).clone(s.assign(name)))
-        #TODO: use scn.cloneObject() instead
+    def clone(self, life_span=0, instantiate=True):
+        cdef gkGameObject *ob = <gkGameObject*>self._p
+        cdef gkScene* scn = ob.getOwner()
+        if scn==NULL:
+            ob = ob.clone(getUniqueName(ob.getName()))
+            return wrap(GameObject, ob)
+        else:
+            ob = scn.cloneObject(ob, life_span, instantiate)
         
     def clone_recursive(self, lifespan=0):
         '''
         '''
         cdef gkGameObject *ob = cloneRecursiveImpl(<gkGameObject*>self._p, lifespan)
         return to_GameObject(ob)
+        
+    property scene:
+        def __get__(self):
+            cdef gkScene *scn = (<gkGameObject*>self._p).getOwner()
+            if scn!=NULL:
+                return wrap(Scene, scn)
+        
+        def __set__(self, Scene scene):
+            cdef gkGameObject *ob = <gkGameObject*>self._p
+            cdef gkScene *scn
+            
+            scn = ob.getOwner()
+            if scn!=NULL:
+                scn.removeObject(ob)
+
+            scn = <gkScene*>scene._p
+            if scn!=NULL:
+                scn.addObject(ob)
+                ob.createInstance()
 
     property parent:
         '''
         '''
         Iterable containing all children of the game object.
         '''
-        return GameObjectArray().P(&((<gkGameObject*>self._p).getChildren()))
+        return wrap(GameObjectArray, &((<gkGameObject*>self._p).getChildren()))
         
     property position:
         '''
         Use animations['animation_name'] to get an animation and add it to this iterable.
         '''
         
-        return AnimationList().P(self._p)
+        return wrap(AnimationList, self._p)
         
     def add_sensor(self, Sensor sensor):
         '''
 
     property bones:
         def __get__(self):
-            return BoneList().P(self._p)
+            return wrap(BoneList, self._p)
 
 cdef class Bone(pywrap):
     
     def __getitem__(self, name):
         cdef gkBone *b = (<gkSkeleton*>self._p).getBone(gkString(name))
         if b:
-            return Bone().P(b)
+            return wrap(Bone, b)
         return None
 
 cdef class GameObjectList(pywrap):
         int buttons[3]
 
         
-cdef extern from "OgreKit.h":
-    
-    cdef gkKeyboard *getKeyboard "gkWindowSystem::getSingleton().getKeyboard"()
-    cdef gkMouse *getMouse "gkWindowSystem::getSingleton().getMouse"()
-    #m_joy      = gkWindowSystem::getSingleton().getJoystick(0);
+cdef extern from "gkWindowSystem.h":
+    cppclass gkWindowSystem "gkWindowSystem::getSingleton":
+        gkWindowSystem()
+        gkKeyboard *getKeyboard()
+        gkMouse *getMouse()
+        #m_joy      = gkWindowSystem::getSingleton().getJoystick(0);
             keycode = KEYS.index(keyname)
         except ValueError:
             raise WrongInputError('Key name not in '+str(KEYS))
-        self.key = getKeyboard().keys + keycode
+        self.key = gkWindowSystem().getKeyboard().keys + keycode
         self.keynum = keycode
         self.init_sensor(key_callbacks)
         
         if not 1<=button<=3:
             raise WrongInputError('Button must be between 1 and 3.')
         
-        self.but = &getMouse().buttons[button - 1]
+        self.but = &gkWindowSystem().getMouse().buttons[button - 1]
         self.butnum = button - 1
         self.init_sensor(mousebutton_callbacks)
     
     cdef gkKeyboard *keybd
     
     def __init__(self):
-        self.keybd = getKeyboard()
+        self.keybd = gkWindowSystem().getKeyboard()
         
     def getKey(self, code):
         return self.keybd.keys[code] == 1
     cdef int butnum
     
     def __init__(self, butnum=-1):
-        self.mouse = getMouse()
+        self.mouse = gkWindowSystem().getMouse()
         self.butnum = butnum
         self.init_sensor(mouse_move_callbacks)
         
 cdef class Accelerometer:
     cdef Vector v
     cdef gkVector3 *v3
+    cdef object ob
 
     def __init__(self):
         self.v = Vector()
         #self.v3 = <gkVector3 *>
+        self.ob = get_active_scene().objects['gravity']
         
     property value:
         def __get__(self):
-            if self.v3:
-                self.v3.assign((<Vector>self.v).v[0])
-            return self.v
+            return self.ob.position
 
 cdef void evaluate_input_callbacks() except *:
     global prev_mouse
-    cdef int k, *keys = getKeyboard().keys
-    cdef gkVector2 pos = getMouse().getPosition(), rel
+    cdef int k, *keys = gkWindowSystem().getKeyboard().keys
+    cdef gkVector2 pos = gkWindowSystem().getMouse().getPosition(), rel
     cdef Sensor e
-    cdef int *mousebuttons = getMouse().buttons, b
+    cdef int *mousebuttons = gkWindowSystem().getMouse().buttons, b
     
     for e in key_callbacks:
         k = (<Key>e).keynum

mesh.pxd

-
-
-from prerequisites cimport *
-from gameobject cimport *
-from gkmath cimport *
-
-cdef extern from "OgreMovableObject.h":
-
-    cdef cppclass Ogre_MovableObject "Ogre::MovableObject":
-        gkString& getMovableType()
-        
-    Ogre_Entity *cast_entity "static_cast<Ogre::Entity *>" (void *)
-    
-cdef extern from "OgreEntity.h":
-    enum:
-        VES_TANGENT "Ogre::VES_TANGENT"
-        
-    cdef cppclass Ogre_Entity "Ogre::Entity":
-        void buildTangentVectors "getMesh()->buildTangentVectors"(
-            int, unsigned short sourceTexCoordSet, unsigned short index, bool splitMirrored, bool splitRotated, bool storeParityInW)
-        
-        void reload "getMesh()->reload"()
-
-
-cdef extern from "gkMesh.h":
-    cppclass btTriangleMesh
-    cppclass gkMeshLoader
-    
-    cppclass gkDeformVertex:
-        int      group
-        gkScalar weight
-        int      vertexId
-    
-    cppclass gkVertex:
-        gkVertex()
-        gkVertex(gkVertex &)
-        gkVertex&    assign "operator="(gkVertex &)
-        gkVector3    co
-        gkVector3    no
-        unsigned int vcol
-        gkVector2    *uv  # actually uv[GK_UV_MAK] = uv[8]
-        int          vba
-    
-    cdef enum TriFlag:
-        TRI_INVISIBLE "gkTriangle::TRI_INVISIBLE"
-        TRI_COLLIDER "gkTriangle::TRI_COLLIDER"
-        
-    struct gkTriangle:
-        unsigned int i0
-        unsigned int i1
-        unsigned int i2
-        int          flag
-    
-    struct gkTriFace:
-        gkVector3    *p  # actually p[3]
-        unsigned int i[3]
-        gkTriFace()
-        gkVector3    normal()
-    
-    cppclass gkSubMeshIndexer
-    
-    cppclass Verticies
-    cppclass Triangles
-    cppclass DeformVerts
-    
-    cppclass gkSubMesh:
-        gkSubMesh()
-        Verticies&            getVertexBuffer()
-        Triangles&            getIndexBuffer()
-        DeformVerts&          getDeformVertexBuffer()
-        gkString              getMaterialName()
-        void                  setMaterialName(gkString &)
-        void                  setTotalLayers(int)
-        int                   getUvLayerCount()
-        void                  setVertexColors(bool)
-        bool                  hasVertexColors()
-        #gkBoundingBox&        getBoundingBox()
-        #gkMaterialProperties& getMaterial()
-        gkSubMesh*            clone()
-        void                  addTriangle(gkVertex &, unsigned int, gkVertex &, unsigned int, gkVertex &, unsigned int, int)
-        void                  addDeformVert(gkDeformVertex &)
-    
-    cppclass gkVertexGroup:
-        gkVertexGroup(gkString &, int)
-        int       getIndex()
-        gkString& getName()
-    
-    ctypedef utArray[gkSubMesh*]             SubMeshArray "gkMesh::SubMeshArray"
-    ctypedef utArrayIterator[SubMeshArray]   SubMeshIterator "gkMesh::SubMeshIterator"
-    ctypedef utArray[gkVertexGroup*]         VertexGroups "gkMesh::VertexGroups"
-    
-    cppclass gkMesh:
-        #gkMesh(gkResourceManager *, gkResourceName &, gkResourceHandle &)
-        void                  addSubMesh(gkSubMesh *)
-        #void                  _setSkeleton(gkSkeletonResource *)
-        #gkSkeletonResource*   getSkeleton()
-        #gkBoundingBox&        getBoundingBox()
-        btTriangleMesh*       getTriMesh()
-        #gkMaterialProperties& getFirstMaterial()
-        gkVertexGroup*        createVertexGroup(gkString &)
-        VertexGroups&         getGroups()
-        gkVertexGroup*        findVertexGroup(gkString &)
-        gkVertexGroup*        findVertexGroup(int)
-        SubMeshIterator       getSubMeshIterator()
-        gkMeshLoader*         getLoader()
-        int                   getMeshVertexCount()
-        gkVertex&             getMeshVertex(int)
-        int                   getMeshTriFaceCount()
-        gkTriFace             getMeshTriFace(int)
-    
-    
-        
-        
-        

mesh.pxi

-
-from mesh cimport *
-from gkmath cimport *
-
-cdef inline gkEntity* unwrap(Entity e):
-    return <gkEntity*>e._p
-
-cdef class Entity(GameObject):
-    
-    def buildTangentVectors(self, sourceTexCoordSet):
-        # (<gkEntity*>self._p).getNode().getAttachedObject(0).getMovableType().c_str() == "Entity"
-        cast_entity((<gkEntity*>self._p).getNode().getAttachedObject(0)).buildTangentVectors(VES_TANGENT, sourceTexCoordSet, 0, True, False, True)
-
-    #def test(self):
-        #cdef gkMesh *me = unwrap(self).getMesh()
-        #cdef SubMeshIterator smi = me.getSubMeshIterator()
-        #cdef gkSubMesh *sm = <gkSubMesh*>smi.getNext()
-        #cdef gkVertex v0, v1, v2
-        #i = me.getMeshVertexCount()
-        #v0.co = gkVector3(2, 2, 0)
-        #v2.co = gkVector3(2, -2, 0)
-        #v1.co = gkVector3(-2, -2, 0)
-        #v0.no = v1.no = v2.no = gkVector3(0,0,1)
-        #v0.vba = i
-        #v1.vba = i+1
-        #v2.vba = i+2
-        #sm.addTriangle(v0, i, v1, i+1, v2, i+2, TRI_COLLIDER)
-        
-        #cast_entity((<gkEntity*>self._p).getNode().getAttachedObject(0)).reload()
-
-cdef class Mesh:
-
-    pass
-    

prerequisites.pxd

         gkString& assign ( char* s )
         #gkString& assign ( size_t n, char c )
         
+cdef extern from "gkUtils.h" namespace "gkUtils":
+    cdef gkString getUniqueName(gkString&)
+        
 cdef extern from "utTypes.h":
     ctypedef unsigned int UTsize  # not exactly true
     
             return self._p != other._p
         return False
         
-    cdef pywrap P(self, void *p):
-        (<pywrap>self)._p = p
-        return self
+    #cdef inline pywrap P(self, void *p):
+        #(<pywrap>self)._p = p
+        #return self
 
-# TODO: instead of SomeObject().P(pointer) try SomeObject.__new__(SomeObject).P(pointer)
-#       and comapre the speedup (as it won't have to call __init__, etc)
-#       (maybe change it here to be SomeObject.P(pointer)?)
-
+cdef inline wrap(wtype, void *p):
+    ret = wtype.__new__(wtype)
+    (<pywrap>ret)._p = p
+    return ret
+        
+# TODO: The functions should return the same pyobject for the same gkobject
     
     cdef cppclass gkScene:
         
+        gkString&   getName()
+        gkString&   getGroupName()
+
         gkCamera*     getMainCamera()
         bool          hasDefaultCamera()
         bool          hasCameras()
         
 cdef extern from "gkSceneManager.h":
     
-    cdef gkScene* createEmptyScene "gkSceneManager::getSingleton().createEmptyScene"(
-                                    gkString& sceneName, gkString& cameraName=*, gkString& group=*)
-    cdef gkScene* copyObjects "gkSceneManager::getSingleton().copyObjects"(gkScene* fromScene, gkScene* toScene, int exceptObjectTypes)
+    cppclass gkSceneManager "gkSceneManager::getSingleton":
+        gkSceneManager()
+        gkScene* createEmptyScene(gkString& sceneName, gkString& cameraName=*, gkString& group=*)
+        gkScene* copyObjects(gkScene* fromScene, gkScene* toScene, int exceptObjectTypes)
     
 
 #cdef extern from "gkDynamicsWorld.h":
     
     def __init__(self):
         self.tickSensor = TickSensor()
-
-    #def setTerrain(self):
-        #self.terrain = new Ogre_Terrain((<gkScene *>self._p).getManager())
-        #cdef Ogre_StringVector tlist
-        #tlist.push_back(gkString("terrain.png"))
-        #self.terrain.addLayer(300.0, &tlist)
-        #self.terrain.dirty()
-        #self.terrain.update()
-        #self.terrain.updateGeometry()
+        
+    property name:
+        '''
+        The name of the scene. It's guaranteed to be unique.
+        '''
+        def __get__(self):
+            return (<gkScene*>self._p).getName().c_str()
         
     property gravity:
         def __get__(self):
     
     property main_camera:
         def __get__(self):
-            return Camera().P((<gkScene *>self._p).getMainCamera())
+            return wrap(Camera, (<gkScene *>self._p).getMainCamera())
         
         def __set__(self, Camera cam):
             (<gkScene *>self._p).setMainCamera(<gkCamera *>cam._p)
         
     def add_object(self, GameObject ob):
-        (<gkScene *>self._p).addObject(<gkGameObject *>ob._p)
+        cdef gkGameObject* gkob = <gkGameObject *>ob._p
+        (<gkScene *>self._p).addObject(gkob)
+        gkob.reinstance()
         
     def remove_object(self, GameObject ob):
-        (<gkScene *>self._p).removeObject(<gkGameObject *>ob._p)
+        cdef gkGameObject* gkob = <gkGameObject *>ob._p
+        (<gkScene *>self._p).removeObject(gkob)
+        gkob.destroyInstance()
         
     def destroy_object(self, GameObject ob):
         (<gkScene *>self._p).destroyObject(<gkGameObject *>ob._p)
     def clone_object(self, GameObject ob, lifeSpan=0, instantiate=False):
         cdef gkGameObject* o = <gkGameObject *>ob._p
         o = (<gkScene *>self._p).cloneObject(o, lifeSpan, instantiate)
-        return GameObject().P(o)
+        return wrap(GameObject, o)
 
     @property
     def objects(self):
-        return GameObjectList().P(self._p)
+        return wrap(GameObjectList, self._p)
         
     def suspend_dynamics(Scene self):
         (<gkScene *>self._p).setUpdateFlags((<gkScene *>self._p).getUpdateFlags()&~UF_PHYSICS)
     cppclass gkSoundStream
     
 cdef extern from "Sound/gkSoundManager.h":
-    gkSound* gkSoundManager_getByName "gkSoundManager::getSingleton().getByName<gkSound>"(gkString&)
-    gkSound* gkSoundManager_create "gkSoundManager::getSingleton().create<gkSound>"(gkString&)
-    void stopAllSounds "gkSoundManager::getSingleton().stopAllSounds"()
+    cppclass gkSoundManager "gkSoundManager::getSingleton":
+        gkSound* getByName "getByName<gkSound>"(gkString&)
+        gkSound* create "create<gkSound>"(gkString&)
+        void stopAllSounds()
 
 #cdef extern from "gkResourceName.h":
     #cppclass gkResourceName:
     cdef gkSoundProperties *props
     
     def __init__(self, name):
-        self.sound = gkSoundManager_getByName(gkString(name))
+        self.sound = gkSoundManager().getByName(gkString(name))
         
         if self.sound:
             self.player = self.sound.createSource()