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.

  • Participants
  • Parent commits 7be9185

Comments (0)

Files changed (21)

File CMakeLists.txt

     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")

File animation.pxi

         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
 

File blendfile.pxi

         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))
 
 
 

File collision.pxi

     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>"

File doc/index.rst

 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"

File gameobject.pxd

 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=*)
+

File gameobject.pxi

 
 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

File 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)
-    
-    
-        
-        
-        

File 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
-    

File 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()