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:
authorKester Maddock <Christopher.Maddock.1@uni.massey.ac.nz>2004-05-21 13:21:15 +0400
committerKester Maddock <Christopher.Maddock.1@uni.massey.ac.nz>2004-05-21 13:21:15 +0400
commite957b12f0eb5ae56f6db1c64d123eacc0840cc61 (patch)
treeb8ed8f092619edb303cf34aba11b0999ad317d40 /source/gameengine/Ketsji/KX_Scene.cpp
parent1217928e662bd74980dc17c8d32797b0bc6f7002 (diff)
Frustum sphere culling.
Do a sphere<->camera sphere and a sphere<->frustum before the box<->frustum test.
Diffstat (limited to 'source/gameengine/Ketsji/KX_Scene.cpp')
-rw-r--r--source/gameengine/Ketsji/KX_Scene.cpp54
1 files changed, 43 insertions, 11 deletions
diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp
index 5abd43574ba..40aca5d7129 100644
--- a/source/gameengine/Ketsji/KX_Scene.cpp
+++ b/source/gameengine/Ketsji/KX_Scene.cpp
@@ -615,6 +615,7 @@ SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject,
replica->GetSGNode()->UpdateWorldData(0);
replica->GetSGNode()->SetBBox(originalobj->GetSGNode()->BBox());
+ replica->GetSGNode()->SetRadius(originalobj->GetSGNode()->Radius());
return replica;
}
@@ -803,13 +804,22 @@ void KX_Scene::UpdateMeshTransformations()
void KX_Scene::MarkVisible(SG_Tree *node, RAS_IRasterizer* rasty)
{
int intersect = KX_Camera::INTERSECT;
+ KX_GameObject *gameobj = node->Client()?(KX_GameObject*) node->Client()->GetSGClientObject():NULL;
/* If the camera is inside the box, assume intersect. */
if (!node->inside(GetActiveCamera()->NodeGetWorldPosition()))
{
- MT_Point3 box[8];
- node->get(box);
- intersect = GetActiveCamera()->BoxInsideFrustum(box);
+ MT_Scalar radius = node->Radius();
+ MT_Point3 centre = node->Centre();
+
+ intersect = GetActiveCamera()->SphereInsideFrustum(centre, radius);
+
+ if (intersect == KX_Camera::INTERSECT)
+ {
+ MT_Point3 box[8];
+ node->get(box);
+ intersect = GetActiveCamera()->BoxInsideFrustum(box);
+ }
}
switch (intersect)
@@ -818,9 +828,8 @@ void KX_Scene::MarkVisible(SG_Tree *node, RAS_IRasterizer* rasty)
MarkSubTreeVisible(node, rasty, false);
break;
case KX_Camera::INTERSECT:
- if (node->Client())
+ if (gameobj)
{
- KX_GameObject *gameobj = (KX_GameObject*) node->Client()->GetSGClientObject();
int nummeshes = gameobj->GetMeshCount();
for (int m=0;m<nummeshes;m++)
@@ -856,7 +865,7 @@ void KX_Scene::MarkSubTreeVisible(SG_Tree *node, RAS_IRasterizer* rasty, bool vi
(gameobj->GetMesh(m))->SchedulePolygons(rasty->GetDrawingMode(),rasty);
}
}
- gameobj->MarkVisible(visible);
+ gameobj->MarkVisible(visible && gameobj->GetVisible());
}
if (node->Left())
MarkSubTreeVisible(node->Left(), rasty, visible);
@@ -873,19 +882,39 @@ void KX_Scene::CalculateVisibleMeshes(RAS_IRasterizer* rasty)
for (int i = 0; i < m_objectlist->GetCount(); i++)
{
KX_GameObject* gameobj = (KX_GameObject*)m_objectlist->GetValue(i);
+ // If Frustum culling is off, the object is always visible.
bool vis = !GetActiveCamera()->GetFrustumCulling();
+
+ // If the camera is inside this node, then the object is visible.
if (!vis)
+ {
vis = gameobj->GetSGNode()->inside( GetActiveCamera()->GetCameraLocation() );
+ }
+
+ // Test the object's bound sphere against the view frustum.
if (!vis)
{
- MT_Point3 box[8];
- gameobj->GetSGNode()->getBBox(box);
- vis = GetActiveCamera()->BoxInsideFrustum(box) != KX_Camera::OUTSIDE;
+ MT_Vector3 scale = gameobj->GetSGNode()->GetWorldScaling();
+ MT_Scalar radius = scale[scale.closestAxis()] * gameobj->GetSGNode()->Radius();
+ switch (GetActiveCamera()->SphereInsideFrustum(gameobj->NodeGetWorldPosition(), radius))
+ {
+ case KX_Camera::INSIDE:
+ vis = true;
+ break;
+ case KX_Camera::OUTSIDE:
+ vis = false;
+ break;
+ case KX_Camera::INTERSECT:
+ // Test the object's bound box against the view frustum.
+ MT_Point3 box[8];
+ gameobj->GetSGNode()->getBBox(box);
+ vis = GetActiveCamera()->BoxInsideFrustum(box) != KX_Camera::OUTSIDE;
+ break;
+ }
}
if (vis)
{
-
int nummeshes = gameobj->GetMeshCount();
for (int m=0;m<nummeshes;m++)
@@ -901,7 +930,10 @@ void KX_Scene::CalculateVisibleMeshes(RAS_IRasterizer* rasty)
}
}
#else
- MarkVisible(m_objecttree, rasty);
+ if (GetActiveCamera()->GetFrustumCulling())
+ MarkVisible(m_objecttree, rasty);
+ else
+ MarkSubTreeVisible(m_objecttree, rasty, true);
#endif
}