00001
00002
00003 #include "Mesh.h"
00004
00005 #include "AABB.h"
00006 #include "Plane.h"
00007 #include "Renderer.h"
00008 #include "Sphere.h"
00009
00010
00011 namespace pge {
00012
00013
00014
00015
00016
00017
00018
00019 Mesh::Mesh(void) {
00020 m_triangles = new std::vector<Triangle*>();
00021 m_alphaColor = 1.0f;
00022 m_displayList = 0;
00023 m_renderMode = DisplayList;
00024 m_boundingBox = NULL;
00025 m_boundingSphere = NULL;
00026 m_debugRender = false;
00027 }
00028
00029
00030
00031
00032
00033
00034
00035 Mesh::~Mesh(void) {
00036 std::vector<Triangle*>::iterator it;
00037
00038
00039 if(m_boundingBox != NULL) {
00040 delete m_boundingBox;
00041 m_boundingBox = NULL;
00042 }
00043 if(m_boundingSphere != NULL) {
00044 delete m_boundingSphere;
00045 m_boundingSphere = NULL;
00046 }
00047
00048 if(m_triangles != NULL) {
00049 for(it = m_triangles->begin(); it != m_triangles->end(); it++) {
00050 delete *it;
00051 *it = NULL;
00052 }
00053 delete m_triangles;
00054 m_triangles = NULL;
00055 }
00056
00057 switch(m_renderMode) {
00058 case Immediate:
00059 break;
00060 case DisplayList:
00061 renderer::deleteDisplayList(m_displayList);
00062 break;
00063 }
00064
00065 }
00066
00067
00068
00069
00070
00071
00072
00073 bool Mesh::init(void) {
00074
00075 buildBoundingBox();
00076
00077
00078 buildBoundingSphere();
00079
00080
00081 switch(m_renderMode) {
00082 case Immediate:
00083 break;
00084 case DisplayList:
00085 buildDisplayList();
00086 break;
00087 }
00088 return true;
00089 }
00090
00091
00092
00093
00094
00095
00096
00097 void Mesh::render(void) {
00098 switch(m_renderMode) {
00099 case Immediate:
00100 renderImmediate();
00101 break;
00102 case DisplayList:
00103 renderDisplayList();
00104 break;
00105 }
00106 }
00107
00108
00109
00110
00111
00112
00113
00114 void Mesh::timer(unsigned int delay) {
00115 }
00116
00117
00118
00119
00120
00121
00122
00123 std::vector<Triangle*>* Mesh::getTriangles(void) {
00124 return m_triangles;
00125 }
00126
00127
00128
00129
00130
00131
00132
00133 int Mesh::getTriangleNum(void) {
00134 return (int)m_triangles->size();
00135 }
00136
00137
00138
00139
00140
00141
00142
00143 int Mesh::getVertexNum(void) {
00144 return (int)m_triangles->size() * 3;
00145 }
00146
00147
00148
00149
00150
00151
00152
00153 AABB* Mesh::getBoundingBox(void) {
00154 return m_boundingBox;
00155 }
00156
00157
00158
00159
00160
00161
00162
00163 Sphere* Mesh::getBoundingSphere(void) {
00164 return m_boundingSphere;
00165 }
00166
00167
00168
00169
00170
00171
00172
00173 void Mesh::setAlphaColor(float alpha) {
00174 }
00175
00176
00177
00178
00179
00180
00181
00182 bool Mesh::addTriangle(Triangle triangle) {
00183
00184 if(triangle.m_vertices == NULL) {
00185 return false;
00186 }
00187
00188
00189 if(triangle.m_texCoords == NULL) {
00190 return false;
00191 }
00192
00193
00194 if (triangle.m_plane == NULL) {
00195 triangle.m_plane = new Plane(&triangle);
00196 }
00197
00198
00199 m_triangles->push_back(new Triangle(triangle));
00200
00201 return true;
00202 }
00203
00204
00205
00206
00207
00208
00209
00210 bool Mesh::getHeightAt(float posX, float posZ, float *result) {
00211 std::vector<Triangle*>::iterator it;
00212
00213 for(it = m_triangles->begin(); it != m_triangles->end(); it++) {
00214 Triangle *triangle = *it;
00215
00216 Vector3f point = triangle->m_plane->getIntersectionPoint(Vector3f(posX, m_boundingBox->m_maxY + 1.0f,
00217 posZ), Vector3f(posX, m_boundingBox->m_maxY - 1.0f, posZ));
00218 if(triangle::isPointInside(point, *triangle)) {
00219 *result = point.m_v[1];
00220 return true;
00221 }
00222 }
00223 return false;
00224 }
00225
00226
00227
00228
00229
00230
00231
00232 bool Mesh::isHeightQueryInside(float posX, float posZ) {
00233
00234 if (posX >= m_boundingBox->m_minX && posX <= m_boundingBox->m_maxX && posZ >= m_boundingBox->m_minZ
00235 && posZ <= m_boundingBox->m_maxZ) {
00236 return true;
00237 }
00238 return false;
00239 }
00240
00241
00242
00243
00244
00245
00246
00247 void Mesh::buildBoundingBox(void) {
00248
00249
00250
00251 float minX;
00252 float minY;
00253 float minZ;
00254 float maxX;
00255 float maxY;
00256 float maxZ;
00257 int i;
00258 Vector3f temp;
00259 std::vector<Triangle*>::iterator it;
00260
00261
00262
00263 if(m_triangles->size() < 1) {
00264 m_boundingBox = new AABB(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
00265 return;
00266 }
00267
00268
00269 temp = m_triangles->at(0)->m_vertices[0];
00270 minX = temp.m_v[0];
00271 minY = temp.m_v[1];
00272 minZ = temp.m_v[2];
00273 maxX = temp.m_v[0];
00274 maxY = temp.m_v[1];
00275 maxZ = temp.m_v[2];
00276
00277
00278 for(it = m_triangles->begin(); it != m_triangles->end(); it++) {
00279 Triangle *triangle = *it;
00280
00281 for (i = 0; i < 3; i++) {
00282 Vector3f v = triangle->m_vertices[i];
00283 if (v.m_v[0] < minX) {
00284 minX = v.m_v[0];
00285 }
00286 if (v.m_v[1] < minY) {
00287 minY = v.m_v[1];
00288 }
00289 if (v.m_v[2] < minZ) {
00290 minZ = v.m_v[2];
00291 }
00292
00293 if (v.m_v[0] > maxX) {
00294 maxX = v.m_v[0];
00295 }
00296 if (v.m_v[1] > maxY) {
00297 maxY = v.m_v[1];
00298 }
00299 if (v.m_v[2] > maxZ) {
00300 maxZ = v.m_v[2];
00301 }
00302 }
00303 }
00304 if(m_boundingBox != NULL) {
00305 m_boundingBox->m_minX = minX;
00306 m_boundingBox->m_minY = minY;
00307 m_boundingBox->m_minZ = minZ;
00308 m_boundingBox->m_maxX = maxX;
00309 m_boundingBox->m_maxY = maxY;
00310 m_boundingBox->m_maxZ = maxZ;
00311 } else {
00312 m_boundingBox = new AABB(minX, minY, minZ, maxX, maxY, maxZ);
00313 }
00314 }
00315
00316
00317
00318
00319
00320
00321
00322 void Mesh::buildBoundingSphere(void) {
00323
00324
00325
00326 int i;
00327 float totalMass;
00328 Vector3f center;
00329 float mag;
00330 float max = 0.0f;
00331 Vector3f vertex;
00332 Vector3f temp;
00333 std::vector<Triangle*>::iterator it;
00334
00335
00336
00337 center = Vector3f();
00338 totalMass = (float)getVertexNum();
00339
00340 for(it = m_triangles->begin(); it != m_triangles->end(); it++) {
00341 Triangle *triangle = *it;
00342
00343 for (i = 0; i < 3; i++) {
00344 center.m_v[0] = center.m_v[0] + triangle->m_vertices[i].m_v[0];
00345 center.m_v[1] = center.m_v[1] + triangle->m_vertices[i].m_v[1];
00346 center.m_v[2] = center.m_v[2] + triangle->m_vertices[i].m_v[2];
00347 }
00348 }
00349 center.m_v[0] = center.m_v[0] / totalMass;
00350 center.m_v[1] = center.m_v[1] / totalMass;
00351 center.m_v[2] = center.m_v[2] / totalMass;
00352
00353
00354 for(it = m_triangles->begin(); it != m_triangles->end(); it++) {
00355 Triangle *triangle = *it;
00356
00357
00358 for (i = 0; i < 3; i++) {
00359 vertex = triangle->m_vertices[i];
00360 temp = vertex.subtract(center);
00361 mag = temp.magnitude();
00362 if (mag > max) {
00363 max = mag;
00364 }
00365 }
00366 }
00367
00368 m_boundingSphere = new Sphere(center, max);
00369 }
00370
00371
00372
00373
00374
00375
00376
00377 void Mesh::buildDisplayList(void) {
00378 m_displayList = renderer::createDisplayList();
00379 renderImmediate();
00380 renderer::endDisplayList();
00381
00382 }
00383
00384
00385
00386
00387
00388
00389
00390 void Mesh::renderImmediate(void) {
00391 std::vector<Triangle*>::iterator it;
00392
00393
00394 for(it = m_triangles->begin(); it != m_triangles->end(); it++) {
00395 Triangle *triangle = *it;
00396
00397 if(triangle->m_texture != NULL) {
00398
00399 if(triangle->m_texture->hasAlphaBlending()) {
00400 renderer::setTextureAlphaBlendEnabled(true);
00401 } else if(m_alphaColor < 1.0f) {
00402 renderer::setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00403 renderer::setBlendingEnabled(true);
00404 }
00405 renderer::setTexture(triangle->m_texture, GL_MODULATE);
00406 } else {
00407 glDisable(GL_TEXTURE_2D);
00408 }
00409
00410 renderer::color4f(1.0f, 1.0f, 1.0f, m_alphaColor);
00411
00412 glBegin(GL_TRIANGLES);
00413 renderer::normal3f(triangle->m_plane->m_normal);
00414 renderer::vertex3f(triangle->m_vertices[0], triangle->m_texCoords[0]);
00415 renderer::normal3f(triangle->m_plane->m_normal);
00416 renderer::vertex3f(triangle->m_vertices[1], triangle->m_texCoords[1]);
00417 renderer::normal3f(triangle->m_plane->m_normal);
00418 renderer::vertex3f(triangle->m_vertices[2], triangle->m_texCoords[2]);
00419 glEnd();
00420
00421 if(triangle->m_texture != NULL) {
00422
00423 if(triangle->m_texture->hasAlphaBlending()) {
00424 renderer::setTextureAlphaBlendEnabled(false);
00425 }
00426 }
00427 if(m_alphaColor < 1.0f) {
00428 renderer::setBlendingEnabled(false);
00429
00430 renderer::color4f(1.0f, 1.0f, 1.0f, 1.0f);
00431 }
00432 }
00433 }
00434
00435
00436
00437
00438
00439
00440
00441 void Mesh::renderDisplayList(void) {
00442 renderer::executeDisplayList(m_displayList);
00443 }
00444 };