[8319] | 1 | /* |
---|
| 2 | orxonox - the future of 3D-vertical-scrollers |
---|
| 3 | |
---|
| 4 | Copyright (C) 2006 orx |
---|
| 5 | |
---|
| 6 | This program is free software; you can redistribute it and/or modify |
---|
| 7 | it under the terms of the GNU General Public License as published by |
---|
| 8 | the Free Software Foundation; either version 2, or (at your option) |
---|
| 9 | any later version. |
---|
| 10 | |
---|
| 11 | ### File Specific: |
---|
| 12 | main programmer: Marco Biasini |
---|
| 13 | |
---|
| 14 | */ |
---|
| 15 | #ifndef _FRUSTUM_H |
---|
| 16 | #define _FRUSTUM_H |
---|
| 17 | #include "types.h" |
---|
| 18 | #include "glincl.h" |
---|
[8328] | 19 | #include <stdio.h> |
---|
[8775] | 20 | |
---|
| 21 | |
---|
| 22 | #define MAX_CLIP_DISTANCE 400.0f |
---|
[8319] | 23 | #define m( _row,_col ) _m[_col*4+_row-5] |
---|
| 24 | |
---|
[8328] | 25 | #define CHECK_GL_ERROR( _d ) do { \ |
---|
| 26 | GLenum __err = glGetError(); \ |
---|
| 27 | if ( __err != GL_NO_ERROR ) \ |
---|
| 28 | printf( "check%s: %s\n", _d, (char*)gluErrorString( __err ) );\ |
---|
| 29 | }\ |
---|
| 30 | while ( 0 ) |
---|
| 31 | |
---|
[8319] | 32 | /** |
---|
[8569] | 33 | * Code borrowed from Lighthouse 3D. Its a very good tutorial on culling. |
---|
[8319] | 34 | */ |
---|
| 35 | class Frustum; |
---|
| 36 | typedef Frustum *pFrustum; |
---|
| 37 | class Frustum { |
---|
| 38 | |
---|
| 39 | public: |
---|
| 40 | |
---|
| 41 | enum { NEAR = 0 , FAR = 1, TOP = 2, BOTTOM = 3, LEFT = 4, RIGHT = 5 }; |
---|
[8570] | 42 | enum { OUTSIDE, INTERSECT, INSIDE }; |
---|
[8319] | 43 | |
---|
| 44 | Frustum() |
---|
| 45 | { |
---|
| 46 | planes = new Plane[6]; |
---|
| 47 | } |
---|
| 48 | ~Frustum() |
---|
| 49 | { |
---|
| 50 | if ( planes ) |
---|
| 51 | delete[] planes; |
---|
| 52 | } |
---|
| 53 | /** |
---|
| 54 | * Extracts the frustum planes from the GL_PROJECTION and GL_MODELVIEW |
---|
| 55 | * matrices... |
---|
| 56 | */ |
---|
| 57 | inline void extractPlanes() |
---|
| 58 | { |
---|
| 59 | float proj[16], view[16], combined[16]; |
---|
| 60 | glGetFloatv( GL_MODELVIEW_MATRIX, view ); |
---|
| 61 | glGetFloatv( GL_PROJECTION_MATRIX, proj ); |
---|
| 62 | multMat( combined, view, proj ); |
---|
| 63 | setFrustum( combined ); |
---|
| 64 | } |
---|
| 65 | |
---|
| 66 | inline int boxInFrustum( const ABox& _box ) |
---|
| 67 | { |
---|
| 68 | int result = INSIDE; |
---|
[8569] | 69 | //for each plane do ... |
---|
| 70 | for( int i = 0; i < 6; ++i ) { |
---|
[8319] | 71 | |
---|
[8569] | 72 | // is the positive vertex outside? |
---|
[8319] | 73 | if ( planes[i].distance( _box.vertexP( planes[i].n ) ) < 0 ) |
---|
| 74 | return OUTSIDE; |
---|
[8569] | 75 | // is the negative vertex outside? |
---|
| 76 | else if ( planes[i].distance( _box.vertexN( planes[i].n ) ) < 0 ) |
---|
| 77 | result = INTERSECT; |
---|
[8319] | 78 | } |
---|
[8569] | 79 | return result; |
---|
[8319] | 80 | } |
---|
| 81 | |
---|
| 82 | inline int pointInFrustum( const Triple& _point) |
---|
| 83 | { |
---|
| 84 | int result = INSIDE; |
---|
| 85 | for(int i=0; i < 6; i++) { |
---|
| 86 | if (planes[i].distance( _point ) < 0) |
---|
| 87 | return OUTSIDE; |
---|
| 88 | } |
---|
| 89 | return result; |
---|
| 90 | } |
---|
| 91 | |
---|
| 92 | inline Plane getPlane( int _plane ) { return planes[_plane]; } |
---|
| 93 | inline void setFrustum( float *_m ) |
---|
| 94 | { |
---|
| 95 | planes[NEAR].setCoefficients( |
---|
| 96 | m( 3, 1 ) + m( 4, 1 ), |
---|
| 97 | m( 3, 2 ) + m( 4, 2 ), |
---|
| 98 | m( 3, 3 ) + m( 4, 3 ), |
---|
| 99 | m( 3, 4 ) + m( 4, 4 ) ); |
---|
[8775] | 100 | |
---|
[8319] | 101 | planes[FAR].setCoefficients( |
---|
| 102 | -m( 3, 1 ) + m( 4, 1 ), |
---|
| 103 | -m( 3, 2 ) + m( 4, 2 ), |
---|
| 104 | -m( 3, 3 ) + m( 4, 3 ), |
---|
| 105 | -m( 3, 4 ) + m( 4, 4 ) ); |
---|
[8775] | 106 | |
---|
[8319] | 107 | planes[BOTTOM].setCoefficients( |
---|
| 108 | m( 2, 1 ) + m( 4, 1 ), |
---|
| 109 | m( 2, 2 ) + m( 4, 2 ), |
---|
| 110 | m( 2, 3 ) + m( 4, 3 ), |
---|
| 111 | m( 2, 4 ) + m( 4, 4 ) ); |
---|
[8775] | 112 | |
---|
[8319] | 113 | planes[TOP].setCoefficients( |
---|
| 114 | -m( 2, 1 ) + m( 4, 1 ), |
---|
| 115 | -m( 2, 2 ) + m( 4, 2 ), |
---|
| 116 | -m( 2, 3 ) + m( 4, 3 ), |
---|
| 117 | -m( 2, 4 ) + m( 4, 4 ) ); |
---|
[8775] | 118 | |
---|
[8319] | 119 | planes[LEFT].setCoefficients( |
---|
| 120 | m( 1, 1 ) + m( 4, 1 ), |
---|
| 121 | m( 1, 2 ) + m( 4, 2 ), |
---|
| 122 | m( 1, 3 ) + m( 4, 3 ), |
---|
| 123 | m( 1, 4 ) + m( 4, 4 ) ); |
---|
[8775] | 124 | |
---|
[8319] | 125 | planes[RIGHT].setCoefficients( |
---|
| 126 | -m( 1, 1 ) + m( 4, 1 ), |
---|
| 127 | -m( 1, 2 ) + m( 4, 2 ), |
---|
| 128 | -m( 1, 3 ) + m( 4, 3 ), |
---|
| 129 | -m( 1, 4 ) + m( 4, 4 ) ); |
---|
[8775] | 130 | |
---|
| 131 | if ( planes[NEAR].d +planes[FAR].d > MAX_CLIP_DISTANCE ) { |
---|
| 132 | planes[FAR].d = -planes[NEAR].d+MAX_CLIP_DISTANCE; |
---|
| 133 | } |
---|
[8319] | 134 | } |
---|
| 135 | |
---|
| 136 | protected: |
---|
| 137 | Plane *planes; |
---|
| 138 | }; |
---|
| 139 | |
---|
| 140 | #endif |
---|