private void TriangulateConnection(VoronoiCell cell, VoronoiDirection direction, EdgeVertices e1) { VoronoiCell neighbor = cell.GetNeighbor(direction); Vector3 bridge = VoronoiMetrics.GetBridge(cell, direction); EdgeVertices e2 = new EdgeVertices( e1.V1 + bridge, e1.V5 + bridge ); if (cell.HasRiverThroughEdge(direction)) { e2.V3 = Vector3.ClampMagnitude(e2.V3, neighbor.StreamBedElevation); TriangulateRiverQuad(e1.V2, e1.V4, e2.V2, e2.V4, cell.RiverSurfaceElevation, neighbor.RiverSurfaceElevation, 0.8f, cell.HasIncomingRiver && cell.IncomingRiver == direction ); } if (cell.GetEdgeType(direction) == VoronoiEdgeType.Slope) { TriangulateEdgeTerraces(e1, cell, e2, neighbor, cell.HasRoadThroughEdge(direction)); } else { TriangulateEdgeStrip(e1, cell.Color, e2, neighbor.Color, cell.HasRoadThroughEdge(direction)); } VoronoiCell nextNeighbor = cell.GetNeighbor(direction.Next(cell)); if (cell.CornerConnections.Contains(direction)) { Vector3 v5 = e1.V5 + VoronoiMetrics.GetBridge(cell, direction.Next(cell)); if (cell.Elevation <= neighbor.Elevation) { if (cell.Elevation <= nextNeighbor.Elevation) { TriangulateCorner(e1.V5, cell, e2.V5, neighbor, v5, nextNeighbor); } else { TriangulateCorner(v5, nextNeighbor, e1.V5, cell, e2.V5, neighbor); } } else if (neighbor.Elevation <= nextNeighbor.Elevation) { TriangulateCorner(e2.V5, neighbor, v5, nextNeighbor, e1.V5, cell); } else { TriangulateCorner(v5, nextNeighbor, e1.V5, cell, e2.V5, neighbor); } } }
private Vector2 GetRoadInterpolators(VoronoiCell cell, VoronoiDirection direction) { Vector2 interpolators; if (cell.HasRoadThroughEdge(direction)) { interpolators.x = interpolators.y = 0.5f; } else { interpolators.x = cell.HasRoadThroughEdge(direction.Previous(cell)) ? 0.5f : 0.25f; interpolators.y = cell.HasRoadThroughEdge(direction.Next(cell)) ? 0.5f : 0.25f; } return(interpolators); }
private void TriangulateRoadAdjacentToRiver(VoronoiCell cell, VoronoiDirection direction, Vector3 center, EdgeVertices e) { bool hasRoadThroughEdge = cell.HasRoadThroughEdge(direction); bool previousHasRiver = cell.HasRiverThroughEdge(direction.Previous(cell)); bool nextHasRiver = cell.HasRiverThroughEdge(direction.Next(cell)); Vector2 interpolators = GetRoadInterpolators(cell, direction); Vector3 roadCenter = center; if (cell.HasRiverBeginOrEnd) { roadCenter -= VoronoiMetrics.GetSolidEdgeMiddle(cell, cell.RiverBeginOrEndDirection) * (1 / 3f); } else if (cell.IncomingRiver == cell.OutgoingRiver.Previous(cell)) { roadCenter -= VoronoiMetrics.GetSecondCorner(cell, cell.IncomingRiver) * 0.2f; } else if (cell.IncomingRiver == cell.OutgoingRiver.Next(cell)) { roadCenter -= VoronoiMetrics.GetFirstCorner(cell, cell.IncomingRiver) * 0.2f; } else if (cell.HasRoadOnThisSideOfRiver(direction)) { Vector3 offset = cell.GetRiverMidpointOffset(direction); if (previousHasRiver && nextHasRiver) { roadCenter += offset * 0.7f; center += offset * 0.5f; } else { roadCenter += offset * 0.5f; center += offset * 0.2f; } } else { return; } Vector3 mL = Vector3.Lerp(roadCenter, e.V1, interpolators.x); Vector3 mR = Vector3.Lerp(roadCenter, e.V5, interpolators.y); TriangulateRoad(roadCenter, mL, mR, e, hasRoadThroughEdge); if (previousHasRiver) { TriangulateRoadEdge(roadCenter, center, mL); } if (nextHasRiver) { TriangulateRoadEdge(roadCenter, mR, center); } }
private void TriangulateWithoutRiver(VoronoiCell cell, VoronoiDirection direction, Vector3 center, EdgeVertices e) { TriangulateEdgeFan(center, e, cell.Color); if (cell.HasRoads) { Vector2 interpolators = GetRoadInterpolators(cell, direction); TriangulateRoad( center, Vector3.Lerp(center, e.V1, interpolators.x), Vector3.Lerp(center, e.V5, interpolators.y), e, cell.HasRoadThroughEdge(direction) ); } }