private void TriangulateWithRiverBeginOrEnd(HexDirection direction, HexCell cell, Vector3 center, EdgeVertices e) { EdgeVertices m = new EdgeVertices(Vector3.Lerp(center, e.v1, 0.5f), Vector3.Lerp(center, e.v5, 0.5f)); m.v3.y = e.v3.y; TriangulateEdgeStrip(m, weights1, cell.Index, e, weights1, cell.Index); TriangulateEdgeFan(center, m, cell.Index); if (!cell.IsUnderwater) { bool reversed = cell.HasIncomingRiver; Vector3 indices; indices.x = indices.y = indices.z = cell.Index; TriangulateRiverQuad(m.v2, m.v4, e.v2, e.v4, cell.RiverSurfaceY, 0.6f, reversed, indices); center.y = m.v2.y = m.v4.y = cell.RiverSurfaceY; rivers.AddTriangle(center, m.v2, m.v4); if (reversed) { rivers.AddTriangleUV(new Vector2(0.5f, 0.4f), new Vector2(1f, 0.2f), new Vector2(0f, 0.2f)); } else { rivers.AddTriangleUV(new Vector2(0.5f, 0.4f), new Vector2(0f, 0.6f), new Vector2(1f, 0.6f)); } rivers.AddTriangleCellData(indices, weights1); } }
private void TriangulateEstuary(EdgeVertices e1, EdgeVertices e2, bool incomingRiver, Vector3 indices) { waterShore.AddTriangle(e2.v1, e1.v2, e1.v1); waterShore.AddTriangle(e2.v5, e1.v5, e1.v4); waterShore.AddTriangleUV(new Vector2(0f, 1f), new Vector2(0f, 0f), new Vector2(0f, 0f)); waterShore.AddTriangleUV(new Vector2(0f, 1f), new Vector2(0f, 0f), new Vector2(0f, 0f)); waterShore.AddTriangleCellData(indices, weights2, weights1, weights1); waterShore.AddTriangleCellData(indices, weights2, weights1, weights1); estuaries.AddQuad(e2.v1, e1.v2, e2.v2, e1.v3); estuaries.AddTriangle(e1.v3, e2.v2, e2.v4); estuaries.AddQuad(e1.v3, e1.v4, e2.v4, e2.v5); estuaries.AddQuadUV(new Vector2(0f, 1f), new Vector2(0f, 0f), new Vector2(1f, 1f), new Vector2(0f, 0f)); estuaries.AddTriangleUV(new Vector2(0f, 0f), new Vector2(1f, 1f), new Vector2(0f, 1f)); estuaries.AddQuadUV(new Vector2(0f, 0f), new Vector2(0f, 0f), new Vector2(1f, 1f), new Vector2(0f, 1f)); estuaries.AddQuadCellData(indices, weights2, weights1, weights2, weights1); estuaries.AddTriangleCellData(indices, weights1, weights2, weights2); estuaries.AddQuadCellData(indices, weights1, weights2); if (incomingRiver) { estuaries.AddQuadUV2(new Vector2(1.5f, 1f), new Vector2(0.7f, 1.15f), new Vector2(1f, 0.8f), new Vector2(0.5f, 1.1f)); estuaries.AddTriangleUV2(new Vector2(0.5f, 1.1f), new Vector2(1f, 0.8f), new Vector2(0f, 0.8f)); estuaries.AddQuadUV2(new Vector2(0.5f, 1.1f), new Vector2(0.3f, 1.15f), new Vector2(0f, 0.8f), new Vector2(-0.5f, 1f)); } else { estuaries.AddQuadUV2(new Vector2(-0.5f, -0.2f), new Vector2(0.3f, -0.35f), new Vector2(0f, 0f), new Vector2(0.5f, -0.3f)); estuaries.AddTriangleUV2(new Vector2(0.5f, -0.3f), new Vector2(0f, 0f), new Vector2(1f, 0f)); estuaries.AddQuadUV2(new Vector2(0.5f, -0.3f), new Vector2(0.7f, -0.35f), new Vector2(1f, 0f), new Vector2(1.5f, -0.2f)); } }
private void TriangulateWithRiver(HexDirection direction, HexCell cell, Vector3 center, EdgeVertices e) { Vector3 centerL, centerR; if (cell.HasRiverThroughEdge(direction.Opposite())) { centerL = center + HexMetrics.GetFirstSolidCorner(direction.Previous()) * 0.25f; centerR = center + HexMetrics.GetSecondSolidCorner(direction.Next()) * 0.25f; } else if (cell.HasRiverThroughEdge(direction.Next())) { centerL = center; centerR = Vector3.Lerp(center, e.v5, 2f / 3f); } else if (cell.HasRiverThroughEdge(direction.Previous())) { centerL = Vector3.Lerp(center, e.v1, 2f / 3f); centerR = center; } else if (cell.HasRiverThroughEdge(direction.Next2())) { centerL = center; centerR = center + HexMetrics.GetSolidEdgeMiddle(direction.Next()) * (0.5f * HexMetrics.innerToOuter); } else { centerL = center + HexMetrics.GetSolidEdgeMiddle(direction.Previous()) * (0.5f * HexMetrics.innerToOuter); centerR = center; } center = Vector3.Lerp(centerL, centerR, 0.5f); EdgeVertices m = new EdgeVertices(Vector3.Lerp(centerL, e.v1, 0.5f), Vector3.Lerp(centerR, e.v5, 0.5f), 1f / 6f); m.v3.y = center.y = e.v3.y; TriangulateEdgeStrip(m, weights1, cell.Index, e, weights1, cell.Index); terrain.AddTriangle(centerL, m.v1, m.v2); terrain.AddQuad(centerL, center, m.v2, m.v3); terrain.AddQuad(center, centerR, m.v3, m.v4); terrain.AddTriangle(centerR, m.v4, m.v5); Vector3 indices; indices.x = indices.y = indices.z = cell.Index; terrain.AddTriangleCellData(indices, weights1); terrain.AddQuadCellData(indices, weights1); terrain.AddQuadCellData(indices, weights1); terrain.AddTriangleCellData(indices, weights1); if (!cell.IsUnderwater) { bool reversed = cell.IncomingRiver == direction; TriangulateRiverQuad(centerL, centerR, m.v2, m.v4, cell.RiverSurfaceY, 0.4f, reversed, indices); TriangulateRiverQuad(m.v2, m.v4, e.v2, e.v4, cell.RiverSurfaceY, 0.6f, reversed, indices); } }
private void TriangulateRoad(Vector3 center, Vector3 mL, Vector3 mR, EdgeVertices e, bool hasRoadThroughCellEdge, float index) { if (hasRoadThroughCellEdge) { Vector3 indices; indices.x = indices.y = indices.z = index; Vector3 mC = Vector3.Lerp(mL, mR, 0.5f); TriangulateRoadSegment(mL, mC, mR, e.v2, e.v3, e.v4, weights1, weights2, indices); roads.AddTriangle(center, mL, mC); roads.AddTriangle(center, mC, mR); roads.AddTriangleUV(new Vector2(1f, 0f), new Vector2(0f, 0f), new Vector2(1f, 0f)); roads.AddTriangleUV(new Vector2(1f, 0f), new Vector2(1f, 0f), new Vector2(0f, 0f)); roads.AddTriangleCellData(indices, weights1); roads.AddTriangleCellData(indices, weights1); } else { TriangulateRoadEdge(center, mL, mR, index); } }
private void TriangulateOpenWater(HexDirection direction, HexCell cell, HexCell neighbor, Vector3 center) { var c1 = center + HexMetrics.GetFirstWaterCorner(direction); var c2 = center + HexMetrics.GetSecondWaterCorner(direction); water.AddTriangle(center, c1, c2); Vector3 indices; indices.x = indices.y = indices.z = cell.Index; water.AddTriangleCellData(indices, weights1); if (direction <= HexDirection.SE) { Vector3 birdge = HexMetrics.GetWaterBridge(direction); var e1 = c1 + birdge; var e2 = c2 + birdge; water.AddQuad(c1, c2, e1, e2); indices.y = neighbor.Index; water.AddQuadCellData(indices, weights1, weights2); if (direction <= HexDirection.E) { HexCell nextNeighbor = cell.GetNeighbor(direction.Next()); if (nextNeighbor == null || !nextNeighbor.IsUnderwater) { return; } water.AddTriangle(c2, e2, c2 + HexMetrics.GetWaterBridge(direction.Next())); indices.z = nextNeighbor.Index; water.AddTriangleCellData(indices, weights1, weights2, weights3); } } }
private void TriangulateWaterShore(HexDirection direction, HexCell cell, HexCell neighbor, Vector3 center) { EdgeVertices e1 = new EdgeVertices( center + HexMetrics.GetFirstWaterCorner(direction), center + HexMetrics.GetSecondWaterCorner(direction) ); water.AddTriangle(center, e1.v1, e1.v2); water.AddTriangle(center, e1.v2, e1.v3); water.AddTriangle(center, e1.v3, e1.v4); water.AddTriangle(center, e1.v4, e1.v5); Vector3 indices; indices.x = indices.z = cell.Index; indices.y = neighbor.Index; water.AddTriangleCellData(indices, weights1); water.AddTriangleCellData(indices, weights1); water.AddTriangleCellData(indices, weights1); water.AddTriangleCellData(indices, weights1); Vector3 center2 = neighbor.Position; center2.y = center.y; EdgeVertices e2 = new EdgeVertices( center2 + HexMetrics.GetSecondSolidCorner(direction.Opposite()), center2 + HexMetrics.GetFirstSolidCorner(direction.Opposite()) ); if (cell.HasRiverThroughEdge(direction)) { TriangulateEstuary(e1, e2, cell.IncomingRiver == direction, indices); } else { waterShore.AddQuad(e1.v1, e1.v2, e2.v1, e2.v2); waterShore.AddQuad(e1.v2, e1.v3, e2.v2, e2.v3); waterShore.AddQuad(e1.v3, e1.v4, e2.v3, e2.v4); waterShore.AddQuad(e1.v4, e1.v5, e2.v4, e2.v5); waterShore.AddQuadUV(0f, 0f, 0f, 1f); waterShore.AddQuadUV(0f, 0f, 0f, 1f); waterShore.AddQuadUV(0f, 0f, 0f, 1f); waterShore.AddQuadUV(0f, 0f, 0f, 1f); waterShore.AddQuadCellData(indices, weights1, weights2); waterShore.AddQuadCellData(indices, weights1, weights2); waterShore.AddQuadCellData(indices, weights1, weights2); waterShore.AddQuadCellData(indices, weights1, weights2); } HexCell nextNeighbor = cell.GetNeighbor(direction.Next()); if (nextNeighbor != null) { Vector3 v3 = nextNeighbor.Position + (nextNeighbor.IsUnderwater ? HexMetrics.GetFirstWaterCorner(direction.Previous()) : HexMetrics.GetFirstSolidCorner(direction.Previous()) ); v3.y = center.y; waterShore.AddTriangle(e1.v5, e2.v5, v3); waterShore.AddTriangleUV( new Vector2(0f, 0f), new Vector2(0f, 1f), new Vector2(0f, nextNeighbor.IsUnderwater ? 0f : 1f) ); indices.z = nextNeighbor.Index; waterShore.AddTriangleCellData(indices, weights1, weights2, weights3); } }