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/Terrain.cpp

Go to the documentation of this file.
00001 
00002 
00003 #include "Terrain.h"
00004 
00005 
00006 #include "Image.h"
00007 #include "MathUtils.h"
00008 #include "SingleTexturedMesh.h"
00009 #include "Texture.h"
00010 #include "TextureDatabase.h"
00011 #include "Triangle.h"
00012 
00013 
00014 namespace pge {
00015 
00016 
00017         //****************************************************************************
00018         //
00019         //
00020         //
00021         //****************************************************************************
00022         HeightmapLoader::HeightmapLoader(const std::string &file) {
00023                 loadHeightmap(file);
00024         }
00025 
00026 
00027         //****************************************************************************
00028         //
00029         //
00030         //
00031         //****************************************************************************
00032         HeightmapLoader::~HeightmapLoader(void) {
00033         }
00034 
00035 
00036         //****************************************************************************
00037         //
00038         //
00039         //
00040         //****************************************************************************
00041         bool HeightmapLoader::loadHeightmap(const std::string &file) {
00042                 m_heightmap = new Image(file);
00043 
00044                 if(m_heightmap->getType() == Image::RGBA) {
00045                         printf("INFO: [%s] Heightmap type: RGBA\n", __FILE__);
00046                 }
00047 
00048                 return m_heightmap->isLoaded();
00049         }
00050 
00051 
00052         //****************************************************************************
00053         //
00054         //
00055         //
00056         //****************************************************************************
00057         Vector3f* HeightmapLoader::generateTerrain(Vector3f startCorner, float mapScale,
00058                 int vertexNumX, int vertexNumZ, float terrainWidth, float terrainDepth) {
00059 
00060                 int x;
00061                 int z;
00062                 float spaceX;
00063                 float spaceZ;
00064                 float dataY;
00065                 float y;
00066                 int mX;
00067                 int mZ;
00068                 Vector3f *vertices = new Vector3f[vertexNumX * vertexNumZ];
00069                 unsigned char *buffer;
00070                 int heightmapWidth = m_heightmap->getWidth();
00071                 int heightmapHeight = m_heightmap->getHeight();
00072                 int index;
00073 
00074 
00075                 spaceX = terrainWidth / vertexNumX;
00076                 spaceZ = terrainDepth / vertexNumZ;
00077 
00078                 buffer = m_heightmap->getImage();
00079 
00080                 index = 0;
00081 
00082                 for (z = 0; z < vertexNumZ; z++) {
00083                         for (x = 0; x < vertexNumX; x++) {
00084 
00085                                 mX = (int)mathutils::mapValueToInterval(0.0f, (float)vertexNumX, 0.0f, (float)heightmapWidth, (float)x);
00086                                 mZ = (int)mathutils::mapValueToInterval(0.0f, (float)vertexNumZ, 0.0f, (float)heightmapHeight, (float)z);
00087                 
00088                                 dataY = (float)buffer[((mZ * heightmapHeight) + mX) * 4];
00089 
00090                                 y = startCorner.m_v[1] + dataY * mapScale;
00091 
00092                                 vertices[index] = Vector3f(startCorner.m_v[0] + (x * spaceX), y, startCorner.m_v[2] + (z * spaceZ));
00093                                 index++;
00094                         }
00095                 }
00096                 return vertices;
00097         }
00098 
00099 
00100         //****************************************************************************
00101         //
00102         //
00103         //
00104         //****************************************************************************
00105         Terrain::Terrain(const std::string &heightmapFile, const std::string &textureFile,
00106                         Vector3f startCorner, float mapScale, int vertexNumX, int vertexNumZ,
00107                         float terrainWidth, float terrainDepth) {
00108 
00109                 HeightmapLoader *loader = new HeightmapLoader(heightmapFile);
00110 
00111                 // Load texture for terrain.
00112                 m_texture = TextureDatabase::getInstance()->addTexture(textureFile);
00113 
00114                 // Create the terrain.
00115                 createTerrain(loader->generateTerrain(startCorner, mapScale, vertexNumX, vertexNumZ,
00116                         terrainWidth, terrainDepth), vertexNumX, vertexNumZ);
00117 
00118                 // Build the bounding box here to enabled height queries.
00119                 buildBoundingBox();
00120         }
00121 
00122 
00123         //****************************************************************************
00124         //
00125         //
00126         //
00127         //****************************************************************************
00128         Terrain::~Terrain(void) {
00129         }
00130 
00131 
00132         //****************************************************************************
00133         //
00134         //
00135         //
00136         //****************************************************************************
00137         void Terrain::createTerrain(Vector3f *vertices, int vertexNumX, int vertexNumZ) {
00138                 int x;
00139                 int z;
00140                 int numTriangles;
00141                 float textureRepeatU = 20.0f;
00142                 float textureRepeatV = 20.0f;
00143                 float texPerCentU = textureRepeatU / (float) vertexNumX;
00144                 float texPerCentV = textureRepeatV / (float) vertexNumX;
00145                 SingleTexturedMesh *mesh = new SingleTexturedMesh();
00146 
00147 
00148                 mesh->setTexture(m_texture);
00149 
00150                 numTriangles = 0;
00151                 for(z = 0; z < vertexNumZ - 1; z++) {
00152                         for(x = 0; x < vertexNumX - 1; x++) {
00153 
00154                                 Vector3f v0 = vertices[(z * vertexNumX) + x];
00155                                 Vector3f v1 = vertices[((z + 1) * vertexNumX) + x];
00156                                 Vector3f v2 = vertices[(z * vertexNumX) + (x + 1)];
00157                                 Vector3f v3 = vertices[((z + 1) * vertexNumX) + (x + 1)];
00158 
00159                                 Triangle triangle0;
00160                                 Triangle triangle1;
00161 
00162                                 triangle0.m_vertices[0] = v0;
00163                                 triangle0.m_vertices[1] = v1;
00164                                 triangle0.m_vertices[2] = v2;
00165                                 triangle0.m_texCoords[0] = Vector2f(x * texPerCentU, z * texPerCentV);
00166                                 triangle0.m_texCoords[1] = Vector2f(x * texPerCentU, (z + 1) * texPerCentV);
00167                                 triangle0.m_texCoords[2] = Vector2f((x + 1) * texPerCentU, z * texPerCentV);
00168 
00169                                 triangle1.m_vertices[0] = v2;
00170                                 triangle1.m_vertices[1] = v1;
00171                                 triangle1.m_vertices[2] = v3;
00172                                 triangle1.m_texCoords[0] = Vector2f((x + 1) * texPerCentU, z * texPerCentV);
00173                                 triangle1.m_texCoords[1] = Vector2f(x * texPerCentU, (z + 1) * texPerCentV);
00174                                 triangle1.m_texCoords[2] = Vector2f((x + 1) * texPerCentU, (z + 1) * texPerCentV);
00175 
00176                                 // Planes.
00177                                 triangle0.m_plane = new Plane(v0, v1, v2);
00178                                 triangle1.m_plane = new Plane(v2, v1, v3);
00179 
00180                                 mesh->addTriangle(triangle0);
00181                                 mesh->addTriangle(triangle1);
00182                                 numTriangles += 2;
00183 
00184                                 if(numTriangles >= 1000000) {
00185                                         addMesh(mesh);
00186                                         mesh = NULL;
00187                                         mesh = new SingleTexturedMesh();
00188                                         mesh->setTexture(m_texture);
00189                                         numTriangles = 0;
00190                                 }
00191                         }
00192                 }
00193 
00194                 if(numTriangles > 0) {
00195                         addMesh(mesh);
00196                 }
00197         }
00198 };

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