public void TriangulateAllCells() { // This method could be invoked at any time, even when cells have already been triangulated earlier. // So we should begin by clearing the old data. Terrain.Clear(); Rivers.Clear(); Roads.Clear(); Water.Clear(); WaterShore.Clear(); Estuaries.Clear(); Features.Clear(); for (int i = 0; i < _cells.Length; i++) { Precalculation(_cells[i]); } for (int i = 0; i < _cells.Length; i++) { TriangulateCell(_cells[i]); AddFeatures(_cells[i]); } Terrain.Apply(); Rivers.Apply(); Roads.Apply(); Water.Apply(); WaterShore.Apply(); Estuaries.Apply(); Features.Apply(); }
void TriangulateEstuary(HexCell cell, HexDirection direction) { var neighbor = cell.GetNeighbor(direction); EdgeVertices closerWaterEdge = cell.WaterEdges[(int)direction]; EdgeVertices furtherWaterEdge = neighbor.WaterEdges[(int)direction.Opposite()]; EdgeVertices furtherEdge = neighbor.Edges[(int)direction.Opposite()]; furtherEdge.V1.y = HexMetrics.WaterSurfaceY; furtherEdge.V2.y = HexMetrics.WaterSurfaceY; furtherEdge.V3.y = HexMetrics.WaterSurfaceY; furtherEdge.V4.y = HexMetrics.WaterSurfaceY; furtherEdge.V5.y = HexMetrics.WaterSurfaceY; WaterShore.AddTriangleUnperturbed(furtherEdge.V5, closerWaterEdge.V2, closerWaterEdge.V1); WaterShore.AddTriangleUnperturbed(furtherEdge.V1, closerWaterEdge.V5, closerWaterEdge.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)); // left quad // quad is rotated 90 degrees to the right so the diagonal connection is shorter // it is done to maintain the symetry with the other quad Estuaries.AddQuadUnperturbed(furtherEdge.V5, closerWaterEdge.V2, furtherEdge.V4, closerWaterEdge.V3); Estuaries.AddQuadUV(new Vector2(0f, 1f), new Vector2(0f, 0f), new Vector2(1f, 1f), new Vector2(0f, 0f)); // big triangle in the middle Estuaries.AddTriangleUnperturbed(closerWaterEdge.V3, furtherEdge.V4, furtherEdge.V2); Estuaries.AddTriangleUV(new Vector2(0f, 0f), new Vector2(1f, 1f), new Vector2(0f, 1f)); // right quad Estuaries.AddQuadUnperturbed(closerWaterEdge.V3, closerWaterEdge.V4, furtherEdge.V2, furtherEdge.V1); Estuaries.AddQuadUV(new Vector2(0f, 0f), new Vector2(0f, 0f), new Vector2(1f, 1f), new Vector2(0f, 1f)); // is incoming river if (cell.IncomingRiver == direction) { 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 { // the U coordinates have to be mirrored for outgoing rivers // the V coordinates are a little bit less straightforward 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)); } }
/// <summary> /// 在前边插入新的水岸线 /// </summary> /// <param name="waterShore">Water shore.</param> private void JoinWaterShoreAtFront(WaterShore waterShore) { List <WaterShoreSegment> waterShoreSegmentList = waterShore.mWaterShoreSegmentList; waterShoreSegmentList.AddRange(mWaterShoreSegmentList); mWaterShoreSegmentList = waterShoreSegmentList; waterShore.mWaterShoreSegmentList = null; }
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(1f, 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)); } }
/// <summary> /// 把传入的海岸线和当前的相连起来 /// </summary> /// <returns><c>true</c>, if water shore was joined, <c>false</c> otherwise.</returns> /// <param name="waterShore">Water shore.</param> public bool JoinWaterShore(WaterShore waterShore) { if (mWaterShoreSegmentList.Count == 0) { Debug.LogError("Water shore with no segment"); return(false); } if (waterShore.mWaterShoreSegmentList.Count == 0) { Debug.LogError("Input Water shore with no segment"); return(false); } bool needExchange = false; if (mWaterShoreSegmentList [0].CanJoinAtFront(waterShore.mWaterShoreSegmentList [waterShore.mWaterShoreSegmentList.Count - 1], out needExchange)) { if (!needExchange) { JoinWaterShoreAtFront(waterShore); return(true); } } if (mWaterShoreSegmentList [0].CanJoinAtFront(waterShore.mWaterShoreSegmentList [0], out needExchange)) { if (needExchange) { waterShore.RevertWaterLines(); JoinWaterShoreAtFront(waterShore); return(true); } } if (mWaterShoreSegmentList [mWaterShoreSegmentList.Count - 1].CanJoinAtEnd(waterShore.mWaterShoreSegmentList [0], out needExchange)) { if (!needExchange) { JoinWaterShoreAtEnd(waterShore); return(true); } } if (mWaterShoreSegmentList [mWaterShoreSegmentList.Count - 1].CanJoinAtEnd(waterShore.mWaterShoreSegmentList [waterShore.mWaterShoreSegmentList.Count - 1], out needExchange)) { if (needExchange) { waterShore.RevertWaterLines(); JoinWaterShoreAtEnd(waterShore); return(true); } } return(false); }
List <Water> GenerateWaters(List <WaterShore> waterShores) { //TODO 现在只是对大小进行了排序 waterShores.Sort(delegate(WaterShore x, WaterShore y) { return(x.EdgeSize.CompareTo(y.EdgeSize)); }); List <Water> ret = new List <Water> (); Water waitOutSideWater = null; for (int i = 0; i < waterShores.Count; ++i) { WaterShore waterShore = waterShores [i]; bool isInsideWater = waterShore.IsInsideWater; if (waterShore.IsInvalidShore) { continue; } if (waterShore.IsInsideWater) { //水岸线的内圈是 if (null != waitOutSideWater) { waitOutSideWater.SetOutsideShore(waterShore); ret.Add(waitOutSideWater); waitOutSideWater = null; } else { Water water = new Water(); water.SetSingleShore(waterShore); ret.Add(water); } } else { //水岸线外圈是水,需要等待到下一个包含自己并且内圈是水的 waitOutSideWater = new Water(); waitOutSideWater.SetInsideShore(waterShore); } } if (null != waitOutSideWater) { Debug.LogError("发现没有匹配成功的"); ret.Remove(waitOutSideWater); } Debug.Log("水的数量 " + ret.Count); return(ret); }
/// <summary> /// Creates the estuary (when river meets shore) geometry. /// </summary> void TriangulateEstuary(EdgeVertices e1, EdgeVertices e2, bool incomingRiver, Vector3 indices) { // Some of the estuary is still water shore, namely one triangle on each side // that leaves the estuary itself with a trapezoid shape connecting the shore/river to water 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); // Make the estuary trapezoid Estuaries.AddQuad(e2.v1, e1.v2, e2.v2, e1.v3); // Adding it rotated for symetric geometry Estuaries.AddTriangle(e1.v3, e2.v2, e2.v4); Estuaries.AddQuad(e1.v3, e1.v4, e2.v4, e2.v5); // For shore effect 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(1f, 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); // For river effect, depending on river flow direction UVs are different // That is if river flows into the water or out of the water (e.g. when a river starts from a lake) 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)); } }
/// <summary> /// 传入的水岸线是否完全在当前的内部 /// </summary> /// <returns><c>true</c> if this instance is water shore inside the specified other; otherwise, <c>false</c>.</returns> /// <param name="other">Other.</param> public bool IsWaterShoreInside(WaterShore other) { List <WaterShoreSegment> otherSegments = other.GetAllWaterShoreSegment(); for (int i = 0; i < otherSegments.Count; ++i) { WaterShoreSegment waterSegment = otherSegments [i]; if (!IsPointInSide(waterSegment.posOne)) { return(false); } if (!IsPointInSide(waterSegment.posTwo)) { return(false); } } return(true); }
/// <summary> /// Builds the mesh of the hex grid out of the provided array of cells. /// </summary> public void Triangulate() { Terrain.Clear(); Rivers.Clear(); Roads.Clear(); Water.Clear(); WaterShore.Clear(); Estuaries.Clear(); Features.Clear(); for (int i = 0; i < Cells.Length; i++) { Triangulate(Cells[i]); } Terrain.Apply(); Rivers.Apply(); Roads.Apply(); Water.Apply(); WaterShore.Apply(); Estuaries.Apply(); Features.Apply(); }
public void Triangulate(HexCell[] cells) { Terrain.Clear(); Rivers.Clear(); Roads.Clear(); Water.Clear(); WaterShore.Clear(); Estuaries.Clear(); Features.Clear(); foreach (var cell in cells) { TriangulateCell(cell); } Terrain.Apply(); Rivers.Apply(); Roads.Apply(); Water.Apply(); WaterShore.Apply(); Estuaries.Apply(); Features.Apply(); }
/// <summary> /// Creates geometry for water connection non water cell. /// </summary> void TriangulateWaterShore(HexDirection direction, HexCell cell, HexCell neighbor, Vector3 center) { // Careful to find the WATER corner not the solid corner // Careful to get the WATER bridge EdgeVertices e1 = new EdgeVertices( center + HexMetrics.GetFirstWaterCorner(direction), center + HexMetrics.GetSecondWaterCorner(direction) ); // Triangle fan still part of open water 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); // Bridge - We get the bridge by finding the land hex center and working from there Vector3 center2 = neighbor.Position; if (neighbor.ColumnIndex < cell.ColumnIndex - 1) { center2.x += HexMetrics.WrapSize * HexMetrics.InnerDiameter; } else if (neighbor.ColumnIndex > cell.ColumnIndex + 1) { center2.x -= HexMetrics.WrapSize * HexMetrics.InnerDiameter; } 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.HasIncomingRiver && cell.IncomingRiver == direction, indices); // River and Shore meet -> Estuary -> different geometry } else // Else normal shore geometry { 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); // U null, V -> 0 water side, 1 shore side 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); } // Corner tripple connection triangle - shore water HexCell nextNeighbor = cell.GetNeighbor(direction.Next()); if (nextNeighbor != null) { Vector3 center3 = nextNeighbor.Position; if (nextNeighbor.ColumnIndex < cell.ColumnIndex - 1) { center3.x += HexMetrics.WrapSize * HexMetrics.InnerDiameter; } else if (nextNeighbor.ColumnIndex > cell.ColumnIndex + 1) { center3.x -= HexMetrics.WrapSize * HexMetrics.InnerDiameter; } // Since this is a tripple connection we need to check if neighbor is underwater or not // If he is underwater connect with WaterCorner if not with SolidCorner Vector3 v3 = center3 + (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) // U null, V -> 0 water side, 1 shore side ); indices.z = nextNeighbor.Index; WaterShore.AddTriangleCellData(indices, weights1, weights2, weights3); } }
public void SetOutsideShore(WaterShore shore) { mOutsideShore = shore; }
public void SetInsideShore(WaterShore shore) { mInsideShore = shore; }
public void SetSingleShore(WaterShore shore) { mSingleShore = shore; }
void TriangulateWater(HexDirection direction, HexCell cell) { EdgeVertices closerWaterEdge = cell.WaterEdges[(int)direction]; // water fan Water.AddTriangleUnperturbed(cell.WaterCenter, closerWaterEdge.V1, closerWaterEdge.V5); HexCell neighbor = cell.GetNeighbor(direction); if (neighbor == null) { return; } // estuary if (!neighbor.IsUnderwater && cell.HasRiverThroughEdge(direction)) { TriangulateEstuary(cell, direction); } EdgeVertices furtherEdge = neighbor.Edges[(int)direction.Opposite()]; EdgeVertices furtherWaterEdge = neighbor.WaterEdges[(int)direction.Opposite()]; HexDirection nextDirection = direction.Next(); HexCell nextNeighbor = cell.GetNeighbor(nextDirection); HexCell previousNeighbor = cell.GetNeighbor(direction.Previous()); // neighbor is under water as well if (neighbor.IsUnderwater) { if (direction <= HexDirection.SouthEast) { Water.AddQuadUnperturbed(closerWaterEdge.V1, closerWaterEdge.V5, furtherWaterEdge.V5, furtherWaterEdge.V1); } } // estuary is on the right side else if (nextNeighbor != null && nextNeighbor.HasEstuaryThroughEdge(direction.Previous())) { Vector3 v4 = furtherEdge.V1; v4.y = HexMetrics.WaterSurfaceY; WaterShore.AddQuadUnperturbed(closerWaterEdge.V1, closerWaterEdge.V5, furtherWaterEdge.V5, v4); WaterShore.AddQuadUV(0f, 0f, 0f, 1f); } // estuary is on the left side else if (previousNeighbor != null && previousNeighbor.HasEstuaryThroughEdge(direction.Next())) { Vector3 v3 = furtherEdge.V5; v3.y = HexMetrics.WaterSurfaceY; WaterShore.AddQuadUnperturbed(closerWaterEdge.V1, closerWaterEdge.V5, v3, furtherWaterEdge.V1); WaterShore.AddQuadUV(0f, 0f, 0f, 1f); } // standard connection quad else if (!cell.HasRiverThroughEdge(direction)) { WaterShore.AddQuadUnperturbed(closerWaterEdge.V1, closerWaterEdge.V5, furtherWaterEdge.V5, furtherWaterEdge.V1); WaterShore.AddQuadUV(0f, 0f, 0f, 1f); } // calculate connection triangles if (neighbor.IsUnderwater) { if (direction <= HexDirection.East && nextNeighbor != null && nextNeighbor.IsUnderwater) { Vector3 v3 = nextNeighbor.WaterEdges[(int)nextDirection.Opposite()].V5; Water.AddTriangleUnperturbed(closerWaterEdge.V5, furtherWaterEdge.V1, v3); } } // calculate water shore else if (cell.HasRiverThroughEdge(direction) && nextNeighbor != null) { Vector3 v2 = neighbor.Edges[(int)direction.Opposite()].V1; v2.y = HexMetrics.WaterSurfaceY; Vector3 v3 = nextNeighbor.WaterEdges[(int)nextDirection.Opposite()].V5; WaterShore.AddTriangleUnperturbed(closerWaterEdge.V5, v2, v3); WaterShore.AddTriangleUV(new Vector2(0f, 0f), new Vector2(0f, 1f), new Vector2(0f, nextNeighbor.IsUnderwater ? 0f : 1f)); } else if (nextNeighbor != null) { Vector3 v2, v3; // estuary is on the right side if (cell.HasRiverThroughEdge(nextDirection)) { v2 = furtherWaterEdge.V1; v3 = nextNeighbor.Edges[(int)nextDirection.Opposite()].V5; v3.y = HexMetrics.WaterSurfaceY; } // estuary is on the left side else if (nextNeighbor.HasEstuaryThroughEdge(direction.Previous())) { v2 = furtherEdge.V1; v2.y = HexMetrics.WaterSurfaceY; v3 = nextNeighbor.WaterEdges[(int)nextDirection.Opposite()].V5; } else { v2 = furtherWaterEdge.V1; v3 = nextNeighbor.WaterEdges[(int)nextDirection.Opposite()].V5; } WaterShore.AddTriangleUnperturbed(closerWaterEdge.V5, v2, v3); WaterShore.AddTriangleUV(new Vector2(0f, 0f), new Vector2(0f, 1f), new Vector2(0f, nextNeighbor.IsUnderwater ? 0f : 1f)); } }
/// <summary> /// 在后边加入新的水岸线 /// </summary> /// <param name="waterShore">Water shore.</param> private void JoinWaterShoreAtEnd(WaterShore waterShore) { mWaterShoreSegmentList.AddRange(waterShore.mWaterShoreSegmentList); waterShore.mWaterShoreSegmentList = null; }
private List <WaterShore> GenerateWaterShoreList(List <WaterShoreSegment> waterShoreSegmentList) { List <WaterShore> waterShoreList = new List <WaterShore> (); //先把零散的线段第一次刷选,处理成一一系列的WaterInfo for (int i = 0; i < waterShoreSegmentList.Count; ++i) { WaterShoreSegment waterShoreSegment = waterShoreSegmentList [i]; bool hasFind = false; for (int j = 0; j < waterShoreList.Count; ++j) { WaterShore waterShore = waterShoreList [j]; if (waterShore.JoinWaterShoreSegment(waterShoreSegment)) { hasFind = true; break; } } if (!hasFind) { WaterShore waterInfo = new WaterShore(waterHeight); waterInfo.JoinWaterShoreSegment(waterShoreSegment); waterShoreList.Add(waterInfo); } } bool hasJoinSuccess = false; for (int i = 0; i < waterShoreList.Count; ++i) { //之所以j从0开始,因为A连接B失败,但是B连接A有可能成功,可以优化连接函数 for (int j = 0; j < waterShoreList.Count; ++j) { if (i == j) { continue; } WaterShore waterShoreA = waterShoreList [i]; WaterShore waterShoreB = waterShoreList [j]; //可以为每一个WaterInfo设定唯一表示,并且拼接WaterLine后ID改变,在这里缓存拼接失败的ID对 if (waterShoreA.JoinWaterShore(waterShoreB)) { hasJoinSuccess = true; waterShoreList.RemoveAt(j); break; } } //成功拼接后,waterInfos中的某一个数据已经无效,从新开始 if (hasJoinSuccess) { i = -1; hasJoinSuccess = false; } } Debug.Log("waterInfos.cout: " + waterShoreList.Count); for (int i = 0; i < waterShoreList.Count; ++i) { waterShoreList [i].CheckError(); } return(waterShoreList); }
private void TriangulateWaterShore(HexDirection direction, HexCell cell, HexCell neighbour, Vector3 centre) { var e1 = new EdgeVertices( centre + HexMetrics.GetFirstWaterCorner(direction), centre + HexMetrics.GetSecondWaterCorner(direction) ); Water.AddTriangle(centre, e1.v1, e1.v2); Water.AddTriangle(centre, e1.v2, e1.v3); Water.AddTriangle(centre, e1.v3, e1.v4); Water.AddTriangle(centre, e1.v4, e1.v5); var indices = new Vector3(cell.Index, neighbour.Index, cell.Index); Water.AddTriangleCellData(indices, weights1); Water.AddTriangleCellData(indices, weights1); Water.AddTriangleCellData(indices, weights1); Water.AddTriangleCellData(indices, weights1); var centre2 = neighbour.Position; if (neighbour.ColumnIndex < cell.ColumnIndex - 1) { centre2.x += HexMetrics.WrapSize * HexMetrics.InnerDiameter; } else if (neighbour.ColumnIndex > cell.ColumnIndex + 1) { centre2.x -= HexMetrics.WrapSize * HexMetrics.InnerDiameter; } centre2.y = centre.y; var e2 = new EdgeVertices( centre2 + HexMetrics.GetSecondSolidCorner(direction.Opposite()), centre2 + HexMetrics.GetFirstSolidCorner(direction.Opposite()) ); // rather than calculating from current centre, work backwards from neighbour centre to find edge 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); } var nextNeighbour = cell.GetNeighbour(direction.Next()); if (nextNeighbour == null) { return; } var centre3 = nextNeighbour.Position; if (nextNeighbour.ColumnIndex < cell.ColumnIndex - 1) { centre3.x += HexMetrics.WrapSize * HexMetrics.InnerDiameter; } else if (nextNeighbour.ColumnIndex > cell.ColumnIndex + 1) { centre3.x -= HexMetrics.WrapSize * HexMetrics.InnerDiameter; } var v3 = centre3 + (nextNeighbour.IsUnderwater ? HexMetrics.GetFirstWaterCorner(direction.Previous()) : HexMetrics.GetFirstSolidCorner(direction.Previous())); v3.y = centre.y; WaterShore.AddTriangle(e1.v5, e2.v5, v3); WaterShore.AddTriangleUV( new Vector2(0f, 0f), new Vector2(0f, 1f), new Vector2(0f, nextNeighbour.IsUnderwater ? 0f : 1f)); indices.z = nextNeighbour.Index; WaterShore.AddTriangleCellData(indices, weights1, weights2, weights3); }