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 ) ...@@ -41,26 +41,54 @@ void Frustum::UpdateFrustumPlanes( const QMatrix4x4& V, const QMatrix4x4& P )
// Left plane. // 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 ); m_Planes[LEFT_PLANE].d0 = -QVector3D::dotProduct( m_Planes[LEFT_PLANE].n, center );
// Right plane. // 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 ); m_Planes[RIGHT_PLANE].d0 = -QVector3D::dotProduct( m_Planes[RIGHT_PLANE].n, center );
// Bottom plane. // 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 ); m_Planes[BOTTOM_PLANE].d0 = -QVector3D::dotProduct( m_Planes[BOTTOM_PLANE].n, center );
// Top plane. // 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 ); 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 bool Frustum::IsOutside( const Box3f& box, const QMatrix4x4& model ) const
{ {
Box3f::CornerSet corners; Box3f::CornerSet corners;
...@@ -69,6 +97,35 @@ bool Frustum::IsOutside( const Box3f& box, const QMatrix4x4& model ) const ...@@ -69,6 +97,35 @@ bool Frustum::IsOutside( const Box3f& box, const QMatrix4x4& model ) const
for( auto &c : corners ) for( auto &c : corners )
c = model.map( c ); 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 ) for( int i=0; i<PLANE_COUNT; ++i )
{ {
uint32_t nBack = 0; uint32_t nBack = 0;
...@@ -79,8 +136,25 @@ bool Frustum::IsOutside( const Box3f& box, const QMatrix4x4& model ) const ...@@ -79,8 +136,25 @@ bool Frustum::IsOutside( const Box3f& box, const QMatrix4x4& model ) const
} }
if( nBack == 8 ) 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 ...@@ -36,11 +36,31 @@ class Frustum
float d0; float d0;
}; };
Plane m_Planes[PLANE_COUNT]; Plane m_Planes[PLANE_COUNT];
bool IsOutside( const Box3f::CornerSet& corners ) const;
public: public:
void UpdateFrustumPlanes( const QMatrix4x4& V, const QMatrix4x4& P ); enum VisibilityState
bool IsOutside( const Box3f& box, const QMatrix4x4& model ) const; {
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