public TerrainChunk(GraphicsDevice graphicsDevice, HeightProvider heightProvider, Vector2 gridCoordinates, NoiseProvider decorNoiseProvider) { _gridTriangles = new List <GridTriangle>(); GridCoordinates = gridCoordinates; CalculateContents(graphicsDevice, heightProvider, decorNoiseProvider); }
public World(GraphicsDevice graphicsDevice, HeightProvider heightProvider, DirectionLight light, NoiseProvider decorNoiseProvider) { _graphicsDevice = graphicsDevice; _heightProvider = heightProvider; _decorNoiseProvider = decorNoiseProvider; _newTerrainChunks = new List <TerrainChunk>(); TerrainChunks = new List <TerrainChunk>(); Light = light; }
private void CalculateContents(GraphicsDevice graphicsDevice, HeightProvider heightProvider, NoiseProvider decorNoiseProvider) { float centreXWorld = GridCoordinates.X * EdgeLength; float centreZWorld = GridCoordinates.Y * EdgeLength; Vector3 min = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue); Vector3 max = new Vector3(float.MinValue, float.MinValue, float.MinValue); List <TerrainVertex> resultVertices = new List <TerrainVertex>(); for (int z = 0; z < VerticesPerEdge; z++) { for (int x = 0; x < VerticesPerEdge; x++) { float positionXLocal = x * VertexSpacing - HalfEdgeLength; float positionZLocal = z * VertexSpacing - HalfEdgeLength; float positionXWorld = positionXLocal + centreXWorld; float positionZWorld = positionZLocal + centreZWorld; Vector3 position = new Vector3(positionXWorld, heightProvider.GetHeight(positionXWorld, positionZWorld), positionZWorld); Vector3 normal = heightProvider.GetNormalFromFiniteOffset(positionXWorld, positionZWorld); Vector2 textureCoordinates = new Vector2(positionXLocal, positionZLocal) / HalfEdgeLength; Vector2 textureCoordinatesDetail = new Vector2(positionXLocal, positionZLocal) * 2 / HalfEdgeLength; TerrainVertex vertex = new TerrainVertex(position, normal, textureCoordinates, textureCoordinatesDetail); resultVertices.Add(vertex); min = Vector3.Min(min, position); max = Vector3.Max(max, position); } } TerrainVertex[] resultVerticesData = resultVertices.ToArray(); VertexBuffer = new VertexBuffer(graphicsDevice, TerrainVertex.VertexDeclaration, resultVerticesData.Length, BufferUsage.WriteOnly); VertexBuffer.SetData(resultVerticesData); // Populate grid triangles _gridTriangles.Clear(); for (int z = 0; z < VerticesPerEdge - 1; z++) { for (int x = 0; x < VerticesPerEdge - 1; x++) { int baseIndexPosition = (x + z * (VerticesPerEdge - 1)) * 6; _gridTriangles.Add(new GridTriangle(resultVerticesData[Indices[baseIndexPosition]].Position, resultVerticesData[Indices[baseIndexPosition + 1]].Position, resultVerticesData[Indices[baseIndexPosition + 2]].Position)); _gridTriangles.Add(new GridTriangle(resultVerticesData[Indices[baseIndexPosition + 3]].Position, resultVerticesData[Indices[baseIndexPosition + 4]].Position, resultVerticesData[Indices[baseIndexPosition + 5]].Position)); } } // Include water tile vertices in bounding box for (int z = -1; z <= 1; z += 2) { for (int x = -1; x <= 1; x += 2) { Vector3 waterTileVertexPosition = new Vector3(centreXWorld + x * HalfEdgeLength, 0, centreZWorld + z * HalfEdgeLength); min = Vector3.Min(min, waterTileVertexPosition); max = Vector3.Max(max, waterTileVertexPosition); } } BoundingBox = new BoundingBox(min, max); // Fill decor according to procedural inputs _decorRandom = new Random(GridCoordinates.GetHashCode()); DecorItems = new List <DecorItem>(); for (int z = 0; z < DecorGridSize; z++) { for (int x = 0; x < DecorGridSize; x++) { float decorCentreXWorld = centreXWorld - HalfEdgeLength + HalfDecorTileEdgeLength + x * DecorTileEdgeLength + (float)(2 * _decorRandom.NextDouble() - 1) * HalfDecorTileEdgeLength; float decorCentreZWorld = centreZWorld - HalfEdgeLength + HalfDecorTileEdgeLength + z * DecorTileEdgeLength + (float)(2 * _decorRandom.NextDouble() - 1) * HalfDecorTileEdgeLength; float?decorHeight = GetGridHeight(new Vector3(decorCentreXWorld, 0, decorCentreZWorld)); if (decorHeight.HasValue && decorHeight.Value > 5) { if (decorNoiseProvider.GetValue(decorCentreXWorld, decorCentreZWorld) > 0.9f) { DecorItems.Add(new DecorItem(new Vector3(decorCentreXWorld, decorHeight.Value, decorCentreZWorld), (float)(_decorRandom.NextDouble() * 2 * Math.PI))); } } } } }