Main Page | Namespace List | Class Hierarchy | Alphabetical List | Data Structures | File List | Namespace Members | Data Fields | Globals

/Users/blackie/Documents/myRepository/phobosengine-vc2005/phobosengine/phobosengine/DynamicCity.cpp

Go to the documentation of this file.
00001 
00002 
00003 #include "DynamicCity.h"
00004 
00005 #include "AABB.h"
00006 #include "MathUtils.h"
00007 #include "Mesh.h"
00008 #include "MeshFactory.h"
00009 #include "SingleTexturedMesh.h"
00010 #include "TextureDatabase.h"
00011 
00012 
00013 namespace pge {
00014 
00015 
00016         //****************************************************************************
00017         //
00018         //
00019         //
00020         //****************************************************************************
00021         DynamicCity::DynamicCity(float width, float depth, Vector3f minHouseSize, Vector3f maxHouseSize) {
00022                 m_groundTexture = NULL;
00023                 m_roofTexture = NULL;
00024                 m_textures = new std::vector<Texture*>();
00025                 m_width = width;
00026                 m_depth = depth;
00027                 m_minHouseSize = minHouseSize;
00028                 m_maxHouseSize = maxHouseSize;
00029         }
00030 
00031 
00032         //****************************************************************************
00033         //
00034         //
00035         //
00036         //****************************************************************************
00037         DynamicCity::~DynamicCity(void) {
00038                 if(m_textures != NULL) {
00039                         delete m_textures;
00040                         m_textures = NULL;
00041                 }
00042         }
00043 
00044 
00045         //****************************************************************************
00046         //
00047         //
00048         //
00049         //****************************************************************************
00050         bool DynamicCity::init(void) {
00051                 AABB *box;
00052 
00053 
00054                 m_textures->push_back(TextureDatabase::getInstance()->addTexture("buldembassydoors_dl.jpg"));
00055                 m_textures->push_back(TextureDatabase::getInstance()->addTexture("bank_1_dl.jpg"));
00056                 m_textures->push_back(TextureDatabase::getInstance()->addTexture("bank_2_dl.jpg"));
00057                 m_textures->push_back(TextureDatabase::getInstance()->addTexture("building_2_dl.jpg"));
00058                 m_textures->push_back(TextureDatabase::getInstance()->addTexture("building_1_dl.jpg"));
00059                 m_textures->push_back(TextureDatabase::getInstance()->addTexture("buldembassyfront_dl.jpg"));
00060 
00061                 m_groundTexture = TextureDatabase::getInstance()->addTexture("brick_3_dl.jpg");
00062                 m_roofTexture = TextureDatabase::getInstance()->addTexture("buldembassyroof2.jpg");
00063 
00064                 // Create the city meshes.
00065                 createCity();
00066 
00067                 buildBoundingBox();
00068 
00069                 box = getBoundingBox();
00070 
00071                 // Create the ground.
00072                 createGround(Vector3f(box->m_minX, box->m_minY, box->m_minZ), Vector3f(box->m_maxX, box->m_minY, box->m_maxZ));
00073 
00074                 MeshModel::init();
00075                 return true;
00076         }
00077 
00078 
00079         //****************************************************************************
00080         //
00081         //
00082         //
00083         //****************************************************************************
00084         void DynamicCity::createCity(void) {
00085                 float positionX;
00086                 float positionZ;
00087                 float width;
00088                 float depth;
00089                 float height;
00090                 float spaceX;
00091                 float spaceZ;
00092                 float oldWidth;
00093                 float maxDepth;
00094 
00095                 float houseMaxWidth;
00096                 float houseMaxHeight;
00097                 float houseMaxDepth;
00098                 float houseMinWidth;
00099                 float houseMinHeight;
00100                 float houseMinDepth;
00101 
00102                 int textureIndex;
00103 
00104                 Vector3f cityStartEdge;
00105                 Vector3f cityEndEdge;
00106 
00107 
00108                 // The start and end points of the city.
00109                 cityStartEdge = Vector3f(-(m_width / 2.0f), 0.0f, -(m_depth / 2.0f));
00110                 cityEndEdge = Vector3f(m_width / 2.0f, 0.0f, m_depth / 2.0f);
00111 
00112                 // Max and min dimensions for the generated houses.
00113                 houseMaxWidth = m_maxHouseSize.m_v[0];
00114                 houseMaxHeight = m_maxHouseSize.m_v[1];
00115                 houseMaxDepth = m_maxHouseSize.m_v[2];
00116 
00117                 houseMinWidth = m_minHouseSize.m_v[0];
00118                 houseMinHeight = m_minHouseSize.m_v[1];
00119                 houseMinDepth = m_minHouseSize.m_v[2];
00120 
00121                 positionX = cityStartEdge.m_v[0];
00122                 positionZ = cityStartEdge.m_v[2];
00123 
00124                 oldWidth = 0.0f;
00125 
00126                 maxDepth = 0.0f;
00127 
00128                 for(; positionZ <= cityEndEdge.m_v[2];) {
00129 
00130                         // Reset maxdepth to find the new max depth in every iteration.
00131                         maxDepth = 0.0f;
00132 
00133                         for(; positionX <= cityEndEdge.m_v[0];) {
00134                                 float w = mathutils::random(0.0f, houseMaxWidth);
00135                                 float d = mathutils::random(0.0f, houseMaxDepth);
00136                                 float h = 0.0f;
00137                                 
00138                                 if(mathutils::random() > 0.95f) {
00139                                         h = mathutils::random(0.0f, houseMaxHeight * 2);
00140                                 } else {
00141                                         h = mathutils::random(0.0f, houseMaxHeight);
00142                                 }
00143 
00144                                 // Make sure we have at least one unit for the dimensions.
00145                                 if (w < houseMinWidth) {
00146                                         w = houseMinWidth;
00147                                 }
00148                                 if (d < houseMinDepth) {
00149                                         d = houseMinDepth;
00150                                 }
00151                                 if (h < houseMinHeight) {
00152                                         h = houseMinHeight;
00153                                 }
00154                                 width = (float)(int)w;
00155                                 depth = (float)(int)d;
00156                                 height = (float)(int)h;
00157 
00158                                 // Get the max depth value of all houses in one row to calculate the
00159                                 // space to the next row of houses.
00160                                 if (depth > maxDepth) {
00161                                         maxDepth = depth;
00162                                 }
00163 
00164                                 // The space between the houses.
00165                                 // TODO: this can also be random?
00166                                 spaceX = 2.0f;
00167 
00168                                 // Add the half width of the last house + half width of the current house + space.
00169                                 positionX += (oldWidth / 2.0f + width / 2.0f + spaceX);
00170 
00171                                 // Calculate a random texture.
00172                                 textureIndex = (int)(mathutils::random(0.0f, (float)m_textures->size() - 1.0f));
00173 
00174                                 // Create the house.
00175                                 SingleTexturedMesh *roof = new SingleTexturedMesh();
00176                                 addMesh(createHouse(width, height, depth, Vector3f(positionX, 0.0f, positionZ),
00177                                         m_textures->at(textureIndex), roof));
00178                                 addMesh(roof);
00179 
00180                                 // Set oldwidth so that in the next iteration, the halfwidth of this house can be added to calculate
00181                                 // correct spaces between the houses.
00182                                 oldWidth = width;
00183                         }
00184                         // Reset the x position.
00185                         positionX = cityStartEdge.m_v[0];
00186 
00187                         // Reset old width.
00188                         oldWidth = 0.0f;
00189 
00190                         // TODO: some random value?
00191                         spaceZ = 3.0f;
00192 
00193                         // Add the depth of the "deepest" house of this row + space.
00194                         positionZ += (maxDepth + spaceZ);
00195                 }
00196         }
00197 
00198 
00199         //****************************************************************************
00200         //
00201         // Generate the ground.
00202         //
00203         //****************************************************************************
00204         void DynamicCity::createGround(Vector3f cityStartEdge, Vector3f cityEndEdge) {
00205                 SingleTexturedMesh *ground;
00206                 Vector3f topLeft;
00207                 Vector3f topRight;
00208                 Vector3f bottomRight;
00209                 Vector3f bottomLeft;
00210                 float texU;
00211                 float texV;
00212 
00213 
00214                 ground = new SingleTexturedMesh();
00215 
00216                 texU = (cityEndEdge.m_v[0] - cityStartEdge.m_v[0]) / 2.0f;
00217                 texV = (cityEndEdge.m_v[2] - cityStartEdge.m_v[2]) / 2.0f;
00218 
00219                 // Ground plane
00220                 topLeft = Vector3f(cityStartEdge);
00221                 topRight = Vector3f(cityEndEdge.m_v[0], cityStartEdge.m_v[1], cityStartEdge.m_v[2]);
00222                 bottomRight = Vector3f(cityEndEdge);
00223                 bottomLeft = Vector3f(cityStartEdge.m_v[0], cityStartEdge.m_v[1], cityEndEdge.m_v[2]);
00224 
00225                 ground->addTriangle(meshfactory::createTriangle(topLeft, bottomLeft, bottomRight,
00226                         Vector2f(0.0f, 0.0f), Vector2f(0.0f, texV), Vector2f(texU, texV)));
00227                 ground->addTriangle(meshfactory::createTriangle(topLeft, bottomRight, topRight,
00228                         Vector2f(0.0f, 0.0f), Vector2f(texU, texV), Vector2f(texU, 0.0f)));
00229 
00230                 ground->setTexture(m_groundTexture);
00231 
00232                 addMesh(ground);
00233         }
00234 
00235 
00236         //****************************************************************************
00237         //
00238         //
00239         //
00240         //****************************************************************************
00241         Mesh* DynamicCity::createHouse(float width, float height, float depth, Vector3f center, Texture *texture, SingleTexturedMesh *roof) {
00242                 SingleTexturedMesh *mesh;
00243                 Vector3f topLeft;
00244                 Vector3f topRight;
00245                 Vector3f bottomRight;
00246                 Vector3f bottomLeft;
00247                 float texU;
00248                 float texV;
00249                 float texUDepth;
00250 
00251 
00252                 mesh = new SingleTexturedMesh();
00253 
00254                 texU = width / 1.0f;
00255                 texV = height / 1.0f;
00256                 texUDepth = depth / 1.0f;
00257 
00258                 width /= 2.0f;
00259                 height /= 2.0f;
00260                 depth /= 2.0f;
00261 
00262                 // Front plane
00263                 topLeft = Vector3f(center.m_v[0] - width, center.m_v[1] + height, center.m_v[2] + depth);
00264                 topRight = Vector3f(center.m_v[0] + width, center.m_v[1] + height, center.m_v[2] + depth);
00265                 bottomRight = Vector3f(center.m_v[0] + width, center.m_v[1], center.m_v[2] + depth);
00266                 bottomLeft = Vector3f(center.m_v[0] - width, center.m_v[1], center.m_v[2] + depth);
00267 
00268                 mesh->addTriangle(meshfactory::createTriangle(topLeft, bottomLeft, bottomRight,
00269                         Vector2f(0.0f, 0.0f), Vector2f(0.0f, texV), Vector2f(texU, texV)));
00270                 mesh->addTriangle(meshfactory::createTriangle(topLeft, bottomRight, topRight,
00271                         Vector2f(0.0f, 0.0f), Vector2f(texU, texV), Vector2f(texU, 0.0f)));
00272 
00273                 // Back plane
00274                 topLeft = Vector3f(center.m_v[0] + width, center.m_v[1] + height, center.m_v[2] - depth);
00275                 topRight = Vector3f(center.m_v[0] - width, center.m_v[1] + height, center.m_v[2] - depth);
00276                 bottomRight = Vector3f(center.m_v[0] - width, center.m_v[1], center.m_v[2] - depth);
00277                 bottomLeft = Vector3f(center.m_v[0] + width, center.m_v[1], center.m_v[2] - depth);
00278 
00279                 mesh->addTriangle(meshfactory::createTriangle(topLeft, bottomLeft, bottomRight,
00280                         Vector2f(0.0f, 0.0f), Vector2f(0.0f, texV), Vector2f(texU, texV)));
00281                 mesh->addTriangle(meshfactory::createTriangle(topLeft, bottomRight, topRight,
00282                         Vector2f(0.0f, 0.0f), Vector2f(texU, texV), Vector2f(texU, 0.0f)));
00283 
00284                 // Left plane
00285                 topLeft = Vector3f(center.m_v[0] - width, center.m_v[1] + height, center.m_v[2] - depth);
00286                 topRight = Vector3f(center.m_v[0] - width, center.m_v[1] + height, center.m_v[2] + depth);
00287                 bottomRight = Vector3f(center.m_v[0] - width, center.m_v[1], center.m_v[2] + depth);
00288                 bottomLeft = Vector3f(center.m_v[0] - width, center.m_v[1], center.m_v[2] - depth);
00289 
00290                 mesh->addTriangle(meshfactory::createTriangle(topLeft, bottomLeft, bottomRight,
00291                         Vector2f(0.0f, 0.0f), Vector2f(0.0f, texV), Vector2f(texUDepth, texV)));
00292                 mesh->addTriangle(meshfactory::createTriangle(topLeft, bottomRight, topRight,
00293                         Vector2f(0.0f, 0.0f), Vector2f(texUDepth, texV), Vector2f(texUDepth, 0.0f)));
00294 
00295                 // Right plane
00296                 topLeft = Vector3f(center.m_v[0] + width, center.m_v[1] + height, center.m_v[2] + depth);
00297                 topRight = Vector3f(center.m_v[0] + width, center.m_v[1] + height, center.m_v[2] - depth);
00298                 bottomRight = Vector3f(center.m_v[0] + width, center.m_v[1], center.m_v[2] - depth);
00299                 bottomLeft = Vector3f(center.m_v[0] + width, center.m_v[1], center.m_v[2] + depth);
00300 
00301                 mesh->addTriangle(meshfactory::createTriangle(topLeft, bottomLeft, bottomRight,
00302                         Vector2f(0.0f, 0.0f), Vector2f(0.0f, texV), Vector2f(texUDepth, texV)));
00303                 mesh->addTriangle(meshfactory::createTriangle(topLeft, bottomRight, topRight,
00304                         Vector2f(0.0f, 0.0f), Vector2f(texUDepth, texV), Vector2f(texUDepth, 0.0f)));
00305 
00306                 // Top plane (roof)
00307                 topLeft = Vector3f(center.m_v[0] - width, center.m_v[1] + height, center.m_v[2] - depth);
00308                 topRight = Vector3f(center.m_v[0] + width, center.m_v[1] + height, center.m_v[2] - depth);
00309                 bottomRight = Vector3f(center.m_v[0] + width, center.m_v[1] + height, center.m_v[2] + depth);
00310                 bottomLeft = Vector3f(center.m_v[0] - width, center.m_v[1] + height, center.m_v[2] + depth);
00311 
00312                 if(roof != NULL) {
00313                         roof->addTriangle(meshfactory::createTriangle(topLeft, bottomLeft, bottomRight,
00314                                 Vector2f(0.0f, 0.0f), Vector2f(0.0f, texUDepth), Vector2f(texU, texUDepth)));
00315                         roof->addTriangle(meshfactory::createTriangle(topLeft, bottomRight, topRight,
00316                                 Vector2f(0.0f, 0.0f), Vector2f(texU, texUDepth), Vector2f(texU, 0.0f)));
00317                         roof->setTexture(m_roofTexture);
00318                 }
00319 
00320                 mesh->setTexture(texture);
00321 
00322                 return mesh;
00323         }
00324 };

Generated on Mon Oct 16 12:08:10 2006 for Phobosengine by doxygen 1.3.4