Go to the documentation of this file.00001 #ifndef OPENTISSUE_UTILITY_GL_GL_FRUSTUM_H
00002 #define OPENTISSUE_UTILITY_GL_GL_FRUSTUM_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/utility/gl/gl.h>
00013 #include <OpenTissue/core/geometry/geometry_plane.h>
00014
00015 #include <cassert>
00016
00017 namespace OpenTissue
00018 {
00019
00020 namespace gl
00021 {
00022
00026 template<typename types>
00027 class Frustum
00028 {
00029 public:
00030
00031 typedef typename types::real_type real_type;
00032 typedef typename types::vector3_type vector3_type;
00033 typedef geometry::Plane<types> plane_type;
00034
00035 const static unsigned int RIGHT = 0u;
00036 const static unsigned int LEFT = 1u;
00037 const static unsigned int BOTTOM = 2u;
00038 const static unsigned int TOP = 3u;
00039 const static unsigned int BACK = 4u;
00040 const static unsigned int FRONT = 5u;
00041
00042 protected:
00043
00044 plane_type m_planes[6];
00045
00046 public:
00047
00048 plane_type & get_plane(unsigned int const & i) { return m_planes[i]; }
00049 plane_type const & get_plane(unsigned int const & i) const { return m_planes[i]; }
00050
00051 protected:
00052
00060 void mul(GLfloat * A,GLfloat * B,GLfloat * C)
00061 {
00062 C[ 0] = A[0]*B[ 0] + A[4]*B[ 1] + A[ 8]*B[ 2] + A[12]*B[ 3];
00063 C[ 1] = A[1]*B[ 0] + A[5]*B[ 1] + A[ 9]*B[ 2] + A[13]*B[ 3];
00064 C[ 2] = A[2]*B[ 0] + A[6]*B[ 1] + A[10]*B[ 2] + A[14]*B[ 3];
00065 C[ 3] = A[3]*B[ 0] + A[7]*B[ 1] + A[11]*B[ 2] + A[15]*B[ 3];
00066 C[ 4] = A[0]*B[ 4] + A[4]*B[ 5] + A[ 8]*B[ 6] + A[12]*B[ 7];
00067 C[ 5] = A[1]*B[ 4] + A[5]*B[ 5] + A[ 9]*B[ 6] + A[13]*B[ 7];
00068 C[ 6] = A[2]*B[ 4] + A[6]*B[ 5] + A[10]*B[ 6] + A[14]*B[ 7];
00069 C[ 7] = A[3]*B[ 4] + A[7]*B[ 5] + A[11]*B[ 6] + A[15]*B[ 7];
00070 C[ 8] = A[0]*B[ 8] + A[4]*B[ 9] + A[ 8]*B[10] + A[12]*B[11];
00071 C[ 9] = A[1]*B[ 8] + A[5]*B[ 9] + A[ 9]*B[10] + A[13]*B[11];
00072 C[10] = A[2]*B[ 8] + A[6]*B[ 9] + A[10]*B[10] + A[14]*B[11];
00073 C[11] = A[3]*B[ 8] + A[7]*B[ 9] + A[11]*B[10] + A[15]*B[11];
00074 C[12] = A[0]*B[12] + A[4]*B[13] + A[ 8]*B[14] + A[12]*B[15];
00075 C[13] = A[1]*B[12] + A[5]*B[13] + A[ 9]*B[14] + A[13]*B[15];
00076 C[14] = A[2]*B[12] + A[6]*B[13] + A[10]*B[14] + A[14]*B[15];
00077 C[15] = A[3]*B[12] + A[7]*B[13] + A[11]*B[14] + A[15]*B[15];
00078 }
00079
00080 public:
00081
00085 void update()
00086 {
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104 GLfloat P[16];
00105 GLfloat M[16];
00106 GLfloat C[16];
00107 glGetFloatv( GL_PROJECTION_MATRIX, P );
00108 glGetFloatv( GL_MODELVIEW_MATRIX, M );
00109 mul(P,M,C);
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 m_planes[RIGHT].n()(0) = C[ 3] - C[0];
00157 m_planes[RIGHT].n()(1) = C[ 7] - C[4];
00158 m_planes[RIGHT].n()(2) = C[11] - C[8];
00159 m_planes[RIGHT].w() = -(C[15] - C[12]);
00160
00161 m_planes[LEFT].n()(0) = C[ 3] + C[ 0];
00162 m_planes[LEFT].n()(1) = C[ 7] + C[ 4];
00163 m_planes[LEFT].n()(2) = C[11] + C[ 8];
00164 m_planes[LEFT].w() = -(C[15] + C[12]);
00165
00166 m_planes[BOTTOM].n()(0) = C[ 3] + C[ 1];
00167 m_planes[BOTTOM].n()(1) = C[ 7] + C[ 5];
00168 m_planes[BOTTOM].n()(2) = C[11] + C[ 9];
00169 m_planes[BOTTOM].w() = -(C[15] + C[13]);
00170
00171 m_planes[TOP].n()(0) = C[ 3] - C[ 1];
00172 m_planes[TOP].n()(1) = C[ 7] - C[ 5];
00173 m_planes[TOP].n()(2) = C[11] - C[ 9];
00174 m_planes[TOP].w() = -(C[15] - C[13]);
00175
00176 m_planes[BACK].n()(0) = C[ 3] - C[ 2];
00177 m_planes[BACK].n()(1) = C[ 7] - C[ 6];
00178 m_planes[BACK].n()(2) = C[11] - C[10];
00179 m_planes[BACK].w() = -(C[15] - C[14]);
00180
00181 m_planes[FRONT].n()(0) = C[ 3] + C[ 2];
00182 m_planes[FRONT].n()(1) = C[ 7] + C[ 6];
00183 m_planes[FRONT].n()(2) = C[11] + C[10];
00184 m_planes[FRONT].w() = -(C[15] + C[14]);
00185
00186
00187 for(unsigned int i=0;i<6;++i)
00188 {
00189 real_type tmp = std::sqrt(m_planes[i].n()*m_planes[i].n());
00190 if(tmp)
00191 {
00192 m_planes[i].n() /= tmp;
00193 m_planes[i].w() /= tmp;
00194 }
00195 }
00196 };
00197
00201 template<typename aabb_type>
00202 const bool contains(aabb_type const & aabb) const
00203 {
00204 vector3_type center = aabb.center();
00205 vector3_type halfdiag = aabb.max()-aabb.center();
00206 for(int i = 0; i < 6; i++)
00207 {
00208 real_type m = m_planes[i].signed_distance(center);
00209 real_type n = halfdiag(0)*std::fabs(m_planes[i].n()(0)) + halfdiag(1)*std::fabs(m_planes[i].n()(1)) + halfdiag(2)*std::fabs(m_planes[i].n()(2));
00210 if (m + n < 0)
00211 return false;
00212 }
00213 return true;
00214 }
00218 const bool contains(vector3_type const & p) const
00219 {
00220 for(unsigned int i=0;i<6;++i)
00221 if(m_planes[i].signed_distance(p)<=0)
00222 return false;
00223 return true;
00224 }
00225
00229 const bool contains(vector3_type const & p,real_type const & radius) const
00230 {
00231 for(unsigned int i=0;i<6;++i)
00232 if(m_planes[i].signed_distance(p)<=-radius)
00233 return false;
00234 return true;
00235 }
00236
00237 };
00238
00239 }
00240
00241 }
00242
00243
00244 #endif