00001
00002
00003 #include "Frustum.h"
00004
00005 #include "AABB.h"
00006 #include "Renderer.h"
00007
00008 #include <math.h>
00009
00010
00011 namespace pge {
00012
00013
00014
00015
00016
00017
00018
00019 Frustum::Frustum(void) {
00020 }
00021
00022
00023
00024
00025
00026
00027
00028 Frustum::~Frustum(void) {
00029 }
00030
00031
00032
00033
00034
00035
00036
00037 void Frustum::update(void) {
00038 float projMatrix[16];
00039 float modelMatrix[16];
00040 float clip[16];
00041
00042
00043 glGetFloatv(GL_PROJECTION_MATRIX, projMatrix);
00044 glGetFloatv(GL_MODELVIEW_MATRIX, modelMatrix);
00045
00046
00047 clip[0] = modelMatrix[0] * projMatrix[0] + modelMatrix[1] * projMatrix[4] + modelMatrix[2] * projMatrix[8] + modelMatrix[3] * projMatrix[12];
00048 clip[1] = modelMatrix[0] * projMatrix[1] + modelMatrix[1] * projMatrix[5] + modelMatrix[2] * projMatrix[9] + modelMatrix[3] * projMatrix[13];
00049 clip[2] = modelMatrix[0] * projMatrix[2] + modelMatrix[1] * projMatrix[6] + modelMatrix[2] * projMatrix[10] + modelMatrix[3] * projMatrix[14];
00050 clip[3] = modelMatrix[0] * projMatrix[3] + modelMatrix[1] * projMatrix[7] + modelMatrix[2] * projMatrix[11] + modelMatrix[3] * projMatrix[15];
00051
00052 clip[4] = modelMatrix[4] * projMatrix[0] + modelMatrix[5] * projMatrix[4] + modelMatrix[6] * projMatrix[8] + modelMatrix[7] * projMatrix[12];
00053 clip[5] = modelMatrix[4] * projMatrix[1] + modelMatrix[5] * projMatrix[5] + modelMatrix[6] * projMatrix[9] + modelMatrix[7] * projMatrix[13];
00054 clip[6] = modelMatrix[4] * projMatrix[2] + modelMatrix[5] * projMatrix[6] + modelMatrix[6] * projMatrix[10] + modelMatrix[7] * projMatrix[14];
00055 clip[7] = modelMatrix[4] * projMatrix[3] + modelMatrix[5] * projMatrix[7] + modelMatrix[6] * projMatrix[11] + modelMatrix[7] * projMatrix[15];
00056
00057 clip[8] = modelMatrix[8] * projMatrix[0] + modelMatrix[9] * projMatrix[4] + modelMatrix[10] * projMatrix[8] + modelMatrix[11] * projMatrix[12];
00058 clip[9] = modelMatrix[8] * projMatrix[1] + modelMatrix[9] * projMatrix[5] + modelMatrix[10] * projMatrix[9] + modelMatrix[11] * projMatrix[13];
00059 clip[10] = modelMatrix[8] * projMatrix[2] + modelMatrix[9] * projMatrix[6] + modelMatrix[10] * projMatrix[10] + modelMatrix[11] * projMatrix[14];
00060 clip[11] = modelMatrix[8] * projMatrix[3] + modelMatrix[9] * projMatrix[7] + modelMatrix[10] * projMatrix[11] + modelMatrix[11] * projMatrix[15];
00061
00062 clip[12] = modelMatrix[12] * projMatrix[0] + modelMatrix[13] * projMatrix[4] + modelMatrix[14] * projMatrix[8] + modelMatrix[15] * projMatrix[12];
00063 clip[13] = modelMatrix[12] * projMatrix[1] + modelMatrix[13] * projMatrix[5] + modelMatrix[14] * projMatrix[9] + modelMatrix[15] * projMatrix[13];
00064 clip[14] = modelMatrix[12] * projMatrix[2] + modelMatrix[13] * projMatrix[6] + modelMatrix[14] * projMatrix[10] + modelMatrix[15] * projMatrix[14];
00065 clip[15] = modelMatrix[12] * projMatrix[3] + modelMatrix[13] * projMatrix[7] + modelMatrix[14] * projMatrix[11] + modelMatrix[15] * projMatrix[15];
00066
00067
00068 m_frustum[PLANE_RIGHT][0] = clip[3] - clip[0];
00069 m_frustum[PLANE_RIGHT][1] = clip[7] - clip[4];
00070 m_frustum[PLANE_RIGHT][2] = clip[11] - clip[8];
00071 m_frustum[PLANE_RIGHT][3] = clip[15] - clip[12];
00072 normalizePlane(PLANE_RIGHT);
00073
00074 m_frustum[PLANE_LEFT][0] = clip[3] + clip[0];
00075 m_frustum[PLANE_LEFT][1] = clip[7] + clip[4];
00076 m_frustum[PLANE_LEFT][2] = clip[11] + clip[8];
00077 m_frustum[PLANE_LEFT][3] = clip[15] + clip[12];
00078 normalizePlane(PLANE_LEFT);
00079
00080 m_frustum[PLANE_BOTTOM][0] = clip[3] + clip[1];
00081 m_frustum[PLANE_BOTTOM][1] = clip[7] + clip[5];
00082 m_frustum[PLANE_BOTTOM][2] = clip[11] + clip[9];
00083 m_frustum[PLANE_BOTTOM][3] = clip[15] + clip[13];
00084 normalizePlane(PLANE_BOTTOM);
00085
00086 m_frustum[PLANE_TOP][0] = clip[3] - clip[1];
00087 m_frustum[PLANE_TOP][1] = clip[7] - clip[5];
00088 m_frustum[PLANE_TOP][2] = clip[11] - clip[9];
00089 m_frustum[PLANE_TOP][3] = clip[15] - clip[13];
00090 normalizePlane(PLANE_TOP);
00091
00092 m_frustum[PLANE_FAR][0] = clip[3] - clip[2];
00093 m_frustum[PLANE_FAR][1] = clip[7] - clip[6];
00094 m_frustum[PLANE_FAR][2] = clip[11] - clip[10];
00095 m_frustum[PLANE_FAR][3] = clip[15] - clip[14];
00096 normalizePlane(PLANE_FAR);
00097
00098 m_frustum[PLANE_NEAR][0] = clip[3] + clip[2];
00099 m_frustum[PLANE_NEAR][1] = clip[7] + clip[6];
00100 m_frustum[PLANE_NEAR][2] = clip[11] + clip[10];
00101 m_frustum[PLANE_NEAR][3] = clip[15] + clip[14];
00102 normalizePlane(PLANE_NEAR);
00103 }
00104
00105
00106
00107
00108
00109
00110
00111 void Frustum::normalizePlane(int plane) {
00112 float mag;
00113
00114
00115 mag = (float)sqrt((double)(m_frustum[plane][0] * m_frustum[plane][0] + m_frustum[plane][1] * m_frustum[plane][1] +
00116 m_frustum[plane][2] * m_frustum[plane][2]));
00117
00118 m_frustum[plane][0] = m_frustum[plane][0] / mag;
00119 m_frustum[plane][1] = m_frustum[plane][1] / mag;
00120 m_frustum[plane][2] = m_frustum[plane][2] / mag;
00121 m_frustum[plane][3] = m_frustum[plane][3] / mag;
00122 }
00123
00124
00125
00126
00127
00128
00129
00130 bool Frustum::isPointInside(Vector3f v) {
00131 int i;
00132
00133
00134 for(i = 0; i < 6; i++) {
00135 if((m_frustum[i][0] * v.m_v[0] + m_frustum[i][1] * v.m_v[1] + m_frustum[i][2] * v.m_v[2] + m_frustum[i][3]) <= 0.0f) {
00136 return false;
00137 }
00138 }
00139 return true;
00140 }
00141
00142
00143
00144
00145
00146
00147
00148 bool Frustum::isPointInside(float x, float y, float z) {
00149 int i;
00150
00151
00152 for(i = 0; i < 6; i++) {
00153 if((m_frustum[i][0] * x + m_frustum[i][1] * y + m_frustum[i][2] * z + m_frustum[i][3]) <= 0.0f) {
00154 return false;
00155 }
00156 }
00157 return true;
00158 }
00159
00160
00161
00162
00163
00164
00165
00166 bool Frustum::isAABBInside(AABB *aabb) {
00167 int i;
00168
00169
00170
00171
00172 for(i = 0; i < 6; i++) {
00173 if(getDistanceToPlane(i, aabb->m_minX, aabb->m_minY, aabb->m_minZ) > 0.0f)
00174 continue;
00175 if(getDistanceToPlane(i, aabb->m_maxX, aabb->m_minY, aabb->m_minZ) > 0.0f)
00176 continue;
00177 if(getDistanceToPlane(i, aabb->m_minX, aabb->m_maxY, aabb->m_minZ) > 0.0f)
00178 continue;
00179 if(getDistanceToPlane(i, aabb->m_maxX, aabb->m_maxY, aabb->m_minZ) > 0.0f)
00180 continue;
00181 if(getDistanceToPlane(i, aabb->m_minX, aabb->m_minY, aabb->m_maxZ) > 0.0f)
00182 continue;
00183 if(getDistanceToPlane(i, aabb->m_maxX, aabb->m_minY, aabb->m_maxZ) > 0.0f)
00184 continue;
00185 if(getDistanceToPlane(i, aabb->m_minX, aabb->m_maxY, aabb->m_maxZ) > 0.0f)
00186 continue;
00187 if(getDistanceToPlane(i, aabb->m_maxX, aabb->m_maxY, aabb->m_maxZ) > 0.0f)
00188 continue;
00189 return false;
00190 }
00191 return true;
00192 }
00193
00194
00195
00196
00197
00198
00199
00200 float Frustum::getDistanceToPlane(int plane, float x, float y, float z) {
00201 return m_frustum[plane][0] * x + m_frustum[plane][1] * y + m_frustum[plane][2] * z
00202 + m_frustum[plane][3];
00203 }
00204 };