Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenoit Bolsee <benoit.bolsee@online.be>2009-04-14 00:08:33 +0400
committerBenoit Bolsee <benoit.bolsee@online.be>2009-04-14 00:08:33 +0400
commit0b8661ab4da1a7cfbc756640649a2d07bb36cc64 (patch)
tree6d171db30ddcba3d379dea04b2da9449203419a6 /source/gameengine/Ketsji
parent6f12e584a97f664c654ddfbe5f721d2a7be3d491 (diff)
BGE: Occlusion culling and other performance improvements.
Added occlusion culling capability in the BGE. More info: http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.49/Game_Engine#BGE_Scenegraph_improvement MSVC, scons, cmake, Makefile updated. Other minor performance improvements: - The rasterizer was computing the openGL model matrix of the objects too many times - DBVT view frustrum culling was not properly culling behind the near plane: Large objects behind the camera were sent to the GPU - Remove all references to mesh split/join feature as it is not yet functional
Diffstat (limited to 'source/gameengine/Ketsji')
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp51
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.h35
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.cpp15
-rw-r--r--source/gameengine/Ketsji/KX_Scene.cpp16
-rw-r--r--source/gameengine/Ketsji/KX_Scene.h11
-rw-r--r--source/gameengine/Ketsji/KX_VisibilityActuator.cpp4
-rw-r--r--source/gameengine/Ketsji/KX_VisibilityActuator.h2
7 files changed, 103 insertions, 31 deletions
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp
index 817afedd205..16cf3d9ae32 100644
--- a/source/gameengine/Ketsji/KX_GameObject.cpp
+++ b/source/gameengine/Ketsji/KX_GameObject.cpp
@@ -92,6 +92,7 @@ KX_GameObject::KX_GameObject(
m_bIsNegativeScaling(false),
m_bVisible(true),
m_bCulled(true),
+ m_bOccluder(false),
m_pPhysicsController1(NULL),
m_pGraphicController(NULL),
m_pPhysicsEnvironment(NULL),
@@ -146,7 +147,12 @@ KX_GameObject::~KX_GameObject()
}
}
-
+KX_GameObject* KX_GameObject::GetClientObject(KX_ClientObjectInfo* info)
+{
+ if (!info)
+ return NULL;
+ return info->m_gameobject;
+}
CValue* KX_GameObject:: Calc(VALUE_OPERATOR op, CValue *val)
{
@@ -435,7 +441,7 @@ static void UpdateBuckets_recursive(SG_Node* node)
void KX_GameObject::UpdateBuckets( bool recursive )
{
- double* fl = GetOpenGLMatrix();
+ double* fl = GetOpenGLMatrixPtr()->getPointer();
for (size_t i=0;i<m_meshes.size();i++)
m_meshes[i]->UpdateBuckets(this, fl, m_bUseObjectColor, m_objectColor, m_bVisible, m_bCulled);
@@ -597,23 +603,34 @@ KX_GameObject::SetVisible(
setVisible_recursive(m_pSGNode, v);
}
-bool
-KX_GameObject::GetCulled(
- void
- )
+static void setOccluder_recursive(SG_Node* node, bool v)
{
- return m_bCulled;
+ NodeList& children = node->GetSGChildren();
+
+ for (NodeList::iterator childit = children.begin();!(childit==children.end());++childit)
+ {
+ SG_Node* childnode = (*childit);
+ KX_GameObject *clientgameobj = static_cast<KX_GameObject*>( (*childit)->GetSGClientObject());
+ if (clientgameobj != NULL) // This is a GameObject
+ clientgameobj->SetOccluder(v, false);
+
+ // if the childobj is NULL then this may be an inverse parent link
+ // so a non recursive search should still look down this node.
+ setOccluder_recursive(childnode, v);
+ }
}
void
-KX_GameObject::SetCulled(
- bool c
+KX_GameObject::SetOccluder(
+ bool v,
+ bool recursive
)
{
- m_bCulled = c;
+ m_bOccluder = v;
+ if (recursive)
+ setOccluder_recursive(m_pSGNode, v);
}
-
void
KX_GameObject::SetLayer(
int l
@@ -1036,6 +1053,7 @@ PyMethodDef KX_GameObject::Methods[] = {
{"setCollisionMargin", (PyCFunction) KX_GameObject::sPySetCollisionMargin, METH_O},
{"setParent", (PyCFunction)KX_GameObject::sPySetParent,METH_O},
{"setVisible",(PyCFunction) KX_GameObject::sPySetVisible, METH_VARARGS},
+ {"setOcclusion",(PyCFunction) KX_GameObject::sPySetOcclusion, METH_VARARGS},
{"removeParent", (PyCFunction)KX_GameObject::sPyRemoveParent,METH_NOARGS},
{"getChildren", (PyCFunction)KX_GameObject::sPyGetChildren,METH_NOARGS},
{"getChildrenRecursive", (PyCFunction)KX_GameObject::sPyGetChildrenRecursive,METH_NOARGS},
@@ -1069,6 +1087,7 @@ PyAttributeDef KX_GameObject::Attributes[] = {
KX_PYATTRIBUTE_RO_FUNCTION("parent", KX_GameObject, pyattr_get_parent),
KX_PYATTRIBUTE_RW_FUNCTION("mass", KX_GameObject, pyattr_get_mass, pyattr_set_mass),
KX_PYATTRIBUTE_RW_FUNCTION("visible", KX_GameObject, pyattr_get_visible, pyattr_set_visible),
+ KX_PYATTRIBUTE_BOOL_RW ("occlusion", KX_GameObject, m_bOccluder),
KX_PYATTRIBUTE_RW_FUNCTION("position", KX_GameObject, pyattr_get_position, pyattr_set_position),
KX_PYATTRIBUTE_RO_FUNCTION("localInertia", KX_GameObject, pyattr_get_localInertia),
KX_PYATTRIBUTE_RW_FUNCTION("orientation",KX_GameObject,pyattr_get_orientation,pyattr_set_orientation),
@@ -1746,6 +1765,16 @@ PyObject* KX_GameObject::PySetVisible(PyObject* self, PyObject* args)
}
+PyObject* KX_GameObject::PySetOcclusion(PyObject* self, PyObject* args)
+{
+ int occlusion, recursive = 0;
+ if (!PyArg_ParseTuple(args,"i|i:setOcclusion",&occlusion, &recursive))
+ return NULL;
+
+ SetOccluder(occlusion ? true:false, recursive ? true:false);
+ Py_RETURN_NONE;
+}
+
PyObject* KX_GameObject::PyGetVisible(PyObject* self)
{
ShowDeprecationWarning("getVisible()", "the visible property");
diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h
index 172272150c0..c389d6cc776 100644
--- a/source/gameengine/Ketsji/KX_GameObject.h
+++ b/source/gameengine/Ketsji/KX_GameObject.h
@@ -87,6 +87,7 @@ protected:
// culled = while rendering, depending on camera
bool m_bVisible;
bool m_bCulled;
+ bool m_bOccluder;
KX_IPhysicsController* m_pPhysicsController1;
PHY_IGraphicController* m_pGraphicController;
@@ -103,6 +104,11 @@ protected:
public:
bool m_isDeformable;
+ /**
+ * Helper function for modules that can't include KX_ClientObjectInfo.h
+ */
+ static KX_GameObject* GetClientObject(KX_ClientObjectInfo* info);
+
// Python attributes that wont convert into CValue
//
// there are 2 places attributes can be stored, in the CValue,
@@ -118,11 +124,8 @@ public:
// * if CValue conversion fails, use a PyObject in "m_attrlist"
// * when assigning a value, first see if it can be a CValue, if it can remove the "m_attrlist" and set the CValue
//
-
PyObject* m_attrlist;
-
-
virtual void /* This function should be virtual - derived classed override it */
Relink(
GEN_Map<GEN_HashedPtr, void*> *map
@@ -698,20 +701,37 @@ public:
/**
* Was this object culled?
*/
- bool
+ inline bool
GetCulled(
void
- );
+ ) { return m_bCulled; }
/**
* Set culled flag of this object
*/
- void
+ inline void
SetCulled(
bool c
- );
+ ) { m_bCulled = c; }
+
+ /**
+ * Is this object an occluder?
+ */
+ inline bool
+ GetOccluder(
+ void
+ ) { return m_bOccluder; }
/**
+ * Set occluder flag of this object
+ */
+ void
+ SetOccluder(
+ bool v,
+ bool recursive
+ );
+
+ /**
* Change the layer of the object (when it is added in another layer
* than the original layer)
*/
@@ -908,6 +928,7 @@ public:
KX_PYMETHOD_O(KX_GameObject,SetOrientation);
KX_PYMETHOD_NOARGS(KX_GameObject,GetVisible);
KX_PYMETHOD_VARARGS(KX_GameObject,SetVisible);
+ KX_PYMETHOD_VARARGS(KX_GameObject,SetOcclusion);
KX_PYMETHOD_NOARGS(KX_GameObject,GetState);
KX_PYMETHOD_O(KX_GameObject,SetState);
KX_PYMETHOD_VARARGS(KX_GameObject,AlignAxisToVect);
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
index aeb80806f6c..83a2fa8a448 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
@@ -294,8 +294,14 @@ void KX_KetsjiEngine::RenderDome()
if (!BeginFrame())
return;
- int n_renders=m_dome->GetNumberRenders();// usually 4 or 6
KX_SceneList::iterator sceneit;
+ for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); sceneit++)
+ {
+ // do this only once per scene
+ (*sceneit)->UpdateMeshTransformations();
+ }
+
+ int n_renders=m_dome->GetNumberRenders();// usually 4 or 6
for (int i=0;i<n_renders;i++){
m_canvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER|RAS_ICanvas::DEPTH_BUFFER);
for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); sceneit++)
@@ -311,7 +317,6 @@ void KX_KetsjiEngine::RenderDome()
// shadow buffers
if (i == 0){
RenderShadowBuffers(scene);
- scene->UpdateMeshTransformations();//I need to run it somewherelse, otherwise Im overrunning it
}
// Avoid drawing the scene with the active camera twice when it's viewport is enabled
if(cam && !cam->GetViewport())
@@ -812,6 +817,9 @@ void KX_KetsjiEngine::Render()
// pass the scene's worldsettings to the rasterizer
SetWorldSettings(scene->GetWorldInfo());
+ // do this only once per scene
+ scene->UpdateMeshTransformations();
+
// shadow buffers
RenderShadowBuffers(scene);
@@ -1140,7 +1148,6 @@ void KX_KetsjiEngine::RenderShadowBuffers(KX_Scene *scene)
light->BindShadowBuffer(m_rasterizer, cam, camtrans);
/* update scene */
- scene->UpdateMeshTransformations();
scene->CalculateVisibleMeshes(m_rasterizer, cam, light->GetShadowLayer());
/* render */
@@ -1245,7 +1252,7 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam)
cam->GetCameraLocation(), cam->GetCameraOrientation());
cam->SetModelviewMatrix(viewmat);
- //redundant, already done in
+ //redundant, already done in Render()
//scene->UpdateMeshTransformations();
// The following actually reschedules all vertices to be
diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp
index 2f7c1b77794..98c129ebca5 100644
--- a/source/gameengine/Ketsji/KX_Scene.cpp
+++ b/source/gameengine/Ketsji/KX_Scene.cpp
@@ -138,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;
@@ -1352,17 +1353,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
diff --git a/source/gameengine/Ketsji/KX_Scene.h b/source/gameengine/Ketsji/KX_Scene.h
index 55e7afa4957..e1e89e253ed 100644
--- a/source/gameengine/Ketsji/KX_Scene.h
+++ b/source/gameengine/Ketsji/KX_Scene.h
@@ -265,6 +265,11 @@ protected:
bool m_dbvt_culling;
/**
+ * Occlusion culling resolution
+ */
+ int m_dbvt_occlusion_res;
+
+ /**
* The framing settings used by this scene
*/
@@ -545,8 +550,10 @@ public:
bool IsClearingZBuffer();
void EnableZBufferClearing(bool isclearingZbuffer);
// use of DBVT tree for camera culling
- void SetDbvtCameraCulling(bool b) { m_dbvt_culling = b; };
- bool GetDbvtCameraCulling() { return m_dbvt_culling; };
+ void SetDbvtCulling(bool b) { m_dbvt_culling = b; };
+ bool GetDbvtCulling() { return m_dbvt_culling; };
+ void SetDbvtOcclusionRes(int i) { m_dbvt_occlusion_res = i; };
+ int GetDbvtOcclusionRes() { return m_dbvt_occlusion_res; };
void SetSceneConverter(class KX_BlenderSceneConverter* sceneConverter);
diff --git a/source/gameengine/Ketsji/KX_VisibilityActuator.cpp b/source/gameengine/Ketsji/KX_VisibilityActuator.cpp
index 1ee2169adc4..fceb0b5922c 100644
--- a/source/gameengine/Ketsji/KX_VisibilityActuator.cpp
+++ b/source/gameengine/Ketsji/KX_VisibilityActuator.cpp
@@ -38,11 +38,13 @@
KX_VisibilityActuator::KX_VisibilityActuator(
SCA_IObject* gameobj,
bool visible,
+ bool occlusion,
bool recursive,
PyTypeObject* T
)
: SCA_IActuator(gameobj,T),
m_visible(visible),
+ m_occlusion(occlusion),
m_recursive(recursive)
{
// intentionally empty
@@ -78,6 +80,7 @@ KX_VisibilityActuator::Update()
KX_GameObject *obj = (KX_GameObject*) GetParent();
obj->SetVisible(m_visible, m_recursive);
+ obj->SetOccluder(m_occlusion, m_recursive);
obj->UpdateBuckets(m_recursive);
return false;
@@ -130,6 +133,7 @@ KX_VisibilityActuator::Methods[] = {
PyAttributeDef KX_VisibilityActuator::Attributes[] = {
KX_PYATTRIBUTE_BOOL_RW("visibility", KX_VisibilityActuator, m_visible),
+ KX_PYATTRIBUTE_BOOL_RW("occlusion", KX_VisibilityActuator, m_occlusion),
KX_PYATTRIBUTE_BOOL_RW("recursion", KX_VisibilityActuator, m_recursive),
{ NULL } //Sentinel
};
diff --git a/source/gameengine/Ketsji/KX_VisibilityActuator.h b/source/gameengine/Ketsji/KX_VisibilityActuator.h
index fca37500915..4269258f862 100644
--- a/source/gameengine/Ketsji/KX_VisibilityActuator.h
+++ b/source/gameengine/Ketsji/KX_VisibilityActuator.h
@@ -39,6 +39,7 @@ class KX_VisibilityActuator : public SCA_IActuator
/** Make visible? */
bool m_visible;
+ bool m_occlusion;
bool m_recursive;
public:
@@ -46,6 +47,7 @@ class KX_VisibilityActuator : public SCA_IActuator
KX_VisibilityActuator(
SCA_IObject* gameobj,
bool visible,
+ bool occlusion,
bool recursive,
PyTypeObject* T=&Type
);