00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef __VMML__FRUSTUM__H__
00010 #define __VMML__FRUSTUM__H__
00011
00012 #include <cmath>
00013
00014
00015
00016 namespace vmml
00017 {
00018
00019 template< class T >
00020 class Frustum
00021 {
00022 public:
00023 union
00024 {
00025 struct
00026 {
00027 T left;
00028 T right;
00029 T bottom;
00030 T top;
00031 T nearPlane;
00032 T farPlane;
00033 };
00034 T data[6];
00035 };
00036
00037
00038 Frustum();
00039 Frustum( const T left, const T right, const T bottom, const T top,
00040 const T nearPlane, const T farPlane );
00041
00042
00043 Frustum( const float* values );
00044 Frustum( const double* values );
00045
00046 ~Frustum();
00047
00048 void set( const T _left, const T _right, const T _bottom,
00049 const T _top, const T _near, const T _far );
00050
00051
00052 void setPerspective( T fieldOfViewY, T aspectRatio, T nearPlane_, T farPlane );
00053
00054 Matrix4< T > computeMatrix() const;
00055 Matrix4< T > computeOrthoMatrix() const;
00056
00057
00058
00059 void adjustNear( const T nearPlane );
00060
00061 friend std::ostream& operator << ( std::ostream& os, const Frustum& frustum)
00062 {
00063 const std::ios::fmtflags flags = os.flags();
00064 const int prec = os.precision();
00065
00066 os.setf( std::ios::right, std::ios::adjustfield );
00067 os.precision( 5 );
00068 os << "[" << std::setw(10) << frustum.left << " "
00069 << std::setw(10) << frustum.right << " "
00070 << std::setw(10) << frustum.bottom << " "
00071 << std::setw(10) << frustum.top << " "
00072 << std::setw(10) << frustum.nearPlane << " "
00073 << std::setw(10) << frustum.farPlane << "]";
00074 os.precision( prec );
00075 os.setf( flags );
00076 return os;
00077 };
00078
00079 static const Frustum DEFAULT;
00080 };
00081
00082
00083 typedef Frustum< float > Frustumf;
00084 typedef Frustum< double > Frustumd;
00085
00086 typedef Frustum< float > frustumf;
00087 typedef Frustum< double > frustumd;
00088
00089 }
00090
00091
00092 #include <vmmlib/matrix4.h>
00093
00094 namespace vmml
00095 {
00096
00097 template< typename T >
00098 const Frustum< T > Frustum< T >::DEFAULT( -1.0, 1.0, -1.0, 1.0, 0.1, 100.0 );
00099
00100
00101
00102 template < class T >
00103 Frustum< T >::Frustum()
00104 {}
00105
00106
00107
00108 template < class T >
00109 Frustum<T>::Frustum( const T _left, const T _right, const T _bottom,
00110 const T _top, const T _near, const T _far )
00111 : left( _left ),
00112 right( _right ),
00113 bottom( _bottom ),
00114 top( _top ),
00115 nearPlane( _near ),
00116 farPlane( _far )
00117 {}
00118
00119
00120
00121 template < class T >
00122 Frustum< T >::Frustum( const float* values )
00123 {
00124 assert( values &&
00125 "Frustum: Nullpointer argument as source for initialisation!" );
00126 left = static_cast< T > ( values[0] );
00127 right = static_cast< T > ( values[1] );
00128 bottom = static_cast< T > ( values[2] );
00129 top = static_cast< T > ( values[3] );
00130 nearPlane = static_cast< T > ( values[4] );
00131 farPlane = static_cast< T > ( values[5] );
00132 }
00133
00134
00135
00136 template < class T >
00137 Frustum< T >::Frustum( const double* values )
00138 {
00139 assert( values &&
00140 "Frustum: Nullpointer argument as source for initialisation!" );
00141 left = static_cast< T > ( values[0] );
00142 right = static_cast< T > ( values[1] );
00143 bottom = static_cast< T > ( values[2] );
00144 top = static_cast< T > ( values[3] );
00145 nearPlane = static_cast< T > ( values[4] );
00146 farPlane = static_cast< T > ( values[5] );
00147 }
00148
00149
00150
00151 template < class T >
00152 Frustum< T >::~Frustum()
00153 {}
00154
00155
00156
00157 template < class T >
00158 void
00159 Frustum< T >::set( const T _left, const T _right, const T _bottom,
00160 const T _top, const T _near, const T _far )
00161 {
00162 left = _left;
00163 right = _right;
00164 bottom = _bottom;
00165 top = _top;
00166 nearPlane = _near;
00167 farPlane = _far;
00168 }
00169
00170
00171
00172
00173 template < class T >
00174 void
00175 Frustum<T>::adjustNear( const T newNear )
00176 {
00177 if( newNear == nearPlane )
00178 return;
00179
00180 const T ratio = newNear / nearPlane;
00181 right *= ratio;
00182 left *= ratio;
00183 top *= ratio;
00184 bottom *= ratio;
00185 nearPlane = newNear;
00186 }
00187
00188
00189
00190
00191 template < class T >
00192 void
00193 Frustum<T>::setPerspective( T fieldOfViewY, T aspectRatio, T nearPlane_, T farPlane_ )
00194 {
00195 nearPlane = nearPlane_;
00196 farPlane = farPlane_;
00197
00198 top = tan( 0.5 * fieldOfViewY * M_PI / 180.0 ) * 0.5;
00199 bottom = - top;
00200
00201 left = bottom * aspectRatio;
00202 right = top * aspectRatio;
00203 }
00204
00205
00206
00207 template < class T >
00208 Matrix4<T> Frustum<T>::computeMatrix() const
00209 {
00210 Matrix4<T> matrix;
00211
00212 matrix.m00 = 2.0 * nearPlane / (right - left);
00213 matrix.m01 = 0.0;
00214 matrix.m02 = (right + left) / (right - left);
00215 matrix.m03 = 0.0;
00216
00217 matrix.m10 = 0.0;
00218 matrix.m11 = 2.0 * nearPlane / (top - bottom);
00219 matrix.m12 = (top + bottom) / (top - bottom);
00220 matrix.m13 = 0.0;
00221
00222 matrix.m20 = 0.0;
00223 matrix.m21 = 0.0;
00224
00225 matrix.m22 = -(farPlane + nearPlane) / (farPlane - nearPlane);
00226 matrix.m23 = -2.0 * farPlane * nearPlane / (farPlane - nearPlane);
00227
00228 matrix.m30 = 0.0;
00229 matrix.m31 = 0.0;
00230 matrix.m32 = -1.0;
00231 matrix.m33 = 0.0;
00232
00233 return matrix;
00234 }
00235
00236
00237
00238 template < typename T >
00239 Matrix4< T >
00240 Frustum< T >::computeOrthoMatrix() const
00241 {
00242 return Matrix4< T > (
00243 2.0 / ( right - left ),
00244 0.0f ,
00245 0.0f,
00246 -( right + left ) / ( right - left ),
00247
00248 0.0f,
00249 2.0 / ( top-bottom ),
00250 0.0f,
00251 -( top + bottom ) / ( top - bottom ),
00252
00253 0.0f,
00254 0.0f,
00255 -2.0 / ( farPlane-nearPlane ),
00256 -( farPlane + nearPlane ) / ( farPlane - nearPlane ),
00257
00258 0.0f,
00259 0.0f,
00260 0.0f,
00261 1.0f
00262 );
00263 }
00264
00265
00266 }
00267
00268 #endif