void TriangulateBoundaryTriangle(Vector3 begin, Color beginColor, Vector3 left, Color leftColor, Vector3 boundary, Color boundaryColor, Vector3 types) { Vector3 v2 = HexMetrics_Script.Perturb(HexMetrics_Script.TerraceLerp(begin, left, 1)); Color c2 = HexMetrics_Script.TerraceLerp(beginColor, leftColor, 1); terrain.AddTriangleUnperturbed(HexMetrics_Script.Perturb(begin), v2, boundary); //Search for Rand Error terrain.AddTriangleColor(beginColor, c2, boundaryColor); terrain.AddTriangleTerrainTypes(types); for (int i = 2; i < HexMetrics_Script.terraceSteps; i++) { Vector3 v1 = v2; Color c1 = c2; v2 = HexMetrics_Script.Perturb(HexMetrics_Script.TerraceLerp(begin, left, i)); c2 = HexMetrics_Script.TerraceLerp(beginColor, leftColor, i); terrain.AddTriangleUnperturbed(v1, v2, boundary); terrain.AddTriangleColor(c1, c2, boundaryColor); terrain.AddTriangleTerrainTypes(types); } terrain.AddTriangleUnperturbed(v2, HexMetrics_Script.Perturb(left), boundary); //Search for Rand Error terrain.AddTriangleColor(c2, leftColor, boundaryColor); terrain.AddTriangleTerrainTypes(types); }
void TriangulateOpenWater(HexDirection direction, HexCell_Script cell, HexCell_Script neighbor, Vector3 center) { Vector3 c1 = center + HexMetrics_Script.GetFirstWaterCorner(direction); Vector3 c2 = center + HexMetrics_Script.GetSecondWaterCorner(direction); water.AddTriangle(center, c1, c2); if (direction <= HexDirection.SE && neighbor != null) { Vector3 bridge = HexMetrics_Script.GetWaterBridge(direction); Vector3 e1 = c1 + bridge; Vector3 e2 = c2 + bridge; water.AddQuad(c1, c2, e1, e2); if (direction <= HexDirection.E) { HexCell_Script nextNeighbor = cell.GetNeighbor(direction.Next()); if (nextNeighbor == null || !nextNeighbor.IsUnderwater) { return; } water.AddTriangle(c2, e2, c2 + HexMetrics_Script.GetWaterBridge(direction.Next())); } } }
void TriangulateAdjacentToRiver(HexDirection direction, HexCell_Script cell, Vector3 center, EdgeVertices e) { if (cell.HasRoads) { TriangulateRoadAdjacentToRiver(direction, cell, center, e); } if (cell.HasRiverThroughEdge(direction.Next())) { if (cell.HasRiverThroughEdge(direction.Previous())) { center += HexMetrics_Script.GetSolidEdgeMiddle(direction) * (HexMetrics_Script.innerToOuter * 0.5f); } else if (cell.HasRiverThroughEdge(direction.Previous2())) { center += HexMetrics_Script.GetFirstSolidCorner(direction) * 0.25f; } } else if (cell.HasRiverThroughEdge(direction.Previous()) && cell.HasRiverThroughEdge(direction.Next2())) { center += HexMetrics_Script.GetSecondSolidCorner(direction) * 0.25f; } EdgeVertices 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 (!cell.IsUnderwater && !cell.HasRoadThroughEdge(direction)) { features.AddFeature(cell, (center + e.v1 + e.v5) * (1f / 3f)); } }
void AddWallWedge(Vector3 near, Vector3 far, Vector3 point) { near = HexMetrics_Script.Perturb(near); far = HexMetrics_Script.Perturb(far); point = HexMetrics_Script.Perturb(point); Vector3 center = HexMetrics_Script.WallLerp(near, far); Vector3 thickness = HexMetrics_Script.WallThicknessOffset(near, far); Vector3 v1, v2, v3, v4; Vector3 pointTop = point; point.y = center.y; v1 = center - thickness; v2 = center + thickness; v3 = center - thickness; v4 = center + thickness; v3.y = center.y + HexMetrics_Script.wallHeight; v4.y = center.y + HexMetrics_Script.wallHeight; pointTop.y = center.y + HexMetrics_Script.wallHeight; walls.AddQuadUnperturbed(v1, point, v3, pointTop); walls.AddQuadUnperturbed(point, v2, pointTop, v4); walls.AddTriangleUnperturbed(pointTop, v3, v4); }
void TriangulateCornerCliffTerraces(Vector3 begin, HexCell_Script beginCell, Vector3 left, HexCell_Script leftCell, Vector3 right, HexCell_Script rightCell) { float b = 1f / (leftCell.Elevation - beginCell.Elevation); if (b < 0) { b = -b; } Vector3 boundary = Vector3.Lerp(HexMetrics_Script.Perturb(begin), HexMetrics_Script.Perturb(left), b); Color boundaryColor = Color.Lerp(color1, color2, b); Vector3 types; types.x = beginCell.TerrainTypeIndex; types.y = beginCell.TerrainTypeIndex; types.z = beginCell.TerrainTypeIndex; TriangulateBoundaryTriangle(right, color3, begin, color1, boundary, boundaryColor, types); if (leftCell.GetEdgeType(rightCell) == HexEdgeType.Slope) { TriangulateBoundaryTriangle(left, color2, right, color3, boundary, boundaryColor, types); } else { terrain.AddTriangleUnperturbed(HexMetrics_Script.Perturb(left), HexMetrics_Script.Perturb(right), boundary); //Search for Rand Error terrain.AddTriangleColor(color2, color3, boundaryColor); terrain.AddTriangleTerrainTypes(types); } }
public void AddSpecialFeature(HexCell_Script cell, Vector3 position) { Transform instance = Instantiate(specials[cell.SpecialIndex - 1]); instance.localPosition = HexMetrics_Script.Perturb(position); HexHash hash = HexMetrics_Script.SampleHashGrid(position); instance.localRotation = Quaternion.Euler(0f, 360f * hash.e, 0f); instance.SetParent(container, false); }
private void OnEnable() { if (!HexMetrics_Script.noiseSource) { HexMetrics_Script.noiseSource = noiseSource; HexMetrics_Script.InitializeHashGrid(seed); HexUnit_Script.unitPrefab = unitPrefab; //HexMetrics_Script.colors = colors; } }
public static EdgeVertices TerraceLerp(EdgeVertices a, EdgeVertices b, int step) { EdgeVertices result; result.v1 = HexMetrics_Script.TerraceLerp(a.v1, b.v1, step); result.v2 = HexMetrics_Script.TerraceLerp(a.v2, b.v2, step); result.v3 = HexMetrics_Script.TerraceLerp(a.v3, b.v3, step); result.v4 = HexMetrics_Script.TerraceLerp(a.v4, b.v4, step); result.v5 = HexMetrics_Script.TerraceLerp(a.v5, b.v5, step); return(result); }
public void AddTriangle(Vector3 v1, Vector3 v2, Vector3 v3) { int vertexIndex = vertices.Count; vertices.Add(HexMetrics_Script.Perturb(v1)); vertices.Add(HexMetrics_Script.Perturb(v2)); vertices.Add(HexMetrics_Script.Perturb(v3)); triangles.Add(vertexIndex); triangles.Add(vertexIndex + 1); triangles.Add(vertexIndex + 2); }
public void AddFeature(HexCell_Script cell, Vector3 position) { if (cell.IsSpecial) { return; } HexHash hash = HexMetrics_Script.SampleHashGrid(position); //if (hash.a >= cell.UrbanLevel*0.25f) // return; //Transform instance = Instantiate(urbanPrefabs[cell.UrbanLevel-1]); Transform prefab = PickPrefab(urbanPrefabs, cell.UrbanLevel, hash.a, hash.d); Transform otherprefab = PickPrefab(farmPrefabs, cell.FarmLevel, hash.b, hash.d); float usedHash = hash.a; if (prefab) { if (otherprefab && hash.b < hash.a) { prefab = otherprefab; usedHash = hash.b; } } else if (otherprefab) { prefab = otherprefab; usedHash = hash.b; } otherprefab = PickPrefab(plantPrefabs, cell.PlantLevel, hash.c, hash.d); if (prefab) { if (otherprefab && hash.c < usedHash) { prefab = otherprefab; } } else if (otherprefab) { prefab = otherprefab; } else { return; } Transform instance = Instantiate(prefab); position.y += instance.localScale.y * 0.5f; instance.localPosition = HexMetrics_Script.Perturb(position); instance.localRotation = Quaternion.Euler(0f, 360f * hash.e, 0f); instance.SetParent(container, false); }
void AddWallSegment(Vector3 nearLeft, Vector3 farLeft, Vector3 nearRight, Vector3 farRight, bool addTower = false) { nearLeft = HexMetrics_Script.Perturb(nearLeft); farLeft = HexMetrics_Script.Perturb(farLeft); nearRight = HexMetrics_Script.Perturb(nearRight); farRight = HexMetrics_Script.Perturb(farRight); Vector3 left = HexMetrics_Script.WallLerp(nearLeft, farLeft); Vector3 right = HexMetrics_Script.WallLerp(nearRight, farRight); Vector3 leftThicknessOffset = HexMetrics_Script.WallThicknessOffset(nearLeft, farLeft); Vector3 rightThicknessOffset = HexMetrics_Script.WallThicknessOffset(nearRight, farRight); float leftTop = left.y + HexMetrics_Script.wallHeight; float rightTop = right.y + HexMetrics_Script.wallHeight; Vector3 v1, v2, v3, v4; v1 = left - leftThicknessOffset; v2 = right - rightThicknessOffset; v3 = left - leftThicknessOffset; v4 = right - rightThicknessOffset; v3.y = leftTop; v4.y = rightTop; walls.AddQuadUnperturbed(v1, v2, v3, v4); Vector3 t1 = v3; Vector3 t2 = v4; v1 = left + leftThicknessOffset; v2 = right + rightThicknessOffset; v3 = left + leftThicknessOffset; v4 = right + rightThicknessOffset; v3.y = leftTop; v4.y = rightTop; walls.AddQuadUnperturbed(v2, v1, v4, v3); walls.AddQuadUnperturbed(t1, t2, v3, v4); if (addTower) { Transform towerInstance = Instantiate(wallTower); towerInstance.transform.localPosition = (left + right) * 0.5f; Vector3 rightDirection = right - left; rightDirection.y = 0f; towerInstance.transform.right = rightDirection; towerInstance.SetParent(container, false); } }
//public Color[] colors; private void Awake() { HexMetrics_Script.noiseSource = noiseSource; HexMetrics_Script.InitializeHashGrid(seed); HexUnit_Script.unitPrefab = unitPrefab; // HexMetrics_Script.colors = colors; //gridCanvas = GetComponentInChildren<Canvas>(); //hexMesh = GetComponentInChildren<HexMesh_Script>(); CreateMap(cellCountX, cellCountZ); }
void RefreshPosition() { Vector3 position = transform.localPosition; position.y = elevation * HexMetrics_Script.elevationStep; position.y += (HexMetrics_Script.SampleNoise(position).y * 2f - 1f) * HexMetrics_Script.elevationPerturbStrength; transform.localPosition = position; Vector3 uiPosition = uiRect.localPosition; uiPosition.z = -position.y; uiRect.localPosition = uiPosition; }
public void AddBridge(Vector3 roadCenter1, Vector3 roadCenter2) { roadCenter1 = HexMetrics_Script.Perturb(roadCenter1); roadCenter2 = HexMetrics_Script.Perturb(roadCenter2); Transform instance = Instantiate(bridge); instance.localPosition = (roadCenter1 + roadCenter2) * 0.5f; instance.forward = roadCenter2 - roadCenter1; float length = Vector3.Distance(roadCenter1, roadCenter2); instance.localScale = new Vector3(1, 1, length * (1f / HexMetrics_Script.bridgeDesignLength)); instance.SetParent(container, false); }
void AddWallSegment(Vector3 pivot, HexCell_Script pivotCell, Vector3 left, HexCell_Script leftCell, Vector3 right, HexCell_Script rightCell) { if (pivotCell.IsUnderwater) { return; } bool hasLeftWall = !leftCell.IsUnderwater && pivotCell.GetEdgeType(leftCell) != HexEdgeType.Cliff; bool hasRightWall = !rightCell.IsUnderwater && pivotCell.GetEdgeType(rightCell) != HexEdgeType.Cliff; if (hasLeftWall) { if (hasRightWall) { bool hasTower = false; if (leftCell.Elevation == rightCell.Elevation) { HexHash hash = HexMetrics_Script.SampleHashGrid((pivot + left + right) * (1f / 3f)); hasTower = hash.e < HexMetrics_Script.wallTowerTreshold; } AddWallSegment(pivot, left, pivot, right, hasTower); } else if (leftCell.Elevation < rightCell.Elevation) { AddWallWedge(pivot, left, right); } else { AddWallCap(pivot, left); } } else if (hasRightWall) { if (rightCell.Elevation < leftCell.Elevation) { AddWallWedge(right, pivot, left); } else { AddWallCap(right, pivot); } } }
Transform PickPrefab(HexFeatureCollection[] collection, int level, float hash, float choice) { if (level > 0) { float[] tresholds = HexMetrics_Script.GetFeatureTresholds(level - 1); for (int i = 0; i < tresholds.Length; i++) { if (hash < tresholds[i]) { return(collection[i].Pick(choice)); } } } return(null); }
void TriangulateWaterShore(HexDirection direction, HexCell_Script cell, HexCell_Script neighbor, Vector3 center) { EdgeVertices e1 = new EdgeVertices(center + HexMetrics_Script.GetFirstWaterCorner(direction), center + HexMetrics_Script.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 center2 = neighbor.Position; center2.y = center.y; EdgeVertices e2 = new EdgeVertices(center2 + HexMetrics_Script.GetSecondSolidCorner(direction.Opposite()), center2 + HexMetrics_Script.GetFirstSolidCorner(direction.Opposite())); if (cell.HasRiverThroughEdge(direction)) { TriangulateEstuary(e1, e2, cell.IncomingRiver == direction); } 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); } HexCell_Script nextNeighbor = cell.GetNeighbor(direction.Next()); if (nextNeighbor != null) { Vector3 v3 = nextNeighbor.Position + (nextNeighbor.IsUnderwater ? HexMetrics_Script.GetFirstWaterCorner(direction.Previous()) : HexMetrics_Script.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)); } }
void Triangulate(HexDirection direction, HexCell_Script cell) { Vector3 center = cell.Position; EdgeVertices e = new EdgeVertices(center + HexMetrics_Script.GetFirstSolidCorner(direction), center + HexMetrics_Script.GetSecondSolidCorner(direction)); if (cell.HasRiver) { if (cell.HasRiverThroughEdge(direction)) { e.v3.y = cell.StreamBedY; if (cell.HasRiverBeginOrEnd) { TriangulateWithRiverBeginOrEnd(direction, cell, center, e); } else { TriangulateWithRiver(direction, cell, center, e); } } else { TriangulateAdjacentToRiver(direction, cell, center, e); } } else { TriangulateWithoutRiver(direction, cell, center, e); if (!cell.IsUnderwater && !cell.HasRoadThroughEdge(direction)) { features.AddFeature(cell, (center + e.v1 + e.v5) * (1f / 3f)); } } if (direction <= HexDirection.SE) { TriangulateConnection(direction, cell, e); } if (cell.IsUnderwater) { TriangulateWater(direction, cell, center); } }
void TriangulateCornerTerraces(Vector3 begin, HexCell_Script beginCell, Vector3 left, HexCell_Script leftCell, Vector3 right, HexCell_Script rightCell) { Vector3 v4 = HexMetrics_Script.TerraceLerp(begin, left, 1); Vector3 v5 = HexMetrics_Script.TerraceLerp(begin, right, 1); Color c3 = HexMetrics_Script.TerraceLerp(color1, color2, 1); Color c4 = HexMetrics_Script.TerraceLerp(color1, color3, 1); Vector3 types; types.x = beginCell.TerrainTypeIndex; types.y = leftCell.TerrainTypeIndex; types.z = rightCell.TerrainTypeIndex; terrain.AddTriangle(begin, v4, v5); //Search for Rand Error terrain.AddTriangleColor(color1, c3, c4); terrain.AddTriangleTerrainTypes(types); for (int i = 2; i < HexMetrics_Script.terraceSteps; i++) { Vector3 v1 = v4; Vector3 v2 = v5; Color c1 = c3; Color c2 = c4; v4 = HexMetrics_Script.TerraceLerp(begin, left, i); v5 = HexMetrics_Script.TerraceLerp(begin, right, i); c3 = HexMetrics_Script.TerraceLerp(color1, color2, i); c4 = HexMetrics_Script.TerraceLerp(color1, color3, i); terrain.AddQuad(v1, v2, v4, v5); terrain.AddQuadColor(c1, c2, c3, c4); terrain.AddQuadTerrainTypes(types); } terrain.AddQuad(v4, v5, left, right); //Search for Rand Error terrain.AddQuadColor(c3, c4, color2, color3); terrain.AddQuadTerrainTypes(types); }
void AddWallCap(Vector3 near, Vector3 far) { near = HexMetrics_Script.Perturb(near); far = HexMetrics_Script.Perturb(far); Vector3 center = HexMetrics_Script.WallLerp(near, far); Vector3 thickness = HexMetrics_Script.WallThicknessOffset(near, far); Vector3 v1, v2, v3, v4; v1 = center - thickness; v2 = center + thickness; v3 = center - thickness; v4 = center + thickness; v3.y = center.y + HexMetrics_Script.wallHeight; v4.y = center.y + HexMetrics_Script.wallHeight; walls.AddQuadUnperturbed(v1, v2, v3, v4); }
void TriangulateWaterfallInWater(Vector3 v1, Vector3 v2, Vector3 v3, Vector3 v4, float y1, float y2, float waterY) { v1.y = y1; v2.y = y1; v3.y = y2; v4.y = y2; v1 = HexMetrics_Script.Perturb(v1); v2 = HexMetrics_Script.Perturb(v2); v3 = HexMetrics_Script.Perturb(v3); v4 = HexMetrics_Script.Perturb(v4); float t = (waterY - y2) / (y1 - y2); v3 = Vector3.Lerp(v3, v1, t); v4 = Vector3.Lerp(v4, v2, t); rivers.AddQuadUnperturbed(v1, v2, v3, v4); rivers.AddQuadUV(0f, 1f, 0.8f, 1f); }
void TriangulateEdgeTerraces(EdgeVertices begin, HexCell_Script beginCell, EdgeVertices end, HexCell_Script endCell, bool hasRoad) { EdgeVertices e2 = EdgeVertices.TerraceLerp(begin, end, 1); Color c2 = HexMetrics_Script.TerraceLerp(color1, color2, 1); float t1 = beginCell.TerrainTypeIndex; float t2 = endCell.TerrainTypeIndex; TriangulateEdgeStrip(begin, color1, t1, e2, c2, t2, hasRoad); for (int i = 2; i < HexMetrics_Script.terraceSteps; i++) { EdgeVertices e1 = e2; Color c1 = c2; e2 = EdgeVertices.TerraceLerp(begin, end, i); c2 = HexMetrics_Script.TerraceLerp(color1, color2, i); TriangulateEdgeStrip(e1, c1, t1, e2, c2, t2, hasRoad); } TriangulateEdgeStrip(e2, c2, t1, end, color2, t2, hasRoad); }
void TriangulateWithRiver(HexDirection direction, HexCell_Script cell, Vector3 center, EdgeVertices e) { Vector3 centerL; Vector3 centerR; if (cell.HasRiverThroughEdge(direction.Opposite())) { centerL = center + HexMetrics_Script.GetFirstSolidCorner(direction.Previous()) * 0.25f; centerR = center + HexMetrics_Script.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_Script.GetSolidEdgeMiddle(direction.Next()) * (0.5f * HexMetrics_Script.innerToOuter); } else { centerL = center + HexMetrics_Script.GetSolidEdgeMiddle(direction.Previous()) * (0.5f * HexMetrics_Script.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 = e.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); Vector3 types; types.x = types.y = types.z = cell.TerrainTypeIndex; terrain.AddTriangleTerrainTypes(types); terrain.AddQuadTerrainTypes(types); terrain.AddQuadTerrainTypes(types); terrain.AddTriangleTerrainTypes(types); if (!cell.IsUnderwater) { bool reversed = cell.IncomingRiver == direction; TriangulateRiverQuad(centerL, centerR, m.v2, m.v4, reversed, cell.RiverSurfaceY, 0.4f); TriangulateRiverQuad(m.v2, m.v4, e.v2, e.v4, reversed, cell.RiverSurfaceY, 0.6f); } }
public HexEdgeType GetEdgeType(HexCell_Script otherCell) { return(HexMetrics_Script.GetEdgeType(elevation, otherCell.elevation)); }
public HexEdgeType GetEdgeType(HexDirection direction) { return(HexMetrics_Script.GetEdgeType(elevation, neighbors[(int)direction].elevation)); }
void TriangulateRoadAdjacentToRiver(HexDirection direction, HexCell_Script cell, Vector3 center, EdgeVertices e) { bool hasRoadThroughEdge = cell.HasRoadThroughEdge(direction); bool previousHasRiver = cell.HasRiverThroughEdge(direction.Previous()); bool nextHasRiver = cell.HasRiverThroughEdge(direction.Next()); Vector2 interpolators = GetRoadInterpolators(direction, cell); Vector3 roadCenter = center; if (cell.HasRiverBeginOrEnd) { roadCenter += HexMetrics_Script.GetSolidEdgeMiddle(cell.RiverBeginOrEndDirection.Opposite()) * (1f / 3f); } else if (cell.IncomingRiver == cell.OutgoingRiver.Opposite()) { Vector3 corner; if (previousHasRiver) { if (!hasRoadThroughEdge && !cell.HasRoadThroughEdge(direction.Next())) { return; } corner = HexMetrics_Script.GetSecondSolidCorner(direction); } else { if (!hasRoadThroughEdge && !cell.HasRoadThroughEdge(direction.Previous())) { return; } corner = HexMetrics_Script.GetFirstSolidCorner(direction); } roadCenter += corner * 0.5f; if (cell.IncomingRiver == direction.Next() && (cell.HasRoadThroughEdge(direction.Next2()) || cell.HasRoadThroughEdge(direction.Opposite()))) { features.AddBridge(roadCenter, center - corner * 0.5f); } center += corner * 0.25f; } else if (cell.IncomingRiver == cell.OutgoingRiver.Previous()) { roadCenter -= HexMetrics_Script.GetSecondCorner(cell.IncomingRiver) * 0.2f; } else if (cell.IncomingRiver == cell.OutgoingRiver.Next()) { roadCenter -= HexMetrics_Script.GetFirstCorner(cell.IncomingRiver) * 0.2f; } else if (previousHasRiver && nextHasRiver) { if (!hasRoadThroughEdge) { return; } Vector3 offset = HexMetrics_Script.GetSolidEdgeMiddle(direction) * HexMetrics_Script.innerToOuter; roadCenter += offset * 0.7f; center += offset * 0.5f; } else { HexDirection middle; if (previousHasRiver) { middle = direction.Next(); } else if (nextHasRiver) { middle = direction.Previous(); } else { middle = direction; } if (!cell.HasRoadThroughEdge(middle) && !cell.HasRoadThroughEdge(middle.Previous()) && !cell.HasRoadThroughEdge(middle.Next())) { return; } Vector3 offset = HexMetrics_Script.GetSolidEdgeMiddle(middle); roadCenter += offset * 0.25f; if (direction == middle && cell.HasRoadThroughEdge(direction.Opposite())) { features.AddBridge(roadCenter, center - offset * (HexMetrics_Script.innerToOuter * 0.7f)); } } 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); } }
void TriangulateConnection(HexDirection direction, HexCell_Script cell, EdgeVertices e1) { HexCell_Script neighbor = cell.GetNeighbor(direction); if (neighbor == null) { return; } Vector3 bridge = HexMetrics_Script.GetBridge(direction); bridge.y = neighbor.Position.y - cell.Position.y; EdgeVertices e2 = new EdgeVertices(e1.v1 + bridge, e1.v5 + bridge); bool hasRiver = cell.HasRiverThroughEdge(direction); bool hasRoad = cell.HasRoadThroughEdge(direction); if (hasRiver) { e2.v3.y = neighbor.StreamBedY; if (!cell.IsUnderwater) { if (!neighbor.IsUnderwater) { TriangulateRiverQuad(e1.v2, e1.v4, e2.v2, e2.v4, cell.HasIncomingRiver && cell.IncomingRiver == direction, cell.RiverSurfaceY, neighbor.RiverSurfaceY, 0.8f); } else if (cell.Elevation > neighbor.WaterLevel) { TriangulateWaterfallInWater(e1.v2, e1.v4, e2.v2, e2.v4, cell.RiverSurfaceY, neighbor.RiverSurfaceY, neighbor.WaterSurfaceY); } } else if (!neighbor.IsUnderwater && neighbor.Elevation > cell.WaterLevel) { TriangulateWaterfallInWater(e2.v4, e2.v2, e1.v4, e1.v2, neighbor.RiverSurfaceY, cell.RiverSurfaceY, cell.WaterSurfaceY); } } if (cell.GetEdgeType(direction) == HexEdgeType.Slope) { TriangulateEdgeTerraces(e1, cell, e2, neighbor, hasRoad); } else { TriangulateEdgeStrip(e1, color1, cell.TerrainTypeIndex, e2, color2, neighbor.TerrainTypeIndex, hasRoad); } features.AddWall(e1, cell, e2, neighbor, hasRiver, hasRoad); HexCell_Script nextNeighbor = cell.GetNeighbor(direction.Next()); if (nextNeighbor != null && direction <= HexDirection.E) { Vector3 v5 = e1.v5 + HexMetrics_Script.GetBridge(direction.Next()); v5.y = nextNeighbor.Position.y; 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); } //AddTriangle(v2, v5, v5); //AddTriangleColor(cell.color, neighbor.color, nextNeighbor.color); } }