2nd try to merge sim_physics with trunk rev 19825
[blender.git] / source / gameengine / Ketsji / KX_Scene.cpp
index 30fed561519a1a12584faa42e99ba409e14a7b8c..96f2f3e8ed391210f1efeb0f7e737367b0fc183f 100644 (file)
@@ -91,6 +91,8 @@
 #include "CcdPhysicsController.h"
 #endif
 
+#include "KX_Light.h"
+
 void* KX_SceneReplicationFunc(SG_IObject* node,void* gameobj,void* scene)
 {
        KX_GameObject* replica = ((KX_Scene*)scene)->AddNodeReplicaObject(node,(KX_GameObject*)gameobj);
@@ -136,6 +138,7 @@ KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice,
        m_suspendeddelta = 0.0;
 
        m_dbvt_culling = false;
+       m_dbvt_occlusion_res = 0;
        m_activity_culling = false;
        m_suspend = false;
        m_isclearingZbuffer = true;
@@ -193,7 +196,7 @@ KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice,
        m_canvasDesignWidth = 0;
        m_canvasDesignHeight = 0;
        
-       m_attrlist = PyDict_New(); /* new ref */
+       m_attr_dict = PyDict_New(); /* new ref */
 }
 
 
@@ -247,7 +250,8 @@ KX_Scene::~KX_Scene()
        {
                delete m_bucketmanager;
        }
-       Py_DECREF(m_attrlist);
+       PyDict_Clear(m_attr_dict);
+       Py_DECREF(m_attr_dict);
 }
 
 void KX_Scene::SetProjectionMatrix(MT_CmMatrix4x4& pmat)
@@ -714,9 +718,9 @@ void KX_Scene::DupliGroupRecurse(CValue* obj, int level)
 
                MT_Matrix3x3 newori = groupobj->NodeGetWorldOrientation() * gameobj->NodeGetWorldOrientation();
                replica->NodeSetLocalOrientation(newori);
-
+               MT_Point3 offset(group->dupli_ofs);
                MT_Point3 newpos = groupobj->NodeGetWorldPosition() + 
-                       newscale*(groupobj->NodeGetWorldOrientation() * gameobj->NodeGetWorldPosition());
+                       newscale*(groupobj->NodeGetWorldOrientation() * (gameobj->NodeGetWorldPosition()-offset));
                replica->NodeSetLocalPosition(newpos);
 
                replica->GetSGNode()->UpdateWorldData(0);
@@ -741,6 +745,12 @@ void KX_Scene::DupliGroupRecurse(CValue* obj, int level)
                (*git)->Relink(&m_map_gameobject_to_replica);
                // add the object in the layer of the parent
                (*git)->SetLayer(groupobj->GetLayer());
+               // If the object was a light, we need to update it's RAS_LightObject as well
+               if ((*git)->IsLight())
+               {
+                       KX_LightObject* lightobj = static_cast<KX_LightObject*>(*git);
+                       lightobj->GetLightData()->m_layer = groupobj->GetLayer();
+               }
        }
 
        // replicate crosslinks etc. between logic bricks
@@ -841,6 +851,12 @@ SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject,
                (*git)->Relink(&m_map_gameobject_to_replica);
                // add the object in the layer of the parent
                (*git)->SetLayer(parentobj->GetLayer());
+               // If the object was a light, we need to update it's RAS_LightObject as well
+               if ((*git)->IsLight())
+               {
+                       KX_LightObject* lightobj = static_cast<KX_LightObject*>(*git);
+                       lightobj->GetLightData()->m_layer = parentobj->GetLayer();
+               }
        }
 
        // replicate crosslinks etc. between logic bricks
@@ -982,6 +998,7 @@ int KX_Scene::NewRemoveObject(class CValue* gameobj)
        if (m_sceneConverter)
                m_sceneConverter->UnregisterGameObject(newobj);
        // return value will be 0 if the object is actually deleted (all reference gone)
+       
        return ret;
 }
 
@@ -1338,17 +1355,18 @@ void KX_Scene::CalculateVisibleMeshes(RAS_IRasterizer* rasty,KX_Camera* cam, int
        if (m_dbvt_culling) 
        {
                // test culling through Bullet
-               PHY__Vector4 planes[5];
+               PHY__Vector4 planes[6];
                // get the clip planes
                MT_Vector4* cplanes = cam->GetNormalizedClipPlanes();
                // and convert
-               planes[0].setValue(cplanes[0].getValue());
-               planes[1].setValue(cplanes[1].getValue());
-               planes[2].setValue(cplanes[2].getValue());
-               planes[3].setValue(cplanes[3].getValue());
-               planes[4].setValue(cplanes[5].getValue());
+               planes[0].setValue(cplanes[4].getValue());      // near
+               planes[1].setValue(cplanes[5].getValue());      // far
+               planes[2].setValue(cplanes[0].getValue());      // left
+               planes[3].setValue(cplanes[1].getValue());      // right
+               planes[4].setValue(cplanes[2].getValue());      // top
+               planes[5].setValue(cplanes[3].getValue());      // bottom
                CullingInfo info(layer);
-               dbvt_culling = m_physicsEnvironment->cullingTest(PhysicsCullingCallback,&info,planes,5);
+               dbvt_culling = m_physicsEnvironment->cullingTest(PhysicsCullingCallback,&info,planes,5,m_dbvt_occlusion_res);
        }
        if (!dbvt_culling) {
                // the physics engine couldn't help us, do it the hard way
@@ -1564,9 +1582,9 @@ PyTypeObject KX_Scene::Type = {
        PyObject_HEAD_INIT(NULL)
                0,
                "KX_Scene",
-               sizeof(KX_Scene),
+               sizeof(PyObjectPlus_Proxy),
                0,
-               PyDestructor,
+               py_base_dealloc,
                0,
                0,
                0,
@@ -1603,25 +1621,25 @@ PyObject* KX_Scene::pyattr_get_name(void *self_v, const KX_PYATTRIBUTE_DEF *attr
 PyObject* KX_Scene::pyattr_get_objects(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
 {
        KX_Scene* self= static_cast<KX_Scene*>(self_v);
-       return self->GetObjectList()->AddRef();
+       return self->GetObjectList()->GetProxy();
 }
 
 PyObject* KX_Scene::pyattr_get_active_camera(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
 {
        KX_Scene* self= static_cast<KX_Scene*>(self_v);
-       return self->GetActiveCamera()->AddRef();
+       return self->GetActiveCamera()->GetProxy();
 }
 
 /* __dict__ only for the purpose of giving useful dir() results */
 PyObject* KX_Scene::pyattr_get_dir_dict(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
 {
        KX_Scene* self= static_cast<KX_Scene*>(self_v);
-       /* Useually done by py_getattro_up but in this case we want to include m_attrlist dict */
+       /* Useually done by py_getattro_up but in this case we want to include m_attr_dict dict */
        PyObject *dict_str= PyString_FromString("__dict__");
        PyObject *dict= py_getattr_dict(self->PyObjectPlus::py_getattro(dict_str), Type.tp_dict);
        Py_DECREF(dict_str);
        
-       PyDict_Update(dict, self->m_attrlist);
+       PyDict_Update(dict, self->m_attr_dict);
        return dict;
 }
 
@@ -1637,30 +1655,59 @@ PyAttributeDef KX_Scene::Attributes[] = {
        { NULL }        //Sentinel
 };
 
+
+PyObject* KX_Scene::py_getattro__internal(PyObject *attr)
+{      
+       py_getattro_up(PyObjectPlus);
+}
+
+int KX_Scene::py_setattro__internal(PyObject *attr, PyObject *pyvalue)
+{
+       return PyObjectPlus::py_setattro(attr, pyvalue);
+}
+
 PyObject* KX_Scene::py_getattro(PyObject *attr)
 {
-       PyObject *object = PyDict_GetItem(m_attrlist, attr);
-       if (object)
+       PyObject *object = py_getattro__internal(attr);
+       
+       if (object==NULL)
        {
-               Py_INCREF(object);
-               return object;
+               PyErr_Clear();
+               object = PyDict_GetItem(m_attr_dict, attr);
+               if(object) {
+                       Py_INCREF(object);
+               }
+               else {
+                       PyErr_Format(PyExc_AttributeError, "KX_Scene attribute \"%s\" not found", PyString_AsString(attr));
+               }
        }
        
-       py_getattro_up(PyObjectPlus);
+       return object;
 }
 
-int KX_Scene::py_delattro(PyObject *attr)
+
+int KX_Scene::py_setattro(PyObject *attr, PyObject *value)
 {
-       PyDict_DelItem(m_attrlist, attr);
-       return 0;
+       int ret= py_setattro__internal(attr, value);
+       
+       if (ret==PY_SET_ATTR_MISSING) {
+               if (PyDict_SetItem(m_attr_dict, attr, value)==0) {
+                       PyErr_Clear();
+                       ret= PY_SET_ATTR_SUCCESS;
+               }
+               else {
+                       PyErr_SetString(PyExc_AttributeError, "failed assigning value to KX_Scenes internal dictionary");
+                       ret= PY_SET_ATTR_FAIL;
+               }
+       }
+       
+       return ret;
 }
 
-int KX_Scene::py_setattro(PyObject *attr, PyObject *pyvalue)
+int KX_Scene::py_delattro(PyObject *attr)
 {
-       if (!PyDict_SetItem(m_attrlist, attr, pyvalue))
-               return 0;
-
-       return PyObjectPlus::py_setattro(attr, pyvalue);
+       PyDict_DelItem(m_attr_dict, attr);
+       return 0;
 }
 
 KX_PYMETHODDEF_DOC_NOARGS(KX_Scene, getLightList,
@@ -1668,7 +1715,7 @@ KX_PYMETHODDEF_DOC_NOARGS(KX_Scene, getLightList,
 "Returns a list of all lights in the scene.\n"
 )
 {
-       return (PyObject*) m_lightlist->AddRef();
+       return m_lightlist->GetProxy();
 }
 
 KX_PYMETHODDEF_DOC_NOARGS(KX_Scene, getObjectList,
@@ -1677,7 +1724,7 @@ KX_PYMETHODDEF_DOC_NOARGS(KX_Scene, getObjectList,
 )
 {
        // ShowDeprecationWarning("getObjectList()", "the objects property"); // XXX Grr, why doesnt this work?
-       return (PyObject*) m_objectlist->AddRef();
+       return m_objectlist->GetProxy();
 }
 
 KX_PYMETHODDEF_DOC_NOARGS(KX_Scene, getName,
@@ -1706,6 +1753,5 @@ KX_PYMETHODDEF_DOC(KX_Scene, addObject,
 
 
        SCA_IObject* replica = AddReplicaObject((SCA_IObject*)ob, other, time);
-       replica->AddRef();
-       return replica;
+       return replica->GetProxy();
 }
\ No newline at end of file