00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef __VMML__FRUSTUM_CULLER__H__
00010 #define __VMML__FRUSTUM_CULLER__H__
00011
00012 #include <vmmlib/vector4.h>
00013 #include <vmmlib/visibility.h>
00014
00015
00016
00017 namespace vmml
00018 {
00019 template< typename T > class Matrix4;
00020
00021
00023 template< class T >
00024 class FrustumCuller
00025 {
00026 public:
00027
00028 FrustumCuller() {}
00029 ~FrustumCuller(){}
00030
00031 void setup( const Matrix4< T >& projModelView );
00032 Visibility testSphere( const Vector4< T >& sphere );
00033
00034 private:
00035 Vector4< T > _leftPlane;
00036 Vector4< T > _rightPlane;
00037 Vector4< T > _bottomPlane;
00038 Vector4< T > _topPlane;
00039 Vector4< T > _nearPlane;
00040 Vector4< T > _farPlane;
00041
00042 };
00043
00044 typedef FrustumCuller< float > FrustumCullerf;
00045 typedef FrustumCuller< double > FrustumCullerd;
00046
00047 }
00048
00049
00050 #include <vmmlib/matrix4.h>
00051
00052 namespace vmml
00053 {
00054
00059 template < class T >
00060 void FrustumCuller< T >::setup( const Matrix4< T >& projModelView )
00061 {
00062
00063
00064 const Vector4< T >& row0 = projModelView.getRow( 0 );
00065 const Vector4< T >& row1 = projModelView.getRow( 1 );
00066 const Vector4< T >& row2 = projModelView.getRow( 2 );
00067 const Vector4< T >& row3 = projModelView.getRow( 3 );
00068
00069 _leftPlane = row3 + row0;
00070 _rightPlane = row3 - row0;
00071 _bottomPlane = row3 + row1;
00072 _topPlane = row3 - row1;
00073 _nearPlane = row3 + row2;
00074 _farPlane = row3 - row2;
00075
00076 _leftPlane.normalizePlane();
00077 _rightPlane.normalizePlane();
00078 _bottomPlane.normalizePlane();
00079 _topPlane.normalizePlane();
00080 _nearPlane.normalizePlane();
00081 _farPlane.normalizePlane();
00082 }
00083
00084 template < class T >
00085 Visibility FrustumCuller< T >::testSphere( const Vector4<T>& sphere )
00086 {
00087 Visibility visibility = VISIBILITY_FULL;
00088
00089
00090
00091
00092
00093
00094
00095
00096 T distance = _leftPlane.normal.x * sphere.center.x +
00097 _leftPlane.normal.y * sphere.center.y +
00098 _leftPlane.normal.z * sphere.center.z + _leftPlane.distance;
00099 if( distance <= -sphere.radius )
00100 return VISIBILITY_NONE;
00101 if( distance < sphere.radius )
00102 visibility = VISIBILITY_PARTIAL;
00103
00104 distance = _rightPlane.normal.x * sphere.center.x +
00105 _rightPlane.normal.y * sphere.center.y +
00106 _rightPlane.normal.z * sphere.center.z + _rightPlane.distance;
00107 if( distance <= -sphere.radius )
00108 return VISIBILITY_NONE;
00109 if( distance < sphere.radius )
00110 visibility = VISIBILITY_PARTIAL;
00111
00112 distance = _bottomPlane.normal.x * sphere.center.x +
00113 _bottomPlane.normal.y * sphere.center.y +
00114 _bottomPlane.normal.z * sphere.center.z + _bottomPlane.distance;
00115 if( distance <= -sphere.radius )
00116 return VISIBILITY_NONE;
00117 if( distance < sphere.radius )
00118 visibility = VISIBILITY_PARTIAL;
00119
00120 distance = _topPlane.normal.x * sphere.center.x +
00121 _topPlane.normal.y * sphere.center.y +
00122 _topPlane.normal.z * sphere.center.z + _topPlane.distance;
00123 if( distance <= -sphere.radius )
00124 return VISIBILITY_NONE;
00125 if( distance < sphere.radius )
00126 visibility = VISIBILITY_PARTIAL;
00127
00128 distance = _nearPlane.normal.x * sphere.center.x +
00129 _nearPlane.normal.y * sphere.center.y +
00130 _nearPlane.normal.z * sphere.center.z + _nearPlane.distance;
00131 if( distance <= -sphere.radius )
00132 return VISIBILITY_NONE;
00133 if( distance < sphere.radius )
00134 visibility = VISIBILITY_PARTIAL;
00135
00136 distance = _farPlane.normal.x * sphere.center.x +
00137 _farPlane.normal.y * sphere.center.y +
00138 _farPlane.normal.z * sphere.center.z + _farPlane.distance;
00139 if( distance <= -sphere.radius )
00140 return VISIBILITY_NONE;
00141 if( distance < sphere.radius )
00142 visibility = VISIBILITY_PARTIAL;
00143
00144 return visibility;
00145 }
00146 }
00147 #endif