00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <math.h>
00022 #include <GLEXT/GLState.h>
00023 #include <GLEXT/GLCameraFrustum.h>
00024 #include <graph/OptionsDisplay.h>
00025
00026 Vector GLCameraFrustum::FrustrumRed(1.0f, 0.0f, 0.0f);
00027 Vector GLCameraFrustum::FrustrumBlue(0.0f, 0.0f, 1.0f);
00028 Vector GLCameraFrustum::FrustrumGreen(0.0f, 1.0f, 0.0f);
00029 Vector GLCameraFrustum::FrustrumWhite(1.0f, 1.0f, 1.0f);
00030
00031 GLCameraFrustum *GLCameraFrustum::instance_ = 0;
00032
00033 GLCameraFrustum *GLCameraFrustum::instance()
00034 {
00035 if (!instance_)
00036 {
00037 instance_ = new GLCameraFrustum;
00038 }
00039
00040 return instance_;
00041 }
00042
00043 GLCameraFrustum::GLCameraFrustum() :
00044 GameStateI("GLCameraFrustum")
00045 {
00046
00047 }
00048
00049 GLCameraFrustum::~GLCameraFrustum()
00050 {
00051
00052 }
00053
00054 void GLCameraFrustum::normalize(float vector[4])
00055 {
00056 float fT = (float) sqrt(
00057 vector[0] * vector[0] +
00058 vector[1] * vector[1] +
00059 vector[2] * vector[2]);
00060
00061 vector[0] /= fT;
00062 vector[1] /= fT;
00063 vector[2] /= fT;
00064 vector[3] /= fT;
00065 }
00066
00067 Vector &GLCameraFrustum::getBilboardVectorX()
00068 {
00069 static Vector bil;
00070 bil[0] = s.fClip[0];
00071 bil[1] = s.fClip[4];
00072 bil[2] = s.fClip[8];
00073 bil *= s.aspect * 0.8f;
00074
00075 return bil;
00076 }
00077
00078 Vector &GLCameraFrustum::getBilboardVectorY()
00079 {
00080 static Vector bil;
00081 bil[0] = s.fClip[1];
00082 bil[1] = s.fClip[5];
00083 bil[2] = s.fClip[9];
00084 bil *= 0.8f;
00085
00086 return bil;
00087 }
00088
00089 void GLCameraFrustum::draw(const unsigned state)
00090 {
00091
00092
00093 glGetFloatv(GL_PROJECTION_MATRIX, s.fProj);
00094 glGetFloatv(GL_MODELVIEW_MATRIX, s.fView);
00095 glGetFloatv(GL_VIEWPORT, s.viewport);
00096 s.aspect = s.viewport[2] / s.viewport[3];
00097
00098
00099 s.fClip[ 0] = s.fView[ 0] * s.fProj[ 0] + s.fView[ 1] * s.fProj[ 4] + s.fView[ 2] * s.fProj[ 8] + s.fView[ 3] * s.fProj[12];
00100 s.fClip[ 1] = s.fView[ 0] * s.fProj[ 1] + s.fView[ 1] * s.fProj[ 5] + s.fView[ 2] * s.fProj[ 9] + s.fView[ 3] * s.fProj[13];
00101 s.fClip[ 2] = s.fView[ 0] * s.fProj[ 2] + s.fView[ 1] * s.fProj[ 6] + s.fView[ 2] * s.fProj[10] + s.fView[ 3] * s.fProj[14];
00102 s.fClip[ 3] = s.fView[ 0] * s.fProj[ 3] + s.fView[ 1] * s.fProj[ 7] + s.fView[ 2] * s.fProj[11] + s.fView[ 3] * s.fProj[15];
00103
00104 s.fClip[ 4] = s.fView[ 4] * s.fProj[ 0] + s.fView[ 5] * s.fProj[ 4] + s.fView[ 6] * s.fProj[ 8] + s.fView[ 7] * s.fProj[12];
00105 s.fClip[ 5] = s.fView[ 4] * s.fProj[ 1] + s.fView[ 5] * s.fProj[ 5] + s.fView[ 6] * s.fProj[ 9] + s.fView[ 7] * s.fProj[13];
00106 s.fClip[ 6] = s.fView[ 4] * s.fProj[ 2] + s.fView[ 5] * s.fProj[ 6] + s.fView[ 6] * s.fProj[10] + s.fView[ 7] * s.fProj[14];
00107 s.fClip[ 7] = s.fView[ 4] * s.fProj[ 3] + s.fView[ 5] * s.fProj[ 7] + s.fView[ 6] * s.fProj[11] + s.fView[ 7] * s.fProj[15];
00108
00109 s.fClip[ 8] = s.fView[ 8] * s.fProj[ 0] + s.fView[ 9] * s.fProj[ 4] + s.fView[10] * s.fProj[ 8] + s.fView[11] * s.fProj[12];
00110 s.fClip[ 9] = s.fView[ 8] * s.fProj[ 1] + s.fView[ 9] * s.fProj[ 5] + s.fView[10] * s.fProj[ 9] + s.fView[11] * s.fProj[13];
00111 s.fClip[10] = s.fView[ 8] * s.fProj[ 2] + s.fView[ 9] * s.fProj[ 6] + s.fView[10] * s.fProj[10] + s.fView[11] * s.fProj[14];
00112 s.fClip[11] = s.fView[ 8] * s.fProj[ 3] + s.fView[ 9] * s.fProj[ 7] + s.fView[10] * s.fProj[11] + s.fView[11] * s.fProj[15];
00113
00114 s.fClip[12] = s.fView[12] * s.fProj[ 0] + s.fView[13] * s.fProj[ 4] + s.fView[14] * s.fProj[ 8] + s.fView[15] * s.fProj[12];
00115 s.fClip[13] = s.fView[12] * s.fProj[ 1] + s.fView[13] * s.fProj[ 5] + s.fView[14] * s.fProj[ 9] + s.fView[15] * s.fProj[13];
00116 s.fClip[14] = s.fView[12] * s.fProj[ 2] + s.fView[13] * s.fProj[ 6] + s.fView[14] * s.fProj[10] + s.fView[15] * s.fProj[14];
00117 s.fClip[15] = s.fView[12] * s.fProj[ 3] + s.fView[13] * s.fProj[ 7] + s.fView[14] * s.fProj[11] + s.fView[15] * s.fProj[15];
00118
00119
00120 s.frustum_[0][0] = s.fClip[ 3] - s.fClip[ 0];
00121 s.frustum_[0][1] = s.fClip[ 7] - s.fClip[ 4];
00122 s.frustum_[0][2] = s.fClip[11] - s.fClip[ 8];
00123 s.frustum_[0][3] = s.fClip[15] - s.fClip[12];
00124 normalize(s.frustum_[0]);
00125
00126
00127 s.frustum_[1][0] = s.fClip[ 3] + s.fClip[ 0];
00128 s.frustum_[1][1] = s.fClip[ 7] + s.fClip[ 4];
00129 s.frustum_[1][2] = s.fClip[11] + s.fClip[ 8];
00130 s.frustum_[1][3] = s.fClip[15] + s.fClip[12];
00131 normalize(s.frustum_[1]);
00132
00133
00134 s.frustum_[2][0] = s.fClip[ 3] + s.fClip[ 1];
00135 s.frustum_[2][1] = s.fClip[ 7] + s.fClip[ 5];
00136 s.frustum_[2][2] = s.fClip[11] + s.fClip[ 9];
00137 s.frustum_[2][3] = s.fClip[15] + s.fClip[13];
00138 normalize(s.frustum_[2]);
00139
00140
00141 s.frustum_[3][0] = s.fClip[ 3] - s.fClip[ 1];
00142 s.frustum_[3][1] = s.fClip[ 7] - s.fClip[ 5];
00143 s.frustum_[3][2] = s.fClip[11] - s.fClip[ 9];
00144 s.frustum_[3][3] = s.fClip[15] - s.fClip[13];
00145 normalize(s.frustum_[3]);
00146
00147
00148 s.frustum_[4][0] = s.fClip[ 3] - s.fClip[ 2];
00149 s.frustum_[4][1] = s.fClip[ 7] - s.fClip[ 6];
00150 s.frustum_[4][2] = s.fClip[11] - s.fClip[10];
00151 s.frustum_[4][3] = s.fClip[15] - s.fClip[14];
00152 normalize(s.frustum_[4]);
00153
00154
00155 s.frustum_[5][0] = s.fClip[ 3] + s.fClip[ 2];
00156 s.frustum_[5][1] = s.fClip[ 7] + s.fClip[ 6];
00157 s.frustum_[5][2] = s.fClip[11] + s.fClip[10];
00158 s.frustum_[5][3] = s.fClip[15] + s.fClip[14];
00159 normalize(s.frustum_[5]);
00160 }
00161
00162 bool GLCameraFrustum::sphereInFrustum(Vector &point,
00163 float fRadius, Vector &color)
00164 {
00165 if (OptionsDisplay::instance()->getDrawBoundingSpheres())
00166 {
00167 static GLUquadric *obj = 0;
00168 if (!obj)
00169 {
00170 obj = gluNewQuadric();
00171 gluQuadricDrawStyle(obj, GLU_LINE);
00172 }
00173
00174 GLState glState(GLState::TEXTURE_OFF);
00175 glColor3fv(color);
00176 glPushMatrix();
00177 glTranslatef(point[0], point[1], point[2]);
00178 gluSphere(obj, fRadius, 6, 6);
00179 glPopMatrix();
00180 }
00181
00182 return sphereInFrustumThreadSafe(point, fRadius);
00183 }
00184
00185 bool GLCameraFrustum::sphereInFrustumThreadSafe(Vector &point, float fRadius)
00186 {
00187 for (int iCurPlane = 0; iCurPlane<6; iCurPlane++)
00188 {
00189 float value =
00190 s.frustum_[iCurPlane][0] * point[0] +
00191 s.frustum_[iCurPlane][1] * point[1] +
00192 s.frustum_[iCurPlane][2] * point[2] +
00193 s.frustum_[iCurPlane][3];
00194 if (value <= -fRadius)
00195 {
00196 return false;
00197 }
00198 }
00199
00200 return true;
00201 }
00202
00203 void GLCameraFrustum::backupFrustum()
00204 {
00205 memcpy(&b, &s, sizeof(b));
00206 }
00207
00208 void GLCameraFrustum::restoreFrustum()
00209 {
00210 memcpy(&s, &b, sizeof(b));
00211 }
00212
00213 void GLCameraFrustum::drawBilboard(Vector &position, Vector &color, float alpha,
00214 float width, float height, bool additive, int textureCoord)
00215 {
00216 if (additive) glBlendFunc(GL_SRC_ALPHA, GL_ONE);
00217
00218 Vector &bilX = getBilboardVectorX();
00219 Vector &bilY = getBilboardVectorY();
00220
00221 float bilXX = bilX[0] * width;
00222 float bilXY = bilX[1] * width;
00223 float bilXZ = bilX[2] * width;
00224 float bilYX = bilY[0] * height;
00225 float bilYY = bilY[1] * height;
00226 float bilYZ = bilY[2] * height;
00227
00228 glColor4f(color[0], color[1], color[2], alpha);
00229 glBegin(GL_QUADS);
00230 switch(textureCoord)
00231 {
00232 default: glTexCoord2d(1.0f, 1.0f); break;
00233 case 1: glTexCoord2d(0.0f, 1.0f); break;
00234 case 2: glTexCoord2d(0.0f, 0.0f); break;
00235 case 3: glTexCoord2d(1.0f, 0.0f); break;
00236 }
00237 glVertex3f(
00238 position[0] + bilXX + bilYX,
00239 position[1] + bilXY + bilYY,
00240 position[2] + bilXZ + bilYZ);
00241 switch(textureCoord)
00242 {
00243 default: glTexCoord2d(0.0f, 1.0f); break;
00244 case 1: glTexCoord2d(0.0f, 0.0f); break;
00245 case 2: glTexCoord2d(1.0f, 0.0f); break;
00246 case 3: glTexCoord2d(1.0f, 1.0f); break;
00247 }
00248 glVertex3f(
00249 position[0] - bilXX + bilYX,
00250 position[1] - bilXY + bilYY,
00251 position[2] - bilXZ + bilYZ);
00252 switch(textureCoord)
00253 {
00254 default: glTexCoord2d(0.0f, 0.0f); break;
00255 case 1: glTexCoord2d(1.0f, 0.0f); break;
00256 case 2: glTexCoord2d(1.0f, 1.0f); break;
00257 case 3: glTexCoord2d(0.0f, 1.0f); break;
00258 }
00259 glVertex3f(
00260 position[0] - bilXX - bilYX,
00261 position[1] - bilXY - bilYY,
00262 position[2] - bilXZ - bilYZ);
00263 switch(textureCoord)
00264 {
00265 default: glTexCoord2d(1.0f, 0.0f); break;
00266 case 1: glTexCoord2d(1.0f, 1.0f); break;
00267 case 2: glTexCoord2d(0.0f, 1.0f); break;
00268 case 3: glTexCoord2d(0.0f, 0.0f); break;
00269 }
00270 glVertex3f(
00271 position[0] + bilXX - bilYX,
00272 position[1] + bilXY - bilYY,
00273 position[2] + bilXZ - bilYZ);
00274 glEnd();
00275
00276 if (additive) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00277 }
00278