public static GridElevations GetVertexHeights(Vector3 position, int seed) { int v0 = GetTerrainHeightFromPerlin(position + GridMetrics.GetEdge(GridDirection.SW), seed); int v1 = GetTerrainHeightFromPerlin(position + GridMetrics.GetEdge(GridDirection.NW), seed); int v2 = GetTerrainHeightFromPerlin(position + GridMetrics.GetEdge(GridDirection.NE), seed); int v3 = GetTerrainHeightFromPerlin(position + GridMetrics.GetEdge(GridDirection.SE), seed); return(new GridElevations(v0, v1, v2, v3)); }
public static GridElevations GetVertexHeightsFromHeightmap(Vector3 position, Texture2D heightmap) { int v0 = GetTerrainHeightFromMap(position + GridMetrics.GetEdge(GridDirection.SW), heightmap); int v1 = GetTerrainHeightFromMap(position + GridMetrics.GetEdge(GridDirection.NW), heightmap); int v2 = GetTerrainHeightFromMap(position + GridMetrics.GetEdge(GridDirection.NE), heightmap); int v3 = GetTerrainHeightFromMap(position + GridMetrics.GetEdge(GridDirection.SE), heightmap); return(new GridElevations(v0, v1, v2, v3)); }
void OnEnable() { if (!GridMetrics.noiseSource) { GridMetrics.noiseSource = noiseSource; GridMetrics.InitializeHashGrid(seed); GridMetrics.colors = colors; } }
void MakeCornerBridge(GridMesh mesh, Vector3 v0, GridDirection bridgeDirection) { Vector3 b0 = GridMetrics.GetBridge(bridgeDirection.Previous()); Vector3 b1 = GridMetrics.GetBridge(bridgeDirection.Next()); mesh.AddQuad(v0, v0 + b0, v0 + b0 + b1, v0 + b1); if (mesh.useUVCoordinates) { mesh.AddQuadUV(0f, 0f, 0f, 1f); } }
void Awake() { GridMetrics.noiseSource = noiseSource; GridMetrics.InitializeHashGrid(seed); GridMetrics.colors = colors; cellCountX = chunkCountX * GridMetrics.chunkSizeX; cellCountZ = chunkCountZ * GridMetrics.chunkSizeZ; CreateChunks(); CreateCells(); }
void MakeBridge(GridMesh mesh, Vector3 v0, Vector3 v1, GridDirection bridgeDirection) { Vector3 bridge = GridMetrics.GetBridge(bridgeDirection); Vector3 e0 = v0 + bridge; Vector3 e1 = v1 + bridge; mesh.AddQuad(v0, e0, e1, v1); if (mesh.useUVCoordinates) { mesh.AddQuadUV(0f, 0f, 0f, 1f); } }
private void Awake() { gridMaterials = GameObject.Find("EditorCanvas").GetComponent <MapEditor>().materials; cellCountX = chunkCountX * GridMetrics.chunkSizeX; cellCountZ = chunkCountZ * GridMetrics.chunkSizeZ; GridMetrics.InitializeHashGrid(seed); chunkCuller = new CullingGroup(); chunkCuller.SetBoundingDistances(new float[] { distanceBand1, distanceBand2, distanceBand3 }); chunkCuller.onStateChanged = StateChangedMethod; CreateChunks(); CreateCells(); }
void MoveEditorPointer(SquareCell cell, GridDirection vertex) { if (activeMode == EditMode.color || activeMode == EditMode.rivers || activeMode == EditMode.roads || activeMode == EditMode.water_level || activeMode == EditMode.building || activeMode == EditMode.trees || activeMode == EditMode.rocks || activeMode == EditMode.mast || activeMode == EditMode.lighthouse || activeMode == EditMode.industry || activeMode == EditMode.town) { pointerLocation = GridCoordinates.ToPosition(cell.coordinates) + Vector3.up * cell.CentreElevation * GridMetrics.elevationStep; } if (activeMode == EditMode.elevation) { pointerLocation = GridCoordinates.ToPosition(cell.coordinates) + GridMetrics.GetEdge(vertex) + Vector3.up * (int)cell.GridElevations[vertex] * GridMetrics.elevationStep; } }
void AddWaterForSquare(SquareCell cell, Vector3 centre) { centre.y = cell.WaterSurfaceY; Vector3 c0 = centre + GridMetrics.GetEdge(GridDirection.SW); Vector3 c1 = centre + GridMetrics.GetEdge(GridDirection.NW); Vector3 c2 = centre + GridMetrics.GetEdge(GridDirection.NE); Vector3 c3 = centre + GridMetrics.GetEdge(GridDirection.SE); if (cell.IsFullyUnderwater) { water.AddQuad(c0, c1, c2, c3); } else if (cell.IsPartUnderwater) { float v0 = 0f, v1 = 0f, v2 = 0f, v3 = 0f; if (cell.GetNeighbor(GridDirection.N) && !cell.GetNeighbor(GridDirection.N).IsUnderwater) { v1 = 1f; v2 = 1f; } if (cell.GetNeighbor(GridDirection.NE) && !cell.GetNeighbor(GridDirection.NE).IsUnderwater) { v2 = 1f; } if (cell.GetNeighbor(GridDirection.E) && !cell.GetNeighbor(GridDirection.E).IsUnderwater) { v2 = 1f; v3 = 1f; } if (cell.GetNeighbor(GridDirection.SE) && !cell.GetNeighbor(GridDirection.SE).IsUnderwater) { v3 = 1f; } if (cell.GetNeighbor(GridDirection.S) && !cell.GetNeighbor(GridDirection.S).IsUnderwater) { v3 = 1f; v0 = 1f; } if (cell.GetNeighbor(GridDirection.SW) && !cell.GetNeighbor(GridDirection.SW).IsUnderwater) { v0 = 1f; } if (cell.GetNeighbor(GridDirection.W) && !cell.GetNeighbor(GridDirection.W).IsUnderwater) { v0 = 1f; v1 = 1f; } if (cell.GetNeighbor(GridDirection.NW) && !cell.GetNeighbor(GridDirection.NW).IsUnderwater) { v1 = 1f; } waterShore.AddQuad(c0, c1, c2, c3); waterShore.AddQuadV(v0, v1, v2, v3); } }
void CreateChunks() { chunks = new GridChunk[chunkCountX * chunkCountZ]; for (int z = 0, i = 0; z < chunkCountZ; z++) { for (int x = 0; x < chunkCountX; x++) { GridChunk chunk = chunks[i++] = Instantiate(chunkPrefab); chunk.transform.SetParent(transform); chunk.transform.position = new Vector3(x * GridMetrics.chunkSizeX, 0, z * GridMetrics.chunkSizeZ); chunk.chunkTypes = GridMetrics.GenerateChunkType(); } } }
void AddCliffEdge(SquareCell cell, GridDirection direction) { GridDirection prev = direction.Previous(); GridDirection next = direction.Next(); GridDirection prevN = prev.Previous2(); GridDirection nextN = next.Next2(); SquareCell neighbor = cell.GetNeighbor(direction); if (neighbor != null) { Vector3 c0 = new Vector3(cell.coordinates.X, 0, cell.coordinates.Z) + GridMetrics.GetEdge(prev) + Vector3.up * (int)cell.GridElevations[prev] * GridMetrics.elevationStep; Vector3 c1 = new Vector3(cell.coordinates.X, 0, cell.coordinates.Z) + GridMetrics.GetEdge(next) + Vector3.up * (int)cell.GridElevations[next] * GridMetrics.elevationStep; Vector3 n0 = new Vector3(neighbor.coordinates.X, 0, neighbor.coordinates.Z) + GridMetrics.GetEdge(prevN) + Vector3.up * (int)neighbor.GridElevations[prevN] * GridMetrics.elevationStep; Vector3 n1 = new Vector3(neighbor.coordinates.X, 0, neighbor.coordinates.Z) + GridMetrics.GetEdge(nextN) + Vector3.up * (int)neighbor.GridElevations[nextN] * GridMetrics.elevationStep; if (c0 != n0 && c1 != n1) { if (c0.y > n0.y && n1.y > c1.y) // if edges cross heights along edge X { Vector2 cross = CrossingPoint(c1.y - c0.y, n1.y - n0.y, c0.y, n0.y); Vector3 worldCross = new Vector3(cell.coordinates.X, 0, cell.coordinates.Z) + GridMetrics.GetEdge(direction.Previous()) + (cross.x * 2 * GridMetrics.GetEdge(direction.Next2())) + new Vector3(0, cross.y, 0); terrain.AddTriangle(worldCross, c0, n0); terrain.AddTriangleColor(Color.cyan); terrain.AddTriangle(worldCross, n1, c1); terrain.AddTriangleColor(Color.green); } else if (c0.y > n0.y && c1.y > n1.y) // if one edge is always above the other { terrain.AddQuad(c0, n0, n1, c1); terrain.AddQuadColor(retainingWallColor); } } else if (c0.y > n0.y) { terrain.AddTriangle(c0, n0, c1); terrain.AddTriangleColor(retainingWallColor); } else if (c1.y > n1.y) { terrain.AddTriangle(c0, n1, c1); terrain.AddTriangleColor(retainingWallColor); } } }
public void AddFeature(SquareCell cell, Vector3 position) { GridHash hash = GridMetrics.SampleHashGrid(position); if (cell.UrbanLevel != 0 && cell.BuildingOnSquare == null) { int buildingIndex = Random.Range(0, townBuildings.Length); cell.BuildingOnSquare = Instantiate(townBuildings[buildingIndex]); cell.BuildingOnSquare.Construct(cell, position, hash); cell.BuildingOnSquare.BuildingModel.SetParent(containerNoDestroy, false); } else if (cell.Industry != 0 && cell.BuildingOnSquare == null) { cell.BuildingOnSquare = Instantiate(industryBuildings[cell.Industry - 1]); cell.BuildingOnSquare.Construct(cell, position, hash); cell.BuildingOnSquare.BuildingModel.SetParent(containerNoDestroy, false); } else if (cell.FarmLevel != 0) { } else if (cell.PlantLevel != 0) { for (int i = 0; i < cell.PlantLevel; i++) { float selectFeature = Mathf.Clamp(Mathf.PerlinNoise((position.x + i / 6f) * 100, (position.z + i / 6f) * 100), 0f, 1f); int randomFeature = (int)Mathf.Floor((treePrefabs[0].Length - 1) * selectFeature); Transform instance = Instantiate(treePrefabs[0][randomFeature]); instance.localPosition = position + (Quaternion.Euler(0, i / (float)cell.PlantLevel * 360f, 0) * new Vector3(hash.a * 0.3f + 0.2f, 0, 0)); instance.localRotation = Quaternion.Euler(0f, 360f * hash.a, 0f); instance.SetParent(container, false); } } else if (cell.ScenaryObject != 0 && cell.BuildingOnSquare == null) { cell.BuildingOnSquare = Instantiate(scenaryBuildings[cell.ScenaryObject - 1]); cell.BuildingOnSquare.Construct(cell, position, hash); cell.BuildingOnSquare.BuildingModel.SetParent(containerNoDestroy, false); } }
void OnEnable() { GridMetrics.InitializeHashGrid(seed); }
void AddHalfCell(SquareCell cell, GridDirection direction, Vector3 centre, Vector3 v0, Vector3 v1, Vector3 v2, Vector3 va, Vector3 vb, Vector3 vc, Vector3 vd, Vector3 vx, Vector3 vy, Vector3 vz) { Vector3 riverbed = centre + Vector3.up * (cell.CentreElevation + GridMetrics.streamBedElevationOffset) * GridMetrics.elevationStep; Vector3 midSolidEdgePrev = centre + GridMetrics.GetSolidEdge(direction.Previous()) + Vector3.up * (cell.CentreElevation + GridMetrics.streamBedElevationOffset) * GridMetrics.elevationStep; Vector3 midSolidEdgeNext = centre + GridMetrics.GetSolidEdge(direction.Next()) + Vector3.up * (cell.CentreElevation + GridMetrics.streamBedElevationOffset) * GridMetrics.elevationStep; SquareCell neighborPrev = cell.GetNeighbor(direction.Previous()) ?? cell; SquareCell neighborNext = cell.GetNeighbor(direction.Next()) ?? cell; Vector3 midEdgePrev = centre + GridMetrics.GetEdge(direction.Previous()) + Vector3.up * ((cell.CentreElevation + neighborPrev.CentreElevation) / 2 + GridMetrics.streamBedElevationOffset) * GridMetrics.elevationStep; Vector3 midEdgeNext = centre + GridMetrics.GetEdge(direction.Next()) + Vector3.up * ((cell.CentreElevation + neighborNext.CentreElevation) / 2 + GridMetrics.streamBedElevationOffset) * GridMetrics.elevationStep; if (cell.HasRiver) { if (cell.HasRiverThroughEdge(direction.Previous())) { terrain.AddTriangle(v0, midSolidEdgePrev, riverbed); // split tri into two tris terrain.AddTriangle(midSolidEdgePrev, v1, riverbed); } else { terrain.AddTriangle(v0, v1, riverbed); } // edge with no river if (cell.HasRiverThroughEdge(direction.Next())) { terrain.AddTriangle(v1, midSolidEdgeNext, riverbed); // split tri into two tris terrain.AddTriangle(midSolidEdgeNext, v2, riverbed); } else { terrain.AddTriangle(v1, v2, riverbed); } // edge with no river } else { terrain.AddTriangle(v0, v1, v2); } if (cell.HasRiverThroughEdge(direction.Next())) { terrain.AddQuad(v1, va, midEdgeNext, midSolidEdgeNext); terrain.AddQuad(midSolidEdgeNext, midEdgeNext, vb, v2); } else { terrain.AddQuad(v1, va, vb, v2); } // top Edge if (cell.HasRiverThroughEdge(direction.Previous())) { terrain.AddQuad(v1, midSolidEdgePrev, midEdgePrev, vd); terrain.AddQuad(midSolidEdgePrev, v0, vc, midEdgePrev); } else { terrain.AddQuad(v1, v0, vc, vd); } // left Edge if (cell.HasRiverThroughEdge(direction)) { } else { terrain.AddQuad(v1, vd, vx, va); } // direction edge if (cell.HasRiverThroughEdge(direction.Next2())) { } else { terrain.AddQuad(v2, vb, vy, vz); } // clockwise edge AddColors(cell, direction); if (cell.HasRoadThroughEdge(direction.Next())) { midEdgeNext = centre + GridMetrics.GetEdge(direction.Next()) + Vector3.up * ((int)cell.GridElevations[direction] + (int)cell.GridElevations[direction.Next2()]) / 2 * GridMetrics.elevationStep; midSolidEdgeNext = centre + GridMetrics.GetSolidEdge(direction.Next()) + Vector3.up * ((int)cell.GridElevations[direction] + (int)cell.GridElevations[direction.Next2()]) / 2 * GridMetrics.elevationStep; TriangulateRoadSegment(v1, midSolidEdgeNext, v2, va, midEdgeNext, vb); } if (cell.HasRoadThroughEdge(direction.Previous())) { midEdgePrev = centre + GridMetrics.GetEdge(direction.Previous()) + Vector3.up * ((int)cell.GridElevations[direction] + (int)cell.GridElevations[direction.Previous2()]) / 2 * GridMetrics.elevationStep; midSolidEdgePrev = centre + GridMetrics.GetSolidEdge(direction.Previous()) + Vector3.up * ((int)cell.GridElevations[direction] + (int)cell.GridElevations[direction.Previous2()]) / 2 * GridMetrics.elevationStep; TriangulateRoadSegment(v0, midSolidEdgePrev, v1, vc, midEdgePrev, vd); } }
void AddMeshForSquare(SquareCell cell) { Vector3 centre = cell.transform.localPosition; Vector3 verticleCentre = centre + Vector3.up * cell.CentreElevation * GridMetrics.elevationStep; Vector3 vb0 = centre + GridMetrics.GetEdge(GridDirection.SW); Vector3 vb1 = centre + GridMetrics.GetEdge(GridDirection.NW); Vector3 vb2 = centre + GridMetrics.GetEdge(GridDirection.NE); Vector3 vb3 = centre + GridMetrics.GetEdge(GridDirection.SE); vb0 = vb0 + Vector3.up * (cell.GridElevations.Y0) * GridMetrics.elevationStep; vb1 = vb1 + Vector3.up * (cell.GridElevations.Y1) * GridMetrics.elevationStep; vb2 = vb2 + Vector3.up * (cell.GridElevations.Y2) * GridMetrics.elevationStep; vb3 = vb3 + Vector3.up * (cell.GridElevations.Y3) * GridMetrics.elevationStep; Vector3 vs0 = centre + GridMetrics.GetSolidEdge(GridDirection.SW); Vector3 vs1 = centre + GridMetrics.GetSolidEdge(GridDirection.NW); Vector3 vs2 = centre + GridMetrics.GetSolidEdge(GridDirection.NE); Vector3 vs3 = centre + GridMetrics.GetSolidEdge(GridDirection.SE); Vector3 bridgeW = GridMetrics.GetBridge(GridDirection.W); Vector3 bridgeN = GridMetrics.GetBridge(GridDirection.N); Vector3 bridgeE = GridMetrics.GetBridge(GridDirection.E); Vector3 bridgeS = GridMetrics.GetBridge(GridDirection.S); Vector3 vS0 = vs0 + bridgeS + GetVertexBlendElevation(cell.GridElevations, GridDirection.SW, GridDirection.S); Vector3 vW0 = vs0 + bridgeW + GetVertexBlendElevation(cell.GridElevations, GridDirection.SW, GridDirection.W); Vector3 vN1 = vs1 + bridgeN + GetVertexBlendElevation(cell.GridElevations, GridDirection.NW, GridDirection.N); Vector3 vW1 = vs1 + bridgeW + GetVertexBlendElevation(cell.GridElevations, GridDirection.NW, GridDirection.W); Vector3 vN2 = vs2 + bridgeN + GetVertexBlendElevation(cell.GridElevations, GridDirection.NE, GridDirection.N); Vector3 vE2 = vs2 + bridgeE + GetVertexBlendElevation(cell.GridElevations, GridDirection.NE, GridDirection.E); Vector3 vE3 = vs3 + bridgeE + GetVertexBlendElevation(cell.GridElevations, GridDirection.SE, GridDirection.E); Vector3 vS3 = vs3 + bridgeS + GetVertexBlendElevation(cell.GridElevations, GridDirection.SE, GridDirection.S); if (cell.GridElevations.Y0 == cell.GridElevations.Y2) // keep diagonals level { vs0 += Vector3.up * (cell.GridElevations.Y0) * GridMetrics.elevationStep; vs1 += GetDoubleVertexBlendElevation(cell.GridElevations, GridDirection.NW); vs2 += Vector3.up * (cell.GridElevations.Y2) * GridMetrics.elevationStep; vs3 += GetDoubleVertexBlendElevation(cell.GridElevations, GridDirection.SE); } else if (cell.GridElevations.Y1 == cell.GridElevations.Y3) { vs0 += GetDoubleVertexBlendElevation(cell.GridElevations, GridDirection.SW); vs1 += Vector3.up * (cell.GridElevations.Y1) * GridMetrics.elevationStep; vs2 += GetDoubleVertexBlendElevation(cell.GridElevations, GridDirection.NE); vs3 += Vector3.up * (cell.GridElevations.Y3) * GridMetrics.elevationStep; } else { vs0 += GetDoubleVertexBlendElevation(cell.GridElevations, GridDirection.SW); vs1 += GetDoubleVertexBlendElevation(cell.GridElevations, GridDirection.NW); vs2 += GetDoubleVertexBlendElevation(cell.GridElevations, GridDirection.NE); vs3 += GetDoubleVertexBlendElevation(cell.GridElevations, GridDirection.SE); } // Works out which diagonal to add if (cell.GridElevations.Y0 == cell.GridElevations.Y2 || Mathf.Abs(cell.GridElevations.Y0 - cell.GridElevations.Y2) < Mathf.Abs(cell.GridElevations.Y1 - cell.GridElevations.Y3)) // sets direction of the triangle pairs in the quad { AddHalfCell(cell, GridDirection.NW, centre, vs0, vs1, vs2, vN1, vN2, vW0, vW1, vb1, vb2, vE2); AddHalfCell(cell, GridDirection.SE, centre, vs2, vs3, vs0, vS3, vS0, vE2, vE3, vb3, vb0, vW0); } else { AddHalfCell(cell, GridDirection.SW, centre, vs3, vs0, vs1, vW0, vW1, vS3, vS0, vb0, vb1, vN1); AddHalfCell(cell, GridDirection.NE, centre, vs1, vs2, vs3, vE2, vE3, vN1, vN2, vb2, vb3, vS3); } if (cell.HasRoads) { TriangulateRoadCentre(cell, verticleCentre, vs0, vs1, vs2, vs3); } if (cell.HasRiver) { if (cell.HasRiverThroughEdge(GridDirection.N)) { TriangulateWithRiver(GridDirection.N, cell, centre, vs1, vb1, vb2, vs2, 0f); } else { TriangulateWithRiver(GridDirection.N, cell, centre, vs1, vb1, vb2, vs2, 0f); } if (cell.HasRiverThroughEdge(GridDirection.E)) { TriangulateWithRiver(GridDirection.E, cell, centre, vs2, vb2, vb3, vs3, 0.5f); } else { TriangulateWithRiver(GridDirection.E, cell, centre, vs2, vb2, vb3, vs3, 0.5f); } if (cell.HasRiverThroughEdge(GridDirection.S)) { TriangulateWithRiver(GridDirection.S, cell, centre, vs3, vb3, vb0, vs0, 1f); } else { TriangulateWithRiver(GridDirection.S, cell, centre, vs3, vb3, vb0, vs0, 1f); } if (cell.HasRiverThroughEdge(GridDirection.W)) { TriangulateWithRiver(GridDirection.W, cell, centre, vs0, vb0, vb1, vs1, 0.5f); } else { TriangulateWithRiver(GridDirection.W, cell, centre, vs0, vb0, vb1, vs1, 0.5f); } } if (cell.IsUnderwater) { AddWaterForSquare(cell, centre); } if (!cell.IsUnderwater && !cell.HasRoads) { features.AddFeature(cell, verticleCentre); } }