Merging with trunk up to r38631.
[blender.git] / source / gameengine / Ketsji / KX_Scene.cpp
index 9e2545f41ccdb6de0185a63b582f99bb8144d192..a49c1bf4b4cbd48f918ae500277b73d55d786cff 100644 (file)
  * Ketsji scene. Holds references to all scene data.
  */
 
+/** \file gameengine/Ketsji/KX_Scene.cpp
+ *  \ingroup ketsji
+ */
+
+
 #if defined(WIN32) && !defined(FREE_WINDOWS)
 #pragma warning (disable : 4786)
 #endif //WIN32
@@ -62,7 +67,7 @@
 #include "SCA_IController.h"
 #include "SCA_IActuator.h"
 #include "SG_Node.h"
-#include "SYS_System.h"
+#include "BL_System.h"
 #include "SG_Controller.h"
 #include "SG_IObject.h"
 #include "SG_Tree.h"
 
 #ifdef USE_BULLET
 #include "KX_SoftBodyDeformer.h"
-#endif
-
-// to get USE_BULLET!
 #include "KX_ConvertPhysicsObject.h"
-
-#ifdef USE_BULLET
 #include "CcdPhysicsEnvironment.h"
 #include "CcdPhysicsController.h"
 #endif
@@ -213,7 +213,7 @@ KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice,
 
        m_bucketmanager=new RAS_BucketManager();
        
-#ifndef DISABLE_PYTHON
+#ifdef WITH_PYTHON
        m_attr_dict = PyDict_New(); /* new ref */
        m_draw_call_pre = NULL;
        m_draw_call_post = NULL;
@@ -267,12 +267,14 @@ KX_Scene::~KX_Scene()
                delete m_bucketmanager;
        }
 
-#ifndef DISABLE_PYTHON
+#ifdef WITH_PYTHON
        PyDict_Clear(m_attr_dict);
-       Py_DECREF(m_attr_dict);
+       /* Py_CLEAR: Py_DECREF's and NULL's */
+       Py_CLEAR(m_attr_dict);
 
-       Py_XDECREF(m_draw_call_pre);
-       Py_XDECREF(m_draw_call_post);
+       /* these may be NULL but the macro checks */
+       Py_CLEAR(m_draw_call_pre);
+       Py_CLEAR(m_draw_call_post);
 #endif
 }
 
@@ -328,7 +330,10 @@ list<class KX_Camera*>* KX_Scene::GetCameras()
        return &m_cameras;
 }
 
-
+list<class KX_FontObject*>* KX_Scene::GetFonts()
+{
+       return &m_fonts;
+}
 
 void KX_Scene::SetFramingType(RAS_FrameSettings & frame_settings)
 {
@@ -817,6 +822,8 @@ SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject,
                // add a timebomb to this object
                // for now, convert between so called frames and realtime
                m_tempObjectList->Add(replica->AddRef());
+               // this convert the life from frames to sort-of seconds, hard coded 0.02 that assumes we have 50 frames per second
+               // if you change this value, make sure you change it in KX_GameObject::pyattr_get_life property too
                CValue *fval = new CFloatValue(lifespan*0.02);
                replica->SetProperty("::timebomb",fval);
                fval->Release();
@@ -1017,6 +1024,9 @@ int KX_Scene::NewRemoveObject(class CValue* gameobj)
        // in case this is a camera
        m_cameras.remove((KX_Camera*)newobj);
 
+       // in case this is a font
+       m_fonts.remove((KX_FontObject*)newobj);
+
        /* currently does nothing, keep incase we need to Unregister something */
 #if 0
        if (m_sceneConverter)
@@ -1076,8 +1086,9 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj, bool use_gfx, bool u
                                blendobj->parent &&                                                     // original object had armature (not sure this test is needed)
                                blendobj->parent->type == OB_ARMATURE &&
                                blendmesh->dvert!=NULL;                                         // mesh has vertex group
+#ifdef USE_BULLET
                        bool bHasSoftBody = (!parentobj && (blendobj->gameflag & OB_SOFT_BODY));
-
+#endif
                        bool releaseParent = true;
 
                        
@@ -1190,6 +1201,27 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj, bool use_gfx, bool u
 #endif
 }
 
+/* Font Object routines */
+void KX_Scene::AddFont(KX_FontObject* font)
+{
+       if (!FindFont(font))
+               m_fonts.push_back(font);
+}
+
+KX_FontObject* KX_Scene::FindFont(KX_FontObject* font)
+{
+       list<KX_FontObject*>::iterator it = m_fonts.begin();
+
+       while ( (it != m_fonts.end()) 
+                       && ((*it) != font) ) {
+         ++it;
+       }
+
+       return ((it == m_fonts.end()) ? NULL : (*it));
+}
+
+
+/* Camera Object routines */
 KX_Camera* KX_Scene::FindCamera(KX_Camera* cam)
 {
        list<KX_Camera*>::iterator it = m_cameras.begin();
@@ -1470,7 +1502,12 @@ void KX_Scene::LogicBeginFrame(double curtime)
        m_logicmgr->BeginFrame(curtime, 1.0/KX_KetsjiEngine::GetTicRate());
 }
 
-
+void KX_Scene::UpdateAnimations(double curtime)
+{
+       // Update any animations
+       for (int i=0; i<GetObjectList()->GetCount(); ++i)
+               ((KX_GameObject*)GetObjectList()->GetValue(i))->UpdateActionManager(curtime);
+}
 
 void KX_Scene::LogicUpdateFrame(double curtime, bool frame)
 {
@@ -1482,7 +1519,7 @@ void KX_Scene::LogicUpdateFrame(double curtime, bool frame)
 void KX_Scene::LogicEndFrame()
 {
        m_logicmgr->EndFrame();
-       int numobj = m_euthanasyobjects->GetCount();
+       int numobj;
 
        KX_GameObject* obj;
 
@@ -1636,6 +1673,11 @@ double KX_Scene::getSuspendedDelta()
        return m_suspendeddelta;
 }
 
+short KX_Scene::GetAnimationFPS()
+{
+       return m_blenderScene->r.frs_sec;
+}
+
 #ifdef USE_BULLET
 #include "KX_BulletPhysicsController.h"
 #endif
@@ -1724,6 +1766,11 @@ static void MergeScene_GameObject(KX_GameObject* gameobj, KX_Scene *to, KX_Scene
        if(sg) {
                if(sg->GetSGClientInfo() == from) {
                        sg->SetSGClientInfo(to);
+
+                       /* Make sure to grab the children too since they might not be tied to a game object */
+                       NodeList children = sg->GetSGChildren();
+                       for (int i=0; i<children.size(); i++)
+                                       children[i]->SetSGClientInfo(to);
                }
 #ifdef USE_BULLET
                SGControllerList::iterator contit;
@@ -1827,6 +1874,16 @@ bool KX_Scene::MergeScene(KX_Scene *other)
 
                        /* when merging objects sensors are moved across into the new manager, dont need to do this here */
                }
+
+               /* grab any timer properties from the other scene */
+               SCA_TimeEventManager *timemgr=          GetTimeEventManager();
+               SCA_TimeEventManager *timemgr_other=    other->GetTimeEventManager();
+               vector<CValue*> times = timemgr_other->GetTimeValues();
+
+               for(unsigned int i= 0; i < times.size(); i++) {
+                       timemgr->AddTimeProperty(times[i]);
+               }
+               
        }
        return true;
 }
@@ -1841,7 +1898,7 @@ void KX_Scene::Render2DFilters(RAS_ICanvas* canvas)
        m_filtermanager.RenderFilters(canvas);
 }
 
-#ifndef DISABLE_PYTHON
+#ifdef WITH_PYTHON
 
 void KX_Scene::RunDrawingCallbacks(PyObject* cb_list)
 {
@@ -2089,8 +2146,7 @@ PyObject* KX_Scene::pyattr_get_drawing_callback_pre(void *self_v, const KX_PYATT
 
        if(self->m_draw_call_pre==NULL)
                self->m_draw_call_pre= PyList_New(0);
-       else
-               Py_INCREF(self->m_draw_call_pre);
+       Py_INCREF(self->m_draw_call_pre);
        return self->m_draw_call_pre;
 }
 
@@ -2100,8 +2156,7 @@ PyObject* KX_Scene::pyattr_get_drawing_callback_post(void *self_v, const KX_PYAT
 
        if(self->m_draw_call_post==NULL)
                self->m_draw_call_post= PyList_New(0);
-       else
-               Py_INCREF(self->m_draw_call_post);
+       Py_INCREF(self->m_draw_call_post);
        return self->m_draw_call_post;
 }
 
@@ -2251,4 +2306,4 @@ KX_PYMETHODDEF_DOC(KX_Scene, get, "")
        return def;
 }
 
-#endif // DISABLE_PYTHON
+#endif // WITH_PYTHON