//Generate a 3D model for the terrain private VertexPositionNormalColor[] TerrainModel(float[,] map) { VertexPositionNormalColor[] VList = new VertexPositionNormalColor[this.polycount * 3]; int index = 0; Vector3 p1, p2, p3; Vector3 normal; //Upper Triangles in Mesh for (int i = 0; i < this.size - 1; i++) { for (int j = 0; j < this.size - 1; j++) { p1 = new Vector3(i, map[i, j], j); p2 = new Vector3(i, map[i, j + 1], j + 1); p3 = new Vector3(i + 1, map[i + 1, j + 1], j + 1); normal = genNormal(p1, p2, p3); VList[index] = new VertexPositionNormalColor(p1, normal, getColor(map[i, j])); VList[index + 1] = new VertexPositionNormalColor(p2, normal, getColor(map[i, j + 1])); VList[index + 2] = new VertexPositionNormalColor(p3, normal, getColor(map[i + 1, j + 1])); index += 3; } } //Lower Triangles in Mesh for (int i = 1; i < this.size; i++) { for (int j = 1; j < this.size; j++) { p1 = new Vector3(i, map[i, j], j); p2 = new Vector3(i, map[i, j - 1], j - 1); p3 = new Vector3(i - 1, map[i - 1, j - 1], j - 1); normal = genNormal(p1, p2, p3); VList[index] = new VertexPositionNormalColor(p1, normal, getColor(map[i, j])); VList[index + 1] = new VertexPositionNormalColor(p2, normal, getColor(map[i, j - 1])); VList[index + 2] = new VertexPositionNormalColor(p3, normal, getColor(map[i - 1, j - 1])); index += 3; } } return(VList); }
public void addPolygon(Vector3 a, Vector3 b, Vector3 c) { Color[] col = new Color[3]; Vector3[] pos = new[] { a, b, c }; // Calc the surface normal Vector3 A, B, normal; A = b - a; B = c - a; normal = Vector3.Cross(A, B); normal.Normalize(); for (int i = 0; i < 3; i++) { if (pos[i].Y > this.snow) { col[i] = Color.White; } else if (pos[i].Y > this.rock) { col[i] = Color.LightGray; } else if (pos[i].Y > this.water) { col[i] = Color.Green; } else { col[i] = Color.BlanchedAlmond; } vertexArray[vertexCount + i] = new VertexPositionNormalColor(pos[i], normal, col[i]); } vertexCount += 3; }
public Landscape(Project1Game game) { this.game = game; // Create the height map and vertex norms heightMap = createRandomMap(); vertexNorms = calcNorms(); // Set the array to hold all the vertices VertexPositionNormalColor[] pointList = new VertexPositionNormalColor[6 * (LENGTH - 1) * (LENGTH - 1) + 6]; int counter = 0; for (int x = 0; x < LENGTH - 1; x++) { for (int y = 1; y < LENGTH; y++) { // Taking a point (x,y) from the height map it draws the square with the corners (x,y) (x+1,y) (x+1,y+1) and (x+1,y) Vector3 pointA = new Vector3(x, heightMap[x, y - 1], y - 1); pointList[counter] = new VertexPositionNormalColor(pointA, vertexNorms[x, y - 1], chooseColor(heightMap[x, y - 1])); counter++; Vector3 pointB = new Vector3(x, heightMap[x, y], y); pointList[counter] = new VertexPositionNormalColor(pointB, vertexNorms[x, y], chooseColor(heightMap[x, y])); counter++; Vector3 pointC = new Vector3(x + 1, heightMap[x + 1, y], y); pointList[counter] = new VertexPositionNormalColor(pointC, vertexNorms[x + 1, y], chooseColor(heightMap[x + 1, y])); counter++; Vector3 pointD = new Vector3(x, heightMap[x, y - 1], y - 1); pointList[counter] = new VertexPositionNormalColor(pointD, vertexNorms[x, y - 1], chooseColor(heightMap[x, y - 1])); counter++; Vector3 pointE = new Vector3(x + 1, heightMap[x + 1, y], y); pointList[counter] = new VertexPositionNormalColor(pointE, vertexNorms[x + 1, y], chooseColor(heightMap[x + 1, y])); counter++; Vector3 pointF = new Vector3(x + 1, heightMap[x + 1, y - 1], y - 1); pointList[counter] = new VertexPositionNormalColor(pointF, vertexNorms[x + 1, y - 1], chooseColor(heightMap[x + 1, y - 1])); counter++; } } // Adds a plane of water which we will make sea level eg. y=0 Color water = new Color(new Vector3(0, 0, 50), TRANSPARENCY); Vector3 wpointA = new Vector3(-0.1f, -0.1f, -0.1f); pointList[counter] = new VertexPositionNormalColor(wpointA, Vector3.Down, water); counter++; Vector3 wpointB = new Vector3(-0.1f, -0.1f, LENGTH - 0.9f); pointList[counter] = new VertexPositionNormalColor(wpointB, Vector3.Down, water); counter++; Vector3 wpointC = new Vector3(LENGTH - 0.9f, -0.1f, LENGTH - 0.9f); pointList[counter] = new VertexPositionNormalColor(wpointC, Vector3.Down, water); counter++; Vector3 wpointD = new Vector3(-0.1f, -0.1f, -0.1f); pointList[counter] = new VertexPositionNormalColor(wpointD, Vector3.Down, water); counter++; Vector3 wpointE = new Vector3(LENGTH - 0.9f, -0.1f, LENGTH - 0.9f); pointList[counter] = new VertexPositionNormalColor(wpointE, Vector3.Down, water); counter++; Vector3 wpointF = new Vector3(LENGTH - 0.9f, -0.1f, -0.1f); pointList[counter] = new VertexPositionNormalColor(wpointF, Vector3.Down, water); counter++; // Add the vertices to the landscape vertices = Buffer.Vertex.New(game.GraphicsDevice, pointList); // Set the lighting of the landscape basicEffect = new BasicEffect(game.GraphicsDevice) { View = game.camera.View, Projection = game.camera.Projection, VertexColorEnabled = true, World = Matrix.Identity, LightingEnabled = true, AmbientLightColor = new Vector3(0.1f, 0.1f, 0.1f), }; basicEffect.DirectionalLight0.Enabled = true; basicEffect.DirectionalLight0.Direction = Vector3.Right; basicEffect.DirectionalLight0.DiffuseColor = new Vector3(0.1f, 0.1f, 0.1f); basicEffect.DirectionalLight0.SpecularColor = new Vector3(1.0f, 1.0f, 1.0f); inputLayout = VertexInputLayout.FromBuffer(0, vertices); }
public Landscape(Project1Game game, float c1, float c2, float c3, float c4, int recDepth) { // setting up the random number generator this.rand = new Random(); // recDepth of 0 would make a flat plane with only the 4 corner vertices // Determine the size of the array depending of the recursion depth this.arraySize = this.compArraySize(recDepth); this.recDepth = recDepth; // Creating array structure in order to store height values for all vertices // format will be heightMap[x][y] = z heightMap = new float[arraySize][]; for (int i = 0; i < arraySize; i++) { heightMap[i] = new float[arraySize]; } // corner pattern: // C1-----C2 // | | // C3-----C4 // set the four corner values heightMap[0][0] = c1; heightMap[arraySize - 1][0] = c2; heightMap[0][arraySize - 1] = c3; heightMap[arraySize - 1][arraySize - 1] = c4; // Generate the rest of the height values diamondsquare(); // Calculate vertex colour heights calcColourZones(); vertexArray = new VertexPositionNormalColor[(arraySize - 1) * (6 + (arraySize - 2) * 6) + 6]; vertexCount = 0; // Add the vertices to the array to make polygons for (int y = 0; y <= arraySize - 2; y++) { for (int x = 0; x <= arraySize - 1; x++) { if (x == 0) { addPolygon( new Vector3(x * positionScale, heightMap[x][y], y * positionScale), new Vector3(x * positionScale, heightMap[x][y + 1], (y + 1) * positionScale), new Vector3((x + 1) * positionScale, heightMap[x + 1][y], y * positionScale) ); } else if (x == arraySize - 1) { addPolygon( new Vector3(x * positionScale, heightMap[x][y], y * positionScale), new Vector3((x - 1) * positionScale, heightMap[x - 1][y + 1], (y + 1) * positionScale), new Vector3(x * positionScale, heightMap[x][y + 1], (y + 1) * positionScale) ); } else { addPolygon( new Vector3(x * positionScale, heightMap[x][y], y * positionScale), new Vector3(x * positionScale, heightMap[x][y + 1], (y + 1) * positionScale), new Vector3((x + 1) * positionScale, heightMap[x + 1][y], y * positionScale) ); addPolygon( new Vector3(x * positionScale, heightMap[x][y], y * positionScale), new Vector3((x - 1) * positionScale, heightMap[x - 1][y + 1], (y + 1) * positionScale), new Vector3(x * positionScale, heightMap[x][y + 1], (y + 1) * positionScale) ); } } } // these vertices are for the water // TODO add water vertices Color water = new Color(new Vector4(0, 0, 255, 0.5f)); vertexArray[vertexCount++] = new VertexPositionNormalColor(new Vector3(0, this.water, 0), Vector3.UnitY, water); vertexArray[vertexCount++] = new VertexPositionNormalColor(new Vector3(0, this.water, arraySize * positionScale), Vector3.UnitY, water); vertexArray[vertexCount++] = new VertexPositionNormalColor(new Vector3(arraySize * positionScale, this.water, arraySize * positionScale), Vector3.UnitY, water); vertexArray[vertexCount++] = new VertexPositionNormalColor(new Vector3(0, this.water, 0), Vector3.UnitY, water); vertexArray[vertexCount++] = new VertexPositionNormalColor(new Vector3(arraySize * positionScale, this.water, arraySize * positionScale), Vector3.UnitY, water); vertexArray[vertexCount++] = new VertexPositionNormalColor(new Vector3(arraySize * positionScale, this.water, 0), Vector3.UnitY, water); vertices = Buffer.Vertex.New( game.GraphicsDevice, vertexArray ); basicEffect = new BasicEffect(game.GraphicsDevice) { VertexColorEnabled = true, Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4.0f, (float)game.GraphicsDevice.BackBuffer.Width / game.GraphicsDevice.BackBuffer.Height, 0.1f, 10000.0f), World = Matrix.Identity, LightingEnabled = true }; basicEffect.DirectionalLight0.Enabled = true; basicEffect.DirectionalLight0.Direction = new Vector3((float)Math.Cos(0), (float)Math.Sin(0), (float)Math.Cos(0)); basicEffect.DirectionalLight0.DiffuseColor = new Vector3(0.3f, 0.3f, 0.3f); basicEffect.AmbientLightColor = new Vector3(0.1f, 0.1f, 0.1f); basicEffect.EmissiveColor = new Vector3(0.5f, 0.5f, 0.5f); basicEffect.SpecularColor = new Vector3(0.3f, 0.5f, 0.5f); basicEffect.SpecularPower = 1f; inputLayout = VertexInputLayout.FromBuffer(0, vertices); this.game = game; }
public Landscape(Game game) { Terrain = new HeightMap(10); terrain3D = new VertexPositionNormalColor[Terrain.max * Terrain.max * 6 + 12]; int index = 0; for (int z = 0; z < Terrain.max; z++) { for (int x = 0; x < Terrain.max; x++) { // Front left. terrain3D[index] = new VertexPositionNormalColor(new Vector3(x, Terrain.get(x, z), z), Terrain.getVertexNormal(x, z), Terrain.getColor(x, z)); index++; // Back left. terrain3D[index] = new VertexPositionNormalColor(new Vector3(x, Terrain.get(x, z + 1), z + 1), Terrain.getVertexNormal(x, z + 1), Terrain.getColor(x, z + 1)); index++; // Back right. terrain3D[index] = new VertexPositionNormalColor(new Vector3(x + 1, Terrain.get(x + 1, z + 1), z + 1), Terrain.getVertexNormal(x + 1, z + 1), Terrain.getColor(x + 1, z + 1)); index++; // Front left. terrain3D[index] = new VertexPositionNormalColor(new Vector3(x, Terrain.get(x, z), z), Terrain.getVertexNormal(x, z), Terrain.getColor(x, z)); index++; // Back right. terrain3D[index] = new VertexPositionNormalColor(new Vector3(x + 1, Terrain.get(x + 1, z + 1), z + 1), Terrain.getVertexNormal(x + 1, z + 1), Terrain.getColor(x + 1, z + 1)); index++; // Front right. terrain3D[index] = new VertexPositionNormalColor(new Vector3(x + 1, Terrain.get(x + 1, z), z), Terrain.getVertexNormal(x + 1, z), Terrain.getColor(x + 1, z)); index++; } } Color blue = Color.MidnightBlue; blue.A = 0xC0; waterHeight = 0.695f * Terrain.maxHeight; //Set Water Polygons // Front left. terrain3D[index] = new VertexPositionNormalColor(new Vector3(0.0f, waterHeight, 0.0f), new Vector3(0.0f, 1.0f, 0.0f), blue); index++; // Back left. terrain3D[index] = new VertexPositionNormalColor(new Vector3(0.0f, waterHeight, Terrain.max), new Vector3(0.0f, 1.0f, 0.0f), blue); index++; // Back right. terrain3D[index] = new VertexPositionNormalColor(new Vector3(Terrain.max, waterHeight, Terrain.max), new Vector3(0.0f, 1.0f, 0.0f), blue); index++; // Front left. terrain3D[index] = new VertexPositionNormalColor(new Vector3(0.0f, waterHeight, 0.0f), new Vector3(0.0f, 1.0f, 0.0f), blue); index++; // Back right. terrain3D[index] = new VertexPositionNormalColor(new Vector3(Terrain.max, waterHeight, Terrain.max), new Vector3(0.0f, 1.0f, 0.0f), blue); index++; // Front right. terrain3D[index] = new VertexPositionNormalColor(new Vector3(Terrain.max, waterHeight, 0.0f), new Vector3(0.0f, 1.0f, 0.0f), blue); index++; //water from the bottom // Front left. terrain3D[index] = new VertexPositionNormalColor(new Vector3(0.0f, waterHeight, 0.0f), new Vector3(0.0f, 1.0f, 0.0f), blue); index++; // Back right. terrain3D[index] = new VertexPositionNormalColor(new Vector3(Terrain.max, waterHeight, Terrain.max), new Vector3(0.0f, 1.0f, 0.0f), blue); index++; // Back left. terrain3D[index] = new VertexPositionNormalColor(new Vector3(0.0f, waterHeight, Terrain.max), new Vector3(0.0f, 1.0f, 0.0f), blue); index++; // Front left. terrain3D[index] = new VertexPositionNormalColor(new Vector3(0.0f, waterHeight, 0.0f), new Vector3(0.0f, 1.0f, 0.0f), blue); index++; // Front right. terrain3D[index] = new VertexPositionNormalColor(new Vector3(Terrain.max, waterHeight, 0.0f), new Vector3(0.0f, 1.0f, 0.0f), blue); index++; // Back right. terrain3D[index] = new VertexPositionNormalColor(new Vector3(Terrain.max, waterHeight, Terrain.max), new Vector3(0.0f, 1.0f, 0.0f), blue); index++; //initialized here because I wanted the terrain details to place the initial position/target. currentPosition = new Vector3(0.0f, Terrain.maxHeight, 0.0f); //start on corner of map at highest point of terrain currentTarget = new Vector3(Terrain.max, Terrain.maxHeight, Terrain.max); //looking across to other corner (same height) currentUp = Vector3.UnitY; prevMouseX = 0.5f; prevMouseY = 0.5f; vertices = Buffer.Vertex.New(game.GraphicsDevice, terrain3D); basicEffect = new BasicEffect(game.GraphicsDevice) { VertexColorEnabled = true, View = Matrix.LookAtLH(currentPosition, currentTarget, currentUp), Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4.0f, (float)game.GraphicsDevice.BackBuffer.Width / game.GraphicsDevice.BackBuffer.Height, -10.0f, (float)Terrain.size * 2), World = Matrix.Identity, LightingEnabled = true }; inputLayout = VertexInputLayout.FromBuffer(0, vertices); basicEffect.EnableDefaultLighting(); basicEffect.AmbientLightColor = new Vector3(.1f * 255 / 255, .1f * 244 / 255, .1f * 229 / 255); this.game = game; }