void TriangulateAdjacentToRiver(HexDirection dir, HexCell cell, Vector3 center, EdgeVertices e) { if (cell.HasRoads) { TriangulateRoadAdjacentToRiver(dir, cell, center, e); } if (cell.HasRiverThroughEdge(dir.Next())) { if (cell.HasRiverThroughEdge(dir.Previous())) { center += HexMetrics.GetSolidEdgeMiddle(dir) * (HexMetrics.innerToOuter * 0.5f); } else if (cell.HasRiverThroughEdge(dir.Previous2())) { center += HexMetrics.GetFirstSolidCorner(dir) * 0.25f; } } else if (cell.HasRiverThroughEdge(dir.Previous()) && cell.HasRiverThroughEdge(dir.Next2())) { center += HexMetrics.GetSecondSolidCorner(dir) * 0.25f; } var m = new EdgeVertices( Vector3.Lerp(center, e.v1, 0.5f), Vector3.Lerp(center, e.v5, 0.5f)); TriangulateEdgeStrip(m, color1, cell.terrainTypeIndex, e, color1, cell.terrainTypeIndex); TriangulateEdgeFan(center, m, cell.terrainTypeIndex); if (CanAddFeature(cell, dir)) { // offset the feature slightly from the center towards // the directional edge. var pos = (center + e.v1 + e.v5) * (1f / 3f); features.AddFeature(cell, pos); } }
public void AddWall( EdgeVertices near, HexCell nearCell, EdgeVertices far, HexCell farCell, bool hasRiver, bool hasRoad) { if (!CanBuildWall(nearCell, farCell)) { return; } AddWallSegment(near.v1, far.v1, near.v2, far.v2); if (hasRiver || hasRoad) { AddWallCap(near.v2, far.v2); AddWallCap(far.v4, near.v4); } else { AddWallSegment(near.v2, far.v2, near.v3, far.v3); AddWallSegment(near.v3, far.v3, near.v4, far.v4); } AddWallSegment(near.v4, far.v4, near.v5, far.v5); }
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); var 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, color1, cell.terrainTypeIndex, e, color1, cell.terrainTypeIndex); terrain.AddTriangle(centerL, m.v1, m.v2); //terrain.AddTriangleColor(cell.color); terrain.AddQuad(centerL, center, m.v2, m.v3); //terrain.AddQuadColor(cell.color); terrain.AddQuad(center, centerR, m.v3, m.v4); //terrain.AddQuadColor(cell.color); terrain.AddTriangle(centerR, m.v4, m.v5); //terrain.AddTriangleColor(cell.color); terrain.AddTriangleColor(color1); terrain.AddQuadColor(color1); terrain.AddQuadColor(color1); terrain.AddTriangleColor(color1); var types = Vector3.one * cell.terrainTypeIndex; terrain.AddTriangleTerrainTypes(types); terrain.AddQuadTerrainTypes(types); terrain.AddQuadTerrainTypes(types); terrain.AddTriangleTerrainTypes(types); if (!cell.isUnderWater) { var reversed = cell.incomingRiver == direction; TriangulateRiverQuad(centerL, centerR, m.v2, m.v4, cell.riverSurfaceY, 0.4f, reversed); TriangulateRiverQuad(m.v2, m.v4, e.v2, e.v4, cell.riverSurfaceY, 0.6f, reversed); } }
void TriangulateRoadAdjacentToRiver(HexDirection dir, HexCell cell, Vector3 center, EdgeVertices e) { var hasRoadThroughEdge = cell.HasRoadThroughEdge(dir); var previousHasRiver = cell.HasRiverThroughEdge(dir.Previous()); var nextHasRiver = cell.HasRiverThroughEdge(dir.Next()); var interpolators = GetRoadInterpolators(dir, cell); var roadCenter = center; if (cell.hasRiverBeginOrEnd) { roadCenter += HexMetrics.GetSolidEdgeMiddle( cell.riverBeginOrEndDirection.Opposite() ) * (1f / 3f); } else if (cell.incomingRiver == cell.outgoingRiver.Opposite()) { Vector3 corner; if (previousHasRiver) { if (!hasRoadThroughEdge && !cell.HasRoadThroughEdge(dir.Next())) { return; } corner = HexMetrics.GetSecondSolidCorner(dir); } else { if (!hasRoadThroughEdge && !cell.HasRoadThroughEdge(dir.Previous())) { return; } corner = HexMetrics.GetFirstSolidCorner(dir); } roadCenter += corner * 0.5f; if (CanAddBridge(cell, dir)) { features.AddBridge(roadCenter, center - corner * 0.5f); } center += corner * 0.25f; } else if (cell.incomingRiver == cell.outgoingRiver.Previous()) { roadCenter -= HexMetrics.GetSecondCorner(cell.incomingRiver) * 0.2f; } else if (cell.incomingRiver == cell.outgoingRiver.Next()) { roadCenter -= HexMetrics.GetFirstCorner(cell.incomingRiver) * 0.2f; } else if (previousHasRiver && nextHasRiver) { if (!hasRoadThroughEdge) { return; } var offset = HexMetrics.GetSolidEdgeMiddle(dir) * HexMetrics.innerToOuter; roadCenter += offset * 0.7f; center += offset * 0.5f; } else { HexDirection middle; if (previousHasRiver) { middle = dir.Next(); } else if (nextHasRiver) { middle = dir.Previous(); } else { middle = dir; } if (!cell.HasRoadThroughEdge(middle) && !cell.HasRoadThroughEdge(middle.Previous()) && !cell.HasRoadThroughEdge(middle.Next())) { return; } var offset = HexMetrics.GetSolidEdgeMiddle(middle); roadCenter += offset * 0.25f; if (dir == middle && cell.HasRoadThroughEdge(dir.Opposite())) { features.AddBridge( roadCenter, center - offset * (HexMetrics.innerToOuter * 0.7f)); } } var mL = Vector3.Lerp(roadCenter, e.v1, interpolators.x); var 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); } }
void TriangulateConnection(HexDirection direction, HexCell cell, EdgeVertices el) { var neighbor = cell.GetNeighbor(direction); if (!neighbor) { return; } var bridge = HexMetrics.GetBridge(direction); bridge.y = neighbor.position.y - cell.position.y; var el2 = new EdgeVertices( el.v1 + bridge, el.v5 + bridge); var hasRiver = cell.HasRiverThroughEdge(direction); var hasRoad = cell.HasRoadThroughEdge(direction); if (hasRiver) { el2.v3.y = neighbor.streamBedY; if (!cell.isUnderWater) { if (!neighbor.isUnderWater) { TriangulateRiverQuad( el.v2, el.v4, el2.v2, el2.v4, cell.riverSurfaceY, neighbor.riverSurfaceY, cell.hasIncomingRiver && cell.incomingRiver == direction); } else if (cell.elevation > neighbor.waterLevel) { TriangulateWaterfallInWater(el.v2, el.v4, el2.v2, el2.v4, cell.riverSurfaceY, neighbor.riverSurfaceY, neighbor.waterSurfaceY); } } else if (!neighbor.isUnderWater && neighbor.elevation > cell.waterLevel) { TriangulateWaterfallInWater(el2.v4, el2.v2, el.v4, el.v2, neighbor.riverSurfaceY, cell.riverSurfaceY, cell.waterSurfaceY); } } if (cell.GetEdgeType(direction) == HexEdgeType.Slope) { TriangulateEdgeTerraces(el, cell, el2, neighbor, hasRoad); } else { TriangulateEdgeStrip(el, color1, cell.terrainTypeIndex, el2, color2, neighbor.terrainTypeIndex, hasRoad); } features.AddWall(el, cell, el2, neighbor, hasRiver, hasRoad); var next_d = direction.Next(); var nextNeighbor = cell.GetNeighbor(next_d); if (direction <= HexDirection.E && nextNeighbor) { var v5 = el.v5 + HexMetrics.GetBridge(next_d); v5.y = nextNeighbor.position.y; if (cell.elevation <= neighbor.elevation) { if (cell.elevation <= nextNeighbor.elevation) { TriangulateCorner(el.v5, cell, el2.v5, neighbor, v5, nextNeighbor); } else { TriangulateCorner(v5, nextNeighbor, el.v5, cell, el2.v5, neighbor); } } else if (neighbor.elevation <= nextNeighbor.elevation) { TriangulateCorner(el2.v5, neighbor, v5, nextNeighbor, el.v5, cell); } else { TriangulateCorner(v5, nextNeighbor, el.v5, cell, el2.v5, neighbor); } //AddTriangle(v2, v4, v5); //AddTriangleColor(cell.color, neighbor.color, nextNeighbor.color); } }