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
00065 createCity();
00066
00067 buildBoundingBox();
00068
00069 box = getBoundingBox();
00070
00071
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
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
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
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
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
00159
00160 if (depth > maxDepth) {
00161 maxDepth = depth;
00162 }
00163
00164
00165
00166 spaceX = 2.0f;
00167
00168
00169 positionX += (oldWidth / 2.0f + width / 2.0f + spaceX);
00170
00171
00172 textureIndex = (int)(mathutils::random(0.0f, (float)m_textures->size() - 1.0f));
00173
00174
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
00181
00182 oldWidth = width;
00183 }
00184
00185 positionX = cityStartEdge.m_v[0];
00186
00187
00188 oldWidth = 0.0f;
00189
00190
00191 spaceZ = 3.0f;
00192
00193
00194 positionZ += (maxDepth + spaceZ);
00195 }
00196 }
00197
00198
00199
00200
00201
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
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
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
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
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
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
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 };