Commit 5c086ac1 authored by Frédéric Larue's avatar Frédéric Larue
Browse files

Frustum updated.

parent 4355bf72
......@@ -41,26 +41,54 @@ void Frustum::UpdateFrustumPlanes( const QMatrix4x4& V, const QMatrix4x4& P )
// Left plane.
m_Planes[LEFT_PLANE].n = QVector3D::crossProduct( front + l*right, top );
m_Planes[LEFT_PLANE].n = QVector3D::crossProduct( front + l*right, top ).normalized();
m_Planes[LEFT_PLANE].d0 = -QVector3D::dotProduct( m_Planes[LEFT_PLANE].n, center );
// Right plane.
m_Planes[RIGHT_PLANE].n = QVector3D::crossProduct( top, front + r*right );
m_Planes[RIGHT_PLANE].n = QVector3D::crossProduct( top, front + r*right ).normalized();
m_Planes[RIGHT_PLANE].d0 = -QVector3D::dotProduct( m_Planes[RIGHT_PLANE].n, center );
// Bottom plane.
m_Planes[BOTTOM_PLANE].n = QVector3D::crossProduct( right, front + b*top );
m_Planes[BOTTOM_PLANE].n = QVector3D::crossProduct( right, front + b*top ).normalized();
m_Planes[BOTTOM_PLANE].d0 = -QVector3D::dotProduct( m_Planes[BOTTOM_PLANE].n, center );
// Top plane.
m_Planes[TOP_PLANE].n = QVector3D::crossProduct( front + t*top, right );
m_Planes[TOP_PLANE].n = QVector3D::crossProduct( front + t*top, right ).normalized();
m_Planes[TOP_PLANE].d0 = -QVector3D::dotProduct( m_Planes[TOP_PLANE].n, center );
}
bool Frustum::IsOutside( const Box3f::CornerSet& corners ) const
{
for( int i=0; i<PLANE_COUNT; ++i )
{
uint32_t nBack = 0;
for( auto &c : corners )
{
float distToPlane = QVector3D::dotProduct( m_Planes[i].n, c ) + m_Planes[i].d0;
nBack += ((* (uint32_t*) &distToPlane) >> 31);
}
if( nBack == 8 )
return true;
}
return false;
}
bool Frustum::IsOutside( const Box3f& box ) const
{
Box3f::CornerSet corners;
box.Corners( corners );
return IsOutside( corners );
}
bool Frustum::IsOutside( const Box3f& box, const QMatrix4x4& model ) const
{
Box3f::CornerSet corners;
......@@ -69,6 +97,35 @@ bool Frustum::IsOutside( const Box3f& box, const QMatrix4x4& model ) const
for( auto &c : corners )
c = model.map( c );
return IsOutside( corners );
}
bool Frustum::IsOutside( const QVector3D& sphereCenter, float sphereRadius ) const
{
for( int i=0; i<PLANE_COUNT; ++i )
{
float distToPlane = QVector3D::dotProduct( m_Planes[i].n, sphereCenter ) + m_Planes[i].d0;
if( distToPlane < -sphereRadius )
return true;
}
return false;
}
bool Frustum::IsOutside( const QVector3D& sphereCenter, float sphereRadius, const QMatrix4x4& model ) const
{
return IsOutside( model.map(sphereCenter), sphereRadius );
}
Frustum::VisibilityState Frustum::TestVisibility( const Box3f& box ) const
{
Box3f::CornerSet corners;
box.Corners( corners );
uint32_t outsideTotalCount = 0;
for( int i=0; i<PLANE_COUNT; ++i )
{
uint32_t nBack = 0;
......@@ -79,8 +136,25 @@ bool Frustum::IsOutside( const Box3f& box, const QMatrix4x4& model ) const
}
if( nBack == 8 )
return true;
return TotallyOutside;
outsideTotalCount += nBack;
}
return false;
return (outsideTotalCount==0)? TotallyInside : PartiallyInside;
}
Frustum::VisibilityState Frustum::TestVisibility( const QVector3D& sphereCenter, float sphereRadius ) const
{
int nInside = 0;
for( int i=0; i<PLANE_COUNT; ++i )
{
float distToPlane = QVector3D::dotProduct( m_Planes[i].n, sphereCenter ) + m_Planes[i].d0;
if( distToPlane < -sphereRadius )
return TotallyOutside;
else if( distToPlane > sphereRadius )
++ nInside;
}
return (nInside==PLANE_COUNT)? TotallyInside : PartiallyInside;
}
......@@ -36,11 +36,31 @@ class Frustum
float d0;
};
Plane m_Planes[PLANE_COUNT];
Plane m_Planes[PLANE_COUNT];
bool IsOutside( const Box3f::CornerSet& corners ) const;
public:
void UpdateFrustumPlanes( const QMatrix4x4& V, const QMatrix4x4& P );
bool IsOutside( const Box3f& box, const QMatrix4x4& model ) const;
enum VisibilityState
{
TotallyOutside ,
TotallyInside ,
PartiallyInside ,
};
inline Frustum() {}
inline Frustum( const QMatrix4x4& V, const QMatrix4x4& P ) { UpdateFrustumPlanes( V, P ); }
void UpdateFrustumPlanes( const QMatrix4x4& V, const QMatrix4x4& P );
bool IsOutside( const Box3f& box ) const;
bool IsOutside( const Box3f& box, const QMatrix4x4& model ) const;
bool IsOutside( const QVector3D& sphereCenter, float sphereRadius ) const;
bool IsOutside( const QVector3D& sphereCenter, float sphereRadius, const QMatrix4x4& model ) const;
VisibilityState TestVisibility( const Box3f& box ) const;
VisibilityState TestVisibility( const QVector3D& sphereCenter, float sphereRadius ) const;
};
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment