|
From: <axl...@us...> - 2009-07-06 16:18:19
|
Revision: 413
http://hgengine.svn.sourceforge.net/hgengine/?rev=413&view=rev
Author: axlecrusher
Date: 2009-07-06 16:18:18 +0000 (Mon, 06 Jul 2009)
Log Message:
-----------
simple bounding box frustum culling is working
Modified Paths:
--------------
Mercury2/src/BoundingBox.cpp
Mercury2/src/HGMDLModel.cpp
Mercury2/src/HGMDLModel.h
Mercury2/src/MercuryAsset.cpp
Mercury2/src/MercuryAsset.h
Mercury2/src/MercuryNode.cpp
Mercury2/src/MercuryPlane.cpp
Modified: Mercury2/src/BoundingBox.cpp
===================================================================
--- Mercury2/src/BoundingBox.cpp 2009-07-06 16:14:59 UTC (rev 412)
+++ Mercury2/src/BoundingBox.cpp 2009-07-06 16:18:18 UTC (rev 413)
@@ -56,37 +56,77 @@
void BoundingBox::ComputeNormals()
{
- //normals are probably just the cardinal axises
-/* MercuryVertex t(m_center, 0);
+ //these need to be the normals of each face
+ /*
+ MercuryVertex t(m_center, 0);
t.SetX( t.GetX() + m_extend.GetX() );
- m_normals[0] = t;//.Normalize();
+ m_normals[0] = (m_center - t).Normalize();
t = m_center;
t.SetY( t.GetY() + m_extend.GetY() );
- m_normals[1] = t;//.Normalize();
+ m_normals[1] = (m_center - t).Normalize();
t = m_center;
t.SetZ( t.GetZ() + m_extend.GetZ() );
- m_normals[2] = t;//.Normalize();
+ m_normals[2] = (m_center - t).Normalize();
+ m_normals[0].Print();
*/
}
void BoundingBox::Transform( const MercuryMatrix& m )
{
+ //the frustum planes are defined in world space so
+ //these values need to be transformed into world space
BoundingBox bb;
- bb.m_extend = m_extend;
- MercuryMatrix mm = m * FRUSTUM->GetMatrix();
- bb.m_center = mm * MercuryVertex(m_center, 1);
- bb.m_normals[0] = (mm * MercuryVector(1.0f,0,0,0)).Normalize();
- bb.m_normals[1] = (mm * MercuryVector(0,1.0f,0,0)).Normalize();
- bb.m_normals[2] = (mm * MercuryVector(0,0,1.0f,0)).Normalize();
-// bb.Render();
+ bb.m_extend = m * m_extend; //Rotate and scale
+ bb.m_center = m * MercuryVertex(m_center, 1);
+
+ //transform the box axises into world axises
+ bb.m_normals[0] = (m * MercuryVector(1,0,0)).Normalize();
+ bb.m_normals[1] = (m * MercuryVector(0,1,0)).Normalize();
+ bb.m_normals[2] = (m * MercuryVector(0,0,1)).Normalize();
+
*this = bb;
}
bool BoundingBox::Clip( const MercuryPlane& p )
{
- MercuryVertex dp = p.GetNormal().DotProduct3(m_normals[0], m_normals[1], m_normals[2]);
+ //do a quick spherical test using the signed distance
+ float d = p.GetNormal().DotProduct( m_center - p.GetCenter() );
+ if (d < -m_extend.Length()) return true;
+ return false;
+
+ ///XXX everything below is broken
+
+ MercuryVector dp; //plain normal in box space
+// dp = p.GetNormal().DotProduct3(m_normals[0],m_normals[2],m_normals[3]);
+ dp[0] = m_normals[0].DotProduct( p.GetNormal() );
+ dp[1] = m_normals[1].DotProduct( p.GetNormal() );
+ dp[2] = m_normals[2].DotProduct( p.GetNormal() );
+ dp.NormalizeSelf();
+// dp = p.GetNormal();
+
+ MercuryVertex P; //max
+ if (dp[0] >= 0) P[0] = m_center.GetX() + m_extend.GetX();
+ if (dp[1] >= 0) P[1] = m_center.GetY() + m_extend.GetY();
+ if (dp[2] >= 0) P[2] = m_center.GetZ() + m_extend.GetZ();
+
+ MercuryVertex N; //min
+ if (dp[0] >= 0) N[0] = m_center.GetX() - m_extend.GetX();
+ if (dp[1] >= 0) N[1] = m_center.GetY() - m_extend.GetY();
+ if (dp[2] >= 0) N[2] = m_center.GetZ() - m_extend.GetZ();
+
+ float x = dp.DotProduct( P );
+ float y = dp.DotProduct( N );
+// printf("p %f n %f\n", x, y);
+ if ( x < 0)
+ return true; //max value outside
+ if ( y < 0) //is negative value outside
+ return false; //intersect
+
+ return false;
+/*
+ db * m_extend;
float x = ABS( m_extend.GetX() * dp[0] );
x += ABS( m_extend.GetY() * dp[1] );
x += ABS( m_extend.GetZ() * dp[2] );
@@ -96,17 +136,22 @@
return false;
return BEHIND_PLANE(d); //if we don't intersect, just see what side we are on
+ */
}
bool BoundingBox::Clip( const Frustum& f )
{
- bool inView = true;
- for (uint8_t i = 0; (i < 6) && inView; ++i)
+ bool clipped = false;
+ for (uint8_t i = 0; (i < 6) && !clipped; ++i)
{
- inView = Clip( f.GetPlane(i) )?false:inView;
+ bool t = Clip( f.GetPlane(i) );
+// printf("p%d %d\n", i, t);
+ clipped = t;
}
+// printf("******\n");
+// return false;
- return !inView;
+ return clipped;
}
//bool BoundingBox::FrustumCull() const
@@ -166,8 +211,10 @@
bool BoundingBox::DoFrustumTest( const MercuryMatrix& m )
{
BoundingBox bb(*this);
+// bb.Render();
bb.Transform( m );
- return false;
+// bb.Render();
+ return bb.Clip( *FRUSTUM );
}
void BoundingBox::DoOcclusionTest( OcclusionResult& result )
@@ -218,7 +265,7 @@
const float* center = GetCenter();
const float* extend = GetExtend();
-// glPushMatrix();
+ glPushMatrix();
// glLoadIdentity();
glPushAttrib( GL_CURRENT_BIT );
glBegin(GL_LINES);
@@ -258,34 +305,45 @@
glEnd();
- //center
glPointSize(4);
glBegin(GL_POINTS);
+ //center
glVertex3f(center[0], center[1], center[2]);
+ //max point
+ glColor3f(1,1,0);
+ glVertex3f(center[0]+extend[0], center[1]+extend[1], center[2]+extend[2]);
+ //min point
+// glColor3f(1,0,0);
+ glVertex3f(center[0]-extend[0], center[1]-extend[1], center[2]-extend[2]);
glEnd();
+
//normals
MercuryVertex c;
glBegin(GL_LINES);
+
glColor3f(1.0f,0,0);
glVertex3f(center[0], center[1], center[2]);
c = center;
c += m_normals[0];
glVertex3f(c.GetX(), c.GetY(), c.GetZ());
+
glColor3f(0,1.0f,0);
glVertex3f(center[0], center[1], center[2]);
c = center;
c += m_normals[1];
glVertex3f(c.GetX(), c.GetY(), c.GetZ());
+
glColor3f(0,0,1.0f);
glVertex3f(center[0], center[1], center[2]);
c = center;
c += m_normals[2];
glVertex3f(c.GetX(), c.GetY(), c.GetZ());
+
glEnd();
glPopAttrib( );
-// glPopMatrix();
+ glPopMatrix();
}
void BoundingBox::PopulateVertices()
Modified: Mercury2/src/HGMDLModel.cpp
===================================================================
--- Mercury2/src/HGMDLModel.cpp 2009-07-06 16:14:59 UTC (rev 412)
+++ Mercury2/src/HGMDLModel.cpp 2009-07-06 16:18:18 UTC (rev 413)
@@ -58,6 +58,13 @@
}
}
+void HGMDLModel::DoCullingTests(MercuryNode* n, const MercuryMatrix& matrix)
+{
+ if ( GetLoadState() != LOADING )
+ for(uint16_t i = 0; i < m_meshes.size(); ++i)
+ m_meshes[i]->DoCullingTests(n, matrix);
+}
+
void HGMDLModel::PreRender(const MercuryNode* node)
{
if ( GetLoadState() != LOADING )
Modified: Mercury2/src/HGMDLModel.h
===================================================================
--- Mercury2/src/HGMDLModel.h 2009-07-06 16:14:59 UTC (rev 412)
+++ Mercury2/src/HGMDLModel.h 2009-07-06 16:18:18 UTC (rev 413)
@@ -19,6 +19,7 @@
static HGMDLModel* Generate();
+ virtual void DoCullingTests(MercuryNode* n, const MercuryMatrix& matrix);
virtual void PreRender(const MercuryNode* node);
virtual void Render(const MercuryNode* node);
Modified: Mercury2/src/MercuryAsset.cpp
===================================================================
--- Mercury2/src/MercuryAsset.cpp 2009-07-06 16:14:59 UTC (rev 412)
+++ Mercury2/src/MercuryAsset.cpp 2009-07-06 16:18:18 UTC (rev 413)
@@ -37,8 +37,19 @@
SetLoadState( LOADED );
}
+void MercuryAsset::DoCullingTests(MercuryNode* n, const MercuryMatrix& matrix)
+{
+ if ( m_boundingVolume )
+ {
+ n->SetCulled( m_boundingVolume->DoFrustumTest(matrix) );
+ if ( !n->IsCulled() )
+ m_boundingVolume->DoOcclusionTest( n->GetOcclusionResult() );
+ }
+}
+
void MercuryAsset::PreRender(const MercuryNode* node)
{
+ /*
MercuryNode* n = const_cast<MercuryNode*>(node);
if ( m_boundingVolume )
{
@@ -46,6 +57,7 @@
if ( !n->IsCulled() )
m_boundingVolume->DoOcclusionTest( n->GetOcclusionResult() );
}
+ */
}
void MercuryAsset::DrawAxes()
Modified: Mercury2/src/MercuryAsset.h
===================================================================
--- Mercury2/src/MercuryAsset.h 2009-07-06 16:14:59 UTC (rev 412)
+++ Mercury2/src/MercuryAsset.h 2009-07-06 16:18:18 UTC (rev 413)
@@ -51,6 +51,7 @@
inline BoundingVolume* GetBoundingVolume() const { return m_boundingVolume; }
inline const MString& Path() const { return m_path; }
+ virtual void DoCullingTests(MercuryNode* n, const MercuryMatrix& matrix);
void DrawAxes();
protected:
void SetLoadState(LoadState ls); //thread safe
Modified: Mercury2/src/MercuryNode.cpp
===================================================================
--- Mercury2/src/MercuryNode.cpp 2009-07-06 16:14:59 UTC (rev 412)
+++ Mercury2/src/MercuryNode.cpp 2009-07-06 16:18:18 UTC (rev 413)
@@ -224,7 +224,10 @@
{
list< MercuryAsset* >::iterator i;
for (i = m_prerender.begin(); i != m_prerender.end(); ++i )
+ {
+ (*i)->DoCullingTests( this, matrix );
(*i)->PreRender(this);
+ }
}
void MercuryNode::Render(const MercuryMatrix& matrix)
Modified: Mercury2/src/MercuryPlane.cpp
===================================================================
--- Mercury2/src/MercuryPlane.cpp 2009-07-06 16:14:59 UTC (rev 412)
+++ Mercury2/src/MercuryPlane.cpp 2009-07-06 16:18:18 UTC (rev 413)
@@ -2,14 +2,10 @@
#include <stdio.h>
#include <MercuryMath.h>
-#define SIGNED_DIST(x) m_normal.DotProduct(x)
-
-// origional algorithim was -x<0
-#define BEHIND_PLANE(x) x>=0
-
bool MercuryPlane::IsBehindPlane(const MercuryVertex& point) const
{
- return BEHIND_PLANE( SIGNED_DIST( point+m_center ) );
+ //signed distance between the plane and the point
+ return m_normal.DotProduct( point - m_center ) < 0;
}
/****************************************************************************
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|