void Terrain::UpdateVertices() { if( this->IsValid() ) { for( int y = 0; y <= this->_size.height; ++y ) { for( int x = 0; x <= this->_size.width; ++x ) { Vertex* vertex = this->_heightMatrix+x+y*(this->_size.width+1); vertex->Position().x = (float)x + (float)this->_offset.x; vertex->Position().z = -(float)y - (float)this->_offset.y; vertex->TextureCoords().u = (float)x / (float)this->_size.width; vertex->TextureCoords().v = (float)y / (float)this->_size.height; vertex->Normal().x = 0.0f; vertex->Normal().y = 1.0f; vertex->Normal().z = 0.0f; } } } }
Mesh::Mesh(const char* filename) :_vertices() ,_triangles() { fstream fileStream; fileStream.open(filename, fstream::in | iostream::binary); if( fileStream.is_open() ) { unsigned short chunkId; unsigned long chunkLength; unsigned short chunkQuantity; // Get file length fileStream.seekg(0, ios::end); int fileLength = fileStream.tellg(); fileStream.seekg(0, ios::beg); // Loop through chunk structure while( fileStream.tellg() < fileLength ) { fileStream.read((char*)&chunkId, 2); fileStream.read((char*)&chunkLength, 4); switch( chunkId ) { case 0x4d4d: // Main chunk break; case 0x3d3d: // 3D editor chunk break; case 0x4000: // Object block { char name[20]; // Read object name for( int count = 0; count < 20; ++count ) { fileStream.read(&name[count], 1); if( name[count] == '\0' ) { break; } } } break; case 0x4100: // Triangular mesh break; case 0x4110: // Vertices list fileStream.read((char*)&chunkQuantity, 2); for( unsigned short i = 0; i < chunkQuantity; ++i ) { Vertex* vertex = new Vertex(); if( vertex ) { Vector3f nativePos; this->_vertices.push_back(vertex); for( int j = 0; j < 3; ++j ) { fileStream.read((char*)(&nativePos[j]), 4); } // Convert from 3ds coordinates to opengl coordinates. vertex->SetPosition(nativePos.x, nativePos.z, -nativePos.y); } } break; case 0x4120: // Faces description fileStream.read((char*)&chunkQuantity, 2); for( unsigned short i = 0; i < chunkQuantity; ++i ) { Triangle* triangle = new Triangle(); if( triangle ) { this->_triangles.push_back(triangle); unsigned short vertIndex; for( int j = 0; j < 3; ++j ) { fileStream.read((char*)&vertIndex, 2); triangle->SetVertex(j, this->_vertices.at((unsigned int)vertIndex)); } fileStream.read((char*)&vertIndex, 2); // Extra data } } break; case 0x4140: // Mapping coordinates list fileStream.read((char*)&chunkQuantity, 2); for( unsigned short i = 0; i < chunkQuantity; ++i ) { Vertex* vertex = this->_vertices.at((unsigned int)i); if( vertex ) { for( int j = 0; j < 2; ++j ) { fileStream.read((char*)(&vertex->TextureCoords()[j]), 4); } } } break; default: // Skip chunk fileStream.seekg(chunkLength-6, ios_base::cur); } } fileStream.close(); this->CalculateVertexNormals(); this->Update(); } }