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); } } }
void TriangulateWithRiver( GridDirection direction, SquareCell cell, Vector3 centre, Vector3 v0, Vector3 v1, Vector3 v2, Vector3 v3, float v ) { GridDirection flowDirection; bool reversed = cell.HasIncomingRiver[(int)direction]; if (cell.HasOutgoingRiver[(int)direction]) { flowDirection = direction; } else if (reversed) { flowDirection = direction.Opposite(); } else { if (cell.HasIncomingRiver[(int)direction.Next2()] && cell.HasOutgoingRiver[(int)direction.Previous2()]) { flowDirection = direction.Previous2(); } else if (cell.HasOutgoingRiver[(int)direction.Next2()] && cell.HasIncomingRiver[(int)direction.Previous2()]) { flowDirection = direction.Next2(); } else { flowDirection = direction.Opposite(); } } TriangulateRiverTri(centre, v0, v3, cell.RiverSurfaceY, reversed, direction, flowDirection); SquareCell neighbor = cell.GetNeighbor(direction); if (neighbor && cell.HasRiverThroughEdge(direction)) { TriangulateRiverQuad(v3, v0, v1, v2, cell.RiverSurfaceY, neighbor.RiverSurfaceY, 0.8f, reversed); } }
void EditCell(SquareCell cell, Vector3 hitpoint) { if (activeMode == EditMode.color) { cell.Tile = activeTileMaterial.GetClone; } else if (activeMode == EditMode.elevation) { GridDirection vertex = squareGrid.GetVertex(hitpoint); if (Input.GetMouseButton(0) && (stopWatch.ElapsedMilliseconds > 500f || freshClick)) { cell.ChangeVertexElevation(vertex, 1); if (!allowCliffs) { if (cell.GetNeighbor(vertex)) { cell.GetNeighbor(vertex).ChangeVertexElevation(vertex.Opposite(), 1); } if (cell.GetNeighbor(vertex.Next())) { cell.GetNeighbor(vertex.Next()).ChangeVertexElevation(vertex.Previous2(), 1); } if (cell.GetNeighbor(vertex.Previous())) { cell.GetNeighbor(vertex.Previous()).ChangeVertexElevation(vertex.Next2(), 1); } } stopWatch.Reset(); stopWatch.Start(); } if (Input.GetMouseButton(1) && (stopWatch.ElapsedMilliseconds > 500f || freshClick)) { cell.ChangeVertexElevation(vertex, -1); if (!allowCliffs) { if (cell.GetNeighbor(vertex)) { cell.GetNeighbor(vertex).ChangeVertexElevation(vertex.Opposite(), -1); } if (cell.GetNeighbor(vertex.Next())) { cell.GetNeighbor(vertex.Next()).ChangeVertexElevation(vertex.Previous2(), -1); } if (cell.GetNeighbor(vertex.Previous())) { cell.GetNeighbor(vertex.Previous()).ChangeVertexElevation(vertex.Next2(), -1); } } stopWatch.Reset(); stopWatch.Start(); } } else if (activeMode == EditMode.rivers) { if (Input.GetMouseButton(1)) { cell.RemoveRivers(); Explosion(cell); } else if (isDrag) { SquareCell otherCell = cell.GetNeighbor(dragDirection.Opposite()); // work with brushes if (otherCell) { otherCell.SetOutgoingRiver(dragDirection); } } } else if (activeMode == EditMode.roads) { float fracX = hitpoint.x - Mathf.Floor(hitpoint.x); float fracZ = hitpoint.z - Mathf.Floor(hitpoint.z); if (fracX > 0.25f && fracX < 0.75f || fracZ > 0.25f && fracZ < 0.75f) { GridDirection edge = squareGrid.GetEdge(hitpoint); if (Input.GetMouseButton(1)) { cell.RemoveRoad(edge); Explosion(cell); } else { cell.AddRoad(edge); } } } else if (activeMode == EditMode.water_level) { if (Input.GetMouseButton(0) && freshClick) { cell.WaterLevel++; } else if (Input.GetMouseButton(1) && freshClick) { cell.WaterLevel--; } } else if (activeMode == EditMode.building) { if (Input.GetMouseButton(0) && freshClick) { cell.UrbanLevel++; } if (Input.GetMouseButton(1) && freshClick) { cell.UrbanLevel = 0; Explosion(cell); } } else if (activeMode == EditMode.trees) { if (Input.GetMouseButton(0) && freshClick) { cell.PlantLevel++; } if (Input.GetMouseButton(1) && freshClick) { cell.PlantLevel = 0; Explosion(cell); } } else if (activeMode == EditMode.rocks) { if (Input.GetMouseButton(0) && freshClick) { cell.ScenaryObject = 1; } if (Input.GetMouseButton(1) && freshClick) { cell.ScenaryObject = 0; Explosion(cell); } } else if (activeMode == EditMode.mast) { if (Input.GetMouseButton(0) && freshClick) { cell.ScenaryObject = 2; } if (Input.GetMouseButton(1) && freshClick) { cell.ScenaryObject = 0; Explosion(cell); } } else if (activeMode == EditMode.lighthouse) { if (Input.GetMouseButton(0) && freshClick) { cell.ScenaryObject = 3; } if (Input.GetMouseButton(1) && freshClick) { cell.ScenaryObject = 0; Explosion(cell); } } else if (activeMode == EditMode.industry) { if (Input.GetMouseButton(0) && freshClick) { cell.Industry = (int)activeIndustry + 1; } if (Input.GetMouseButton(1) && freshClick) { cell.Industry = 0; Explosion(cell); } } else if (activeMode == EditMode.town) { if (cell.Town == null) { GameObject town = Instantiate(townPrefab); TownManager manager = town.GetComponent <TownManager>(); town.transform.position = GridCoordinates.ToPosition(cell.coordinates) + new Vector3(0, cell.CentreElevation * GridMetrics.elevationStep, 0); manager.Init(cell); cell.Town = manager; } } }
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); } }