00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef __VMML__FRUSTUM__HPP__
00010 #define __VMML__FRUSTUM__HPP__
00011
00012 #include <vmmlib/matrix.hpp>
00013
00014 #include <cmath>
00015
00016
00017
00018 namespace vmml
00019 {
00020
00021 template< class T >
00022 class frustum
00023 {
00024 public:
00025 T array[6];
00026
00027
00028 frustum();
00029 frustum( const T left, const T right, const T bottom, const T top,
00030 const T nearPlane, const T farPlane );
00031
00032
00033 frustum( const float* values );
00034 frustum( const double* values );
00035
00036 ~frustum();
00037
00038 void set( const T _left, const T _right, const T _bottom,
00039 const T _top, const T _near, const T _far );
00040
00041
00042 void setPerspective( T fieldOfViewY, T aspectRatio, T nearPlane_, T farPlane );
00043
00044 matrix< 4, 4, T > computeMatrix() const;
00045 matrix< 4, 4, T > computeOrthoMatrix() const;
00046
00047 void computeMatrix( matrix< 4, 4, T >& matrix_ ) const;
00048 void computeOrthoMatrix( matrix< 4, 4, T >& matrix_ ) const;
00049
00050
00051
00052 void adjustNear( const T nearPlane );
00053
00054 inline T& left();
00055 inline const T& left() const;
00056
00057 inline T& right();
00058 inline const T& right() const;
00059
00060 inline T& bottom();
00061 inline const T& bottom() const;
00062
00063 inline T& top();
00064 inline const T& top() const;
00065
00066 inline T& nearPlane();
00067 inline const T& nearPlane() const;
00068
00069 inline T& farPlane();
00070 inline const T& farPlane() const;
00071
00072 friend std::ostream& operator << ( std::ostream& os, const frustum& frustum_ )
00073 {
00074 const std::ios::fmtflags flags = os.flags();
00075 const int prec = os.precision();
00076
00077 os.setf( std::ios::right, std::ios::adjustfield );
00078 os.precision( 5 );
00079 os << "[" << std::setw(10) << frustum_.left << " "
00080 << std::setw(10) << frustum_.right << " "
00081 << std::setw(10) << frustum_.bottom << " "
00082 << std::setw(10) << frustum_.top << " "
00083 << std::setw(10) << frustum_.nearPlane << " "
00084 << std::setw(10) << frustum_.farPlane << "]";
00085 os.precision( prec );
00086 os.setf( flags );
00087 return os;
00088 };
00089
00090 static const frustum DEFAULT;
00091 };
00092
00093 #ifndef VMMLIB_NO_TYPEDEFS
00094 typedef frustum< float > frustumf;
00095 typedef frustum< double > frustumd;
00096 #endif
00097
00098 }
00099
00100
00101
00102 namespace vmml
00103 {
00104
00105 template< typename T >
00106 const frustum< T > frustum< T >::DEFAULT( -1.0, 1.0, -1.0, 1.0, 0.1, 100.0 );
00107
00108
00109
00110 template < class T >
00111 frustum< T >::frustum()
00112 {}
00113
00114
00115
00116 template < class T >
00117 frustum<T>::frustum( const T _left, const T _right, const T _bottom,
00118 const T _top, const T _near, const T _far )
00119 {
00120 set( _left, _right, _bottom, _top, _near, _far );
00121 }
00122
00123
00124
00125 template < class T >
00126 frustum< T >::frustum( const float* values )
00127 {
00128 assert( values &&
00129 "frustum: Nullpointer argument as source for initialisation!" );
00130 left() = static_cast< T > ( values[0] );
00131 right() = static_cast< T > ( values[1] );
00132 bottom() = static_cast< T > ( values[2] );
00133 top() = static_cast< T > ( values[3] );
00134 nearPlane() = static_cast< T > ( values[4] );
00135 farPlane() = static_cast< T > ( values[5] );
00136 }
00137
00138
00139
00140 template < class T >
00141 frustum< T >::frustum( const double* values )
00142 {
00143 assert( values &&
00144 "frustum: Nullpointer argument as source for initialisation!" );
00145 left() = static_cast< T > ( values[0] );
00146 right() = static_cast< T > ( values[1] );
00147 bottom() = static_cast< T > ( values[2] );
00148 top() = static_cast< T > ( values[3] );
00149 nearPlane() = static_cast< T > ( values[4] );
00150 farPlane() = static_cast< T > ( values[5] );
00151 }
00152
00153
00154
00155 template < class T >
00156 frustum< T >::~frustum()
00157 {}
00158
00159
00160
00161 template < class T >
00162 void
00163 frustum< T >::set( const T _left, const T _right, const T _bottom,
00164 const T _top, const T _near, const T _far )
00165 {
00166 left() = _left;
00167 right() = _right;
00168 bottom() = _bottom;
00169 top() = _top;
00170 nearPlane() = _near;
00171 farPlane() = _far;
00172 }
00173
00174
00175
00176
00177 template < class T >
00178 void
00179 frustum<T>::adjustNear( const T newNear )
00180 {
00181 if( newNear == nearPlane() )
00182 return;
00183
00184 const T ratio = newNear / nearPlane;
00185 right() *= ratio;
00186 left() *= ratio;
00187 top() *= ratio;
00188 bottom() *= ratio;
00189 nearPlane() = newNear;
00190 }
00191
00192
00193
00194
00195 template < class T >
00196 void
00197 frustum<T>::setPerspective( T fieldOfViewY, T aspectRatio, T nearPlane_, T farPlane_ )
00198 {
00199 nearPlane() = nearPlane_;
00200 farPlane() = farPlane_;
00201
00202 top() = tan( 0.5 * fieldOfViewY * M_PI / 180.0 ) * 0.5;
00203 bottom() = - top();
00204
00205 left() = bottom() * aspectRatio;
00206 right() = top() * aspectRatio;
00207 }
00208
00209
00210 template < class T >
00211 matrix< 4, 4, T >
00212 frustum<T>::computeMatrix() const
00213 {
00214 matrix< 4, 4, T > matrix_;
00215 computeMatrix( matrix_ );
00216 return matrix_;
00217 }
00218
00219
00220
00221 template < class T >
00222 void
00223 frustum<T>::computeMatrix( matrix< 4, 4, T >& M ) const
00224 {
00225 M( 0,0 ) = 2.0 * nearPlane() / ( right() - left() );
00226 M( 0,1 ) = 0.0;
00227 M( 0,2 ) = ( right() + left() ) / ( right() - left() );
00228 M( 0,3 ) = 0.0;
00229
00230 M( 1,0 ) = 0.0;
00231 M( 1,1 ) = 2.0 * nearPlane() / ( top() - bottom() );
00232 M( 1,2 ) = ( top() + bottom() ) / ( top() - bottom() );
00233 M( 1,3 ) = 0.0;
00234
00235 M( 2,0 ) = 0.0;
00236 M( 2,1 ) = 0.0;
00237
00238 M( 2,2 ) = -( farPlane() + nearPlane() ) / ( farPlane() - nearPlane() );
00239 M( 2,3 ) = -2.0 * farPlane() * nearPlane() / ( farPlane() - nearPlane() );
00240
00241 M( 3,0 ) = 0.0;
00242 M( 3,1 ) = 0.0;
00243 M( 3,2 ) = -1.0;
00244 M( 3,3 ) = 0.0;
00245 }
00246
00247
00248
00249 template < typename T >
00250 matrix< 4, 4, T >
00251 frustum< T >::computeOrthoMatrix() const
00252 {
00253 matrix< 4, 4, T > matrix_;
00254 computeOrthoMatrix( matrix_ );
00255 return matrix_;
00256 }
00257
00258
00259
00260 template < typename T >
00261 void
00262 frustum< T >::computeOrthoMatrix( matrix< 4, 4, T >& M ) const
00263 {
00264 M( 0,0 ) = 2.0 / ( right() - left() );
00265 M( 0,1 ) = 0.0;
00266 M( 0,2 ) = 0.0;
00267 M( 0,3 ) = -( right() + left() ) / ( right() - left() );
00268
00269 M( 1,0 ) = 0.0;
00270 M( 1,1 ) = 2.0 / ( top() - bottom() );
00271 M( 1,2 ) = 0.0f;
00272 M( 1,3 ) = -( top() + bottom() ) / ( top() - bottom() );
00273
00274 M( 2,0 ) = 0.0;
00275 M( 2,1 ) = 0.0;
00276 M( 2,2 ) = -2.0 / ( farPlane() - nearPlane() );
00277 M( 2,3 ) = -( farPlane() + nearPlane() ) / ( farPlane() - nearPlane() );
00278
00279 M( 3,0 ) = 0.0;
00280 M( 3,1 ) = 0.0;
00281 M( 3,2 ) = 0.0;
00282 M( 3,3 ) = 1.0f;
00283 }
00284
00285
00286
00287 template< typename T >
00288 inline T&
00289 frustum< T >::left()
00290 {
00291 return array[ 0 ];
00292 }
00293
00294
00295
00296 template< typename T >
00297 inline const T&
00298 frustum< T >::left() const
00299 {
00300 return array[ 0 ];
00301 }
00302
00303
00304
00305 template< typename T >
00306 inline T&
00307 frustum< T >::right()
00308 {
00309 return array[ 1 ];
00310 }
00311
00312
00313
00314 template< typename T >
00315 inline const T&
00316 frustum< T >::right() const
00317 {
00318 return array[ 1 ];
00319 }
00320
00321
00322
00323 template< typename T >
00324 inline T&
00325 frustum< T >::bottom()
00326 {
00327 return array[ 2 ];
00328 }
00329
00330
00331
00332 template< typename T >
00333 inline const T&
00334 frustum< T >::bottom() const
00335 {
00336 return array[ 2 ];
00337 }
00338
00339
00340
00341 template< typename T >
00342 inline T&
00343 frustum< T >::top()
00344 {
00345 return array[ 3 ];
00346 }
00347
00348
00349
00350 template< typename T >
00351 inline const T&
00352 frustum< T >::top() const
00353 {
00354 return array[ 3 ];
00355 }
00356
00357
00358
00359 template< typename T >
00360 inline T&
00361 frustum< T >::nearPlane()
00362 {
00363 return array[ 4 ];
00364 }
00365
00366
00367
00368 template< typename T >
00369 inline const T&
00370 frustum< T >::nearPlane() const
00371 {
00372 return array[ 4 ];
00373 }
00374
00375
00376
00377 template< typename T >
00378 inline T&
00379 frustum< T >::farPlane()
00380 {
00381 return array[ 5 ];
00382 }
00383
00384
00385
00386 template< typename T >
00387 inline const T&
00388 frustum< T >::farPlane() const
00389 {
00390 return array[ 5 ];
00391 }
00392
00393
00394 }
00395
00396 #endif