/* * Terrain.h * Jonathan Boldiga * 09/20/03 * * Description: The Terrain class is derived from Object, and represents * terrain in the world. Randomly generated terrain and frustrum clipping * are provided. * * The random terrain is created with the midpoint * displacement algorithm. * * Random terrain generation Copyright (C) Jason Shankel, 2000 */ #ifndef __TERRAIN_H #define __TERRAIN_H #define WIN32_LEAN_AND_MEAN #define WIN32_EXTRA_LEAN #include #include #include #include "Camera.h" #include "Object.h" #include "Texture.h" #include "Vector3.h" class Terrain : public Object{ private: // terrain is of size width X width preferrably with 2^n = width int width; float widthScale; // scale of terrain width float terrainMul; float heightMul; float scanDepth; float textureMul; float rangedRandom(float v1, float v2); void normalizeTerrain(float field[], int size); void filterHeightBand(float* band, int stride, int count, float filter); void filterHeightField(float field[], int size, float filter); void makeTerrainPlasma(float field[], int size, float rough); protected: // terrain doesn't move, so no physics animations void onAnimate(float deltaTime) {} void onDraw(Camera* camera); void onCollision(Object *collisionObject); public: float* heightMap; // dynamic heightmap Texture terrainTex[5]; // for multiple textures on the terrain float fogColor[4]; // color of the fog/sky Terrain(); Terrain(int width, float rFactor); ~Terrain(){ delete [] heightMap; } void load() {} void unload() {} void buildTerrain(int width, float rFactor); float getHeight(float x, float z){ float projCameraX, projCameraZ; // divide by the grid-spacing if it is not 1 projCameraX = x / terrainMul; projCameraZ = z / terrainMul; // compute the height field coordinates (Col0, Row0) // and (Col1, Row1) that identify the height field cell // directly below the camera. int col0 = int(projCameraX); int row0 = int(projCameraZ); int col1 = col0 + 1; int row1 = row0 + 1; // make sure that the cell coordinates don't fall // outside the height field. if (col1 > width) col1 = 0; if (row1 > width) row1 = 0; // get the four corner heights of the cell from the height field float h00 = heightMul * (float)heightMap[col0 + row0*width]; float h01 = heightMul * (float)heightMap[col1 + row0*width]; float h11 = heightMul * (float)heightMap[col1 + row1*width]; float h10 = heightMul * (float)heightMap[col0 + row1*width]; // calculate the position of the camera relative to the cell. // note, that 0 <= tx, ty <= 1. float tx = projCameraX - float(col0); float ty = projCameraZ - float(row0); // the next step is to perform a bilinear interpolation // to compute the height of the terrain directly below // the object. float txty = tx * ty; float finalHeight = h00 * (1.0f - ty - tx + txty) + h01 * (tx - txty) + h11 * txty + h10 * (ty - txty); return finalHeight; } }; #endif