public void TriangulateWithRiverBeginningOrEnd(HexDirection dir, HexCell cell, Vector3 center, EdgeVertices edges) { EdgeVertices modifiedEdges = new EdgeVertices(Vector3.Lerp(center, edges.v1, 0.5f), Vector3.Lerp(center, edges.v5, 0.5f)); modifiedEdges.v3.y = edges.v3.y; Color color = Weights1; // cell.Color; TriangulateEdgeStrip(modifiedEdges, color, cell.TerrainTypeIndex, edges, color, cell.CellIndex); TriangulateEdgeFan(center, modifiedEdges, color, cell.CellIndex); if (!cell.IsUnderwater) { bool reverse = cell.HasIncomingRiver; Vector3 indices = new Vector3(cell.CellIndex, cell.CellIndex, cell.CellIndex); TriangulateRiverQuad(modifiedEdges.v2, modifiedEdges.v4, edges.v2, edges.v4, cell.RiverSurfaceY, 0.6f, reverse, indices); center.y = modifiedEdges.v2.y = modifiedEdges.v4.y = cell.RiverSurfaceY; Rivers.AddTriangle(center, modifiedEdges.v2, modifiedEdges.v4); if (reverse) { 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); } }
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.5f), 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); } }
/// <summary> /// 三角化扇形内的道路 /// ----e /// mL--mR /// . /// </summary> /// <param name="center">六边形中点</param> /// <param name="mL">e.v1与center的中点</param> /// <param name="mR">e.v5与center的中点</param> /// <param name="e">扇形的弧(五顶点边)</param> /// <param name="hasRoadThroughCellEdge">该扇形是否有道路</param> /// <param name="index">六边形格子索引</param> void TriangulateRoad(Vector3 center, Vector3 mL, Vector3 mR, EdgeVertices e, bool hasRoadThroughCellEdge, int 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, weights1, 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); } }
public void TriangulateRoadEdge(Vector3 center, Vector3 midLeft, Vector3 midRight, float index) { Roads.AddTriangle(center, midLeft, midRight); Roads.AddTriangleUV(new Vector2(1, 0), Vector2.zero, Vector2.zero); Vector3 indices = new Vector3(index, index, index); Roads.AddTriangleCellData(indices, Weights1); }
public void TriangulateEstuary(EdgeVertices edges1, EdgeVertices edges2, bool incomingRiver, Vector3 indices) { WaterShore.AddTriangle(edges2.v1, edges1.v2, edges1.v1); WaterShore.AddTriangle(edges2.v5, edges1.v5, edges1.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(edges2.v1, edges1.v2, edges2.v2, edges1.v3); Estuaries.AddTriangle(edges1.v3, edges2.v2, edges2.v4); Estuaries.AddQuad(edges1.v3, edges1.v4, edges2.v4, edges2.v5); Estuaries.AddQuadUV(new Vector2(0f, 1f), new Vector2(0f, 0f), new Vector2(0f, 1f), new Vector2(0f, 0f)); Estuaries.AddTriangleUV(new Vector2(0f, 0f), new Vector2(0f, 1f), new Vector2(0f, 1f)); Estuaries.AddQuadUV(0f, 0f, 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> /// <param name="direction"></param> /// <param name="cell"></param> /// <param name="center"></param> /// <param name="e"></param> 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; // 流入河水需要翻转UV 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); } }
/// <summary> /// 三角化河口 /// </summary> /// <param name="e1">自身纯色区扇形边(弧)</param> /// <param name="e2">邻居纯色区扇形边(弧)</param> /// <param name="incomingRiver">是否是流入河</param> /// <param name="indices">临近六边形</param> 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); // 第一个顶点位于邻居六边形内所以用weights2,第二三个顶点位于自身六边形所以用weights1 waterShore.AddTriangleCellData(indices, weights2, weights1, weights1); // 河口顶点 : e2: v1----v5 // e1: v2--v4 // 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); // 该UV的v用于判断离岸远近,u用于匹配瀑布水流消失插值(瀑布下方为1,扩散外围为0) 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) { // uv2 用于匹配河水流动, v为河水流动方向 // 由于是河口位于桥的下面,所以v坐标是0.8~1, // 由于水平面纯色区占比只有0.6,陆地水面交接处的桥是0.2+0.4,比陆地与陆地交接处的桥(0.2+0.2)大了50%,所以v坐标扩大50%,变成0.8~1.1 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)); } // 如果是流出河流的河口(翻转uv) 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)); } }
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, weights2, weights1, 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.3f), 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) ); } }
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; for (int i = 0; i < 4; i++) { 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); for (int i = 0; i < 4; i++) { 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); } }
public void TriangulateWaterShore(HexDirection dir, HexCell hexCell, HexCell neighbour, Vector3 center) { EdgeVertices edges1 = new EdgeVertices(center + HexMetrics.GetFirstWaterCorner(dir), center + HexMetrics.GetSecondWaterCorner(dir)); Water.AddTriangle(center, edges1.v1, edges1.v2); Water.AddTriangle(center, edges1.v2, edges1.v3); Water.AddTriangle(center, edges1.v3, edges1.v4); Water.AddTriangle(center, edges1.v4, edges1.v5); Vector3 indices = new Vector3(hexCell.CellIndex, hexCell.CellIndex, hexCell.CellIndex); Water.AddTriangleCellData(indices, Weights1); Water.AddTriangleCellData(indices, Weights1); Water.AddTriangleCellData(indices, Weights1); Water.AddTriangleCellData(indices, Weights1); Vector3 center2 = neighbour.Position; center2.y = center.y; if (neighbour.ColumnIndex < hexCell.ColumnIndex - 1) { center2.x += HexMetrics.WrapSize * HexMetrics.InnerDiameter; } else if (neighbour.ColumnIndex > hexCell.ColumnIndex + 1) { center2.x -= HexMetrics.WrapSize * HexMetrics.InnerDiameter; } Vector3 bridge = HexMetrics.GetWaterBridge(dir); EdgeVertices edges2 = new EdgeVertices(center2 + HexMetrics.GetSecondSolidCorner(dir.Opposite()), center2 + HexMetrics.GetFirstSolidCorner(dir.Opposite())); if (hexCell.HasRiverThroughEdge(dir)) { TriangulateEstuary(edges1, edges2, hexCell.IncomingRiverDirection == dir, indices); } else { WaterShore.AddQuad(edges1.v1, edges1.v2, edges2.v1, edges2.v2); WaterShore.AddQuad(edges1.v2, edges1.v3, edges2.v2, edges2.v3); WaterShore.AddQuad(edges1.v3, edges1.v4, edges2.v3, edges2.v4); WaterShore.AddQuad(edges1.v4, edges1.v5, edges2.v4, edges2.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 nextNeighbour = hexCell.GetNeighbour(dir.Next()); if (nextNeighbour != null) { Vector3 center3 = nextNeighbour.Position; if (nextNeighbour.ColumnIndex < hexCell.ColumnIndex - 1) { center3.x += HexMetrics.WrapSize * HexMetrics.InnerDiameter; } else if (nextNeighbour.ColumnIndex > hexCell.ColumnIndex + 1) { center3.x -= HexMetrics.WrapSize * HexMetrics.InnerDiameter; } Vector3 v3 = center3 + (nextNeighbour.IsUnderwater ? HexMetrics.GetFirstWaterCorner(dir.Previous()) : HexMetrics.GetFirstSolidCorner(dir.Previous())); v3.y = center.y; WaterShore.AddTriangle(edges1.v5, edges2.v5, v3); WaterShore.AddTriangleUV(new Vector2(0f, 0f), new Vector2(0f, 1f), new Vector2(0f, 0f)); WaterShore.AddTriangleCellData(indices, Weights1, Weights2, Weights3); } } }
/// <summary> /// 三角化沿岸水面扇形 /// </summary> /// <param name="direction">当前处理的扇形方向</param> /// <param name="cell">自身六边形</param> /// <param name="neighbor">邻居六边形</param> /// <param name="center">自身六边形中点</param> void TriangulateWaterShore(HexDirection direction, HexCell cell, HexCell neighbor, Vector3 center) { center.y = cell.WaterSurfaceY; Vector3 c1 = center + HexMetrics.GetFirstWaterCorner(direction); Vector3 c2 = center + HexMetrics.GetSecondWaterCorner(direction); EdgeVertices e1 = new EdgeVertices(c1, c2); // 三角化沿岸扇形 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 neighbor_center = neighbor.Position; neighbor_center.y = center.y; // 保持y与自身等高 // 得到邻居纯色区的弧(边) EdgeVertices e2 = new EdgeVertices(neighbor_center + HexMetrics.GetSecondSolidCorner(direction.Opposite()), neighbor_center + HexMetrics.GetFirstSolidCorner(direction.Opposite())); if (cell.HasRiverThroughEdge(direction)) { TriangulateEstuary(e1, e2, cell.HasIncomingRiver && 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(0, 0, 0, 1); // 陆地一侧v坐标为1 waterShore.AddQuadUV(0, 0, 0, 1); waterShore.AddQuadUV(0, 0, 0, 1); waterShore.AddQuadUV(0, 0, 0, 1); 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; // 保持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)); // 第三个顶点需要判断是在水面还是陆地,水面v为0,陆地用v为1 indices.z = nextNeighbor.Index; waterShore.AddTriangleCellData(indices, weights1, weights2, weights3); } }