/// <summary> /// Default constructor /// </summary> public PlanetHomogenousProceduralTerrainTemplate( ) { // TerrainFunction heightFunction = new TerrainFunction( TerrainFunctionType.RidgedFractal ); // FractalTerrainParameters parameters = ( FractalTerrainParameters )heightFunction.Parameters; TerrainFunction heightFunction = new TerrainFunction( TerrainFunctionType.Flat ); m_HeightFunction = heightFunction; }
public TerrainPrimitive(GraphicsDevice device, TerrainFunction function) { heights = new float[100, 100]; for (int i = 0; i < 100; i++) { for (int e = 0; e < 100; e++) { heights[i, e] = function(i, e); } } Vector3[] neighbour = new Vector3[4]; for (int i = 0; i < 100; i++) { for (int e = 0; e < 100; e++) { Vector3 pos = new Vector3(i, heights[i, e], e); if (i > 0) { neighbour[0] = new Vector3(i - 1, heights[i - 1, e], e); } else { neighbour[0] = pos; } if (e > 0) { neighbour[1] = new Vector3(i, heights[i, e - 1], e - 1); } else { neighbour[1] = pos; } if (i < 99) { neighbour[2] = new Vector3(i + 1, heights[i + 1, e], e); } else { neighbour[2] = pos; } if (e < 99) { neighbour[3] = new Vector3(i, heights[i, e + 1], e + 1); } else { neighbour[3] = pos; } Vector3 normal = Vector3.Zero; normal += Vector3.Cross(neighbour[1] - pos, neighbour[0] - pos); normal += Vector3.Cross(neighbour[2] - pos, neighbour[1] - pos); normal += Vector3.Cross(neighbour[3] - pos, neighbour[2] - pos); normal += Vector3.Cross(neighbour[0] - pos, neighbour[3] - pos); normal.Normalize(); this.AddVertex(new Vector3(i, heights[i, e], e), normal); } } for (int i = 1; i < 100; i++) { for (int e = 1; e < 100; e++) { this.AddIndex((i - 1) * 100 + e); this.AddIndex(i * 100 + (e - 1)); this.AddIndex(i * 100 + e); this.AddIndex(i * 100 + (e - 1)); this.AddIndex((i - 1) * 100 + e); this.AddIndex((i - 1) * 100 + (e - 1)); } } this.InitializePrimitive(device); }
public TerrainPrimitive(GraphicsDevice device,TerrainFunction function) { heights = new float[100,100]; for (int i = 0; i < 100; i++) { for (int e = 0; e < 100; e++) { heights[i,e]=function(i,e); } } Vector3[] neighbour = new Vector3[4]; for (int i = 0; i < 100; i++) { for (int e = 0; e < 100; e++) { Vector3 pos = new Vector3(i, heights[i,e], e); if (i > 0) neighbour[0] = new Vector3(i - 1, heights[i - 1,e], e); else neighbour[0] = pos; if (e > 0) neighbour[1] = new Vector3(i, heights[i,e - 1], e - 1); else neighbour[1] = pos; if (i < 99) neighbour[2] = new Vector3(i +1, heights[i + 1,e], e); else neighbour[2] = pos; if (e < 99) neighbour[3] = new Vector3(i, heights[i,e+1], e+1); else neighbour[3] = pos; Vector3 normal = Vector3.Zero; normal += Vector3.Cross(neighbour[1] - pos, neighbour[0] - pos); normal += Vector3.Cross(neighbour[2] - pos, neighbour[1] - pos); normal += Vector3.Cross(neighbour[3] - pos, neighbour[2] - pos); normal += Vector3.Cross(neighbour[0] - pos, neighbour[3] - pos); normal.Normalize(); this.AddVertex(new Vector3(i, heights[i,e], e), normal); } } for (int i = 1; i < 100; i++) { for (int e = 1; e < 100; e++) { this.AddIndex((i - 1) * 100 + e); this.AddIndex(i * 100 + (e - 1)); this.AddIndex(i * 100 + e); this.AddIndex(i * 100 + (e - 1)); this.AddIndex((i - 1) * 100 + e); this.AddIndex((i - 1) * 100 + (e - 1)); } } this.InitializePrimitive(device); }
void UpdateTerrain() { mesh = new Mesh(); Vector3[] vertices = new Vector3[NofTiles * NofTiles * 4]; Color32[] colors = new Color32[NofTiles * NofTiles * 4]; int[] triangles = new int[NofTiles * NofTiles * 6]; TerrainParameter terrainParameter; terrainParameter.nofTiles = NofTiles; terrainParameter.nofPatches = NofPatches; terrainParameter.weight1 = weight1; terrainParameter.weight2 = weight2; terrainParameter.weight3 = weight3; terrainParameter.weight4 = weight4; terrainParameter.seaLevel = seaLevel; TerrainFunction terrainFunction = new TerrainFunction(); terrainFunction.Create(terrainParameter); float x0 = -(NofTiles * TileSize / 2f); float z0 = x0; float dx = TileSize; float dz = dx; float[,] vertexElevations = terrainFunction.VertexElevations; float z = z0; for (int v = 0; v < terrainParameter.nofTiles; ++v) { float x = x0; for (int u = 0; u < terrainParameter.nofTiles; ++u) { float y1 = vertexElevations [u, v] * maxHeight; float y2 = vertexElevations [u + 1, v] * maxHeight; float y3 = vertexElevations [u + 1, v + 1] * maxHeight; float y4 = vertexElevations [u, v + 1] * maxHeight; int vertexBaseAddress = NofTiles * v * 4; vertices [vertexBaseAddress + u * 4] = new Vector3(x, y1, z); // Bottom left (0) vertices [vertexBaseAddress + u * 4 + 1] = new Vector3(x + dx, y2, z); // Bottom right (1) vertices [vertexBaseAddress + u * 4 + 2] = new Vector3(x + dx, y3, z + dz); // Top right (2) vertices [vertexBaseAddress + u * 4 + 3] = new Vector3(x, y4, z + dz); // Top left (3) Color32 color = terrainFunction.TileColors [u, v]; colors [vertexBaseAddress + u * 4] = color; colors [vertexBaseAddress + u * 4 + 1] = color; colors [vertexBaseAddress + u * 4 + 2] = color; colors [vertexBaseAddress + u * 4 + 3] = color; int triangleBaseAddress = NofTiles * v * 6; // Lower left triangle triangles [triangleBaseAddress + u * 6] = vertexBaseAddress + u * 4; // (0) triangles [triangleBaseAddress + u * 6 + 1] = vertexBaseAddress + u * 4 + 2; // (2) triangles [triangleBaseAddress + u * 6 + 2] = vertexBaseAddress + u * 4 + 1; // (1) // Upper right triangle triangles [triangleBaseAddress + u * 6 + 3] = vertexBaseAddress + u * 4 + 2; // (2) triangles [triangleBaseAddress + u * 6 + 4] = vertexBaseAddress + u * 4; // (0) triangles [triangleBaseAddress + u * 6 + 5] = vertexBaseAddress + u * 4 + 3; // (3) x += dx; } // x z += dz; } // z mesh.vertices = vertices; mesh.triangles = triangles; mesh.colors32 = colors; // By setting a larger bound than geometrically required we prevent // the discarding of triangles out of the view frustum, specifically // when the player crosses the northern boundary of the map // @todo Fix bounds (calculate them) Bounds bounds = new Bounds(Vector2.zero, new Vector3(100, 200, 200)); mesh.bounds = bounds; mesh.RecalculateNormals(); }
/// <summary> /// Sets up the terrain functions /// </summary> /// <param name="heightFunction">The terrain height function</param> /// <param name="groundFunction">The terrain ground offset function</param> public void SetupTerrain( TerrainFunction heightFunction, TerrainFunction groundFunction ) { if ( Planet == null ) { throw new InvalidOperationException( "Terrain model does not have an associated planet. Cannot setup terrain" ); } float radius = SpherePlanet.PlanetModel.Radius.ToRenderUnits; float height = MaximumHeight.ToRenderUnits; // NOTE: AP: Patch scale is irrelevant, because vertices are projected onto the function sphere anyway m_Gen = new TerrainGenerator( TerrainGeometry.Sphere, heightFunction, groundFunction ); m_Gen.Setup( 1024, radius, radius + height ); m_Gen.SetSmallestStepSize( MinimumStepSize, MinimumStepSize ); OnModelChanged( false, true ); }
/// <summary> /// Sets up the terrain functions /// </summary> /// <param name="heightFunction">The terrain height function</param> /// <param name="groundFunction">The terrain ground offset function</param> public void SetupTerrain( TerrainFunction heightFunction, TerrainFunction groundFunction ) { if ( PlanetModel == null ) { throw new InvalidOperationException( "Terrain model does not have an associated planet. Cannot setup terrain" ); } float height = MaximumHeight.ToRenderUnits; m_Gen = new TerrainGenerator( TerrainGeometry.Plane, heightFunction, groundFunction ); m_Gen.Setup( 1024, 0, height ); m_Gen.SetSmallestStepSize( 0.001f, 0.001f ); OnModelChanged( ); }