public void TriangulateOpenWater(HexDirection dir, HexCell cell, HexCell neighbour, Vector3 center) { Vector3 c1 = center + HexMetrics.GetFirstWaterCorner(dir); Vector3 c2 = center + HexMetrics.GetSecondWaterCorner(dir); Water.AddTriangle(center, c1, c2); Vector3 indices = new Vector3(cell.CellIndex, cell.CellIndex, cell.CellIndex); Water.AddTriangleCellData(indices, Weights1); if (dir <= HexDirection.SE && neighbour != null) { Vector3 bridge = HexMetrics.GetWaterBridge(dir); Vector3 e1 = c1 + bridge; Vector3 e2 = c2 + bridge; Water.AddQuad(c1, c2, e1, e2); indices.y = neighbour.CellIndex; Water.AddQuadCellData(indices, Weights1, Weights2); if (dir <= HexDirection.E) { HexCell nextNeightbour = cell.GetNeighbour(dir.Next()); if (nextNeightbour == null || !nextNeightbour.IsUnderwater) { return; } Water.AddTriangle(c2, e2, c2 + HexMetrics.GetWaterBridge(dir.Next())); indices.z = nextNeightbour.CellIndex; Water.AddTriangleCellData(indices, Weights1, Weights2, Weights3); } } }
private void TriangulateOpenWater(HexDirection dir, HexCell cell, HexCell neighbor, Vector3 center) { var c1 = center + HexMetrics.GetFirstWaterCorner(dir); var c2 = center + HexMetrics.GetSecondWaterCorner(dir); water.AddTriangle(center, c1, c2); var indices = new Vector3(cell.Index, cell.Index, cell.Index); water.AddTriangleCellData(indices, weights1); if (dir <= HexDirection.SE && neighbor != null) { var bridge = HexMetrics.GetWaterBridge(dir); var e1 = c1 + bridge; var e2 = c2 + bridge; water.AddQuad(c1, c2, e1, e2); indices.y = neighbor.Index; water.AddQuadCellData(indices, weights1, weights2); if (dir <= HexDirection.E) { var nextNeighbor = cell.GetNeighbor(dir.Next()); if (nextNeighbor == null || !nextNeighbor.IsUnderwater) { return; } water.AddTriangle(c2, e2, c2 + HexMetrics.GetWaterBridge(dir.Next())); indices.z = nextNeighbor.Index; water.AddTriangleCellData(indices, weights1, weights2, weights3); } } }
void TriangulateOpenWater(HexDirection direction, HexCell cell, HexCell neighbor, Vector3 center) { Vector3 c1 = center + HexMetrics.GetFirstWaterCorner(direction); Vector3 c2 = center + HexMetrics.GetSecondWaterCorner(direction); water.AddTriangle(center, c1, c2); if (direction <= HexDirection.SE && neighbor != null) { Vector3 bridge = HexMetrics.GetWaterBridge(direction); Vector3 e1 = c1 + bridge; Vector3 e2 = c2 + bridge; water.AddQuad(c1, c2, e1, e2); if (direction <= HexDirection.E) { HexCell nextNeighbor = cell.GetNeighbor(direction.Next()); if (nextNeighbor == null || !nextNeighbor.IsUnderwater) { return; } water.AddTriangle(c2, e2, c2 + HexMetrics.GetWaterBridge(direction.Next())); } } }
private 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); // Use water edge on the water side and solid edge on the land // side. 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); } 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); // Put the information about the shore on the V coordinate. // Set it to 0 on the water side, and to 1 on the land side. 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 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)); } }
void TriangulateWaterShore(HexDirection direction, HexCell cell, HexCell neighbor, Vector3 center) { //center hex expansion 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); //bridge 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); } 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); //UVS waterShore.AddQuadUV(0f, 0f, 0f, 1f); waterShore.AddQuadUV(0f, 0f, 0f, 1f); waterShore.AddQuadUV(0f, 0f, 0f, 1f); waterShore.AddQuadUV(0f, 0f, 0f, 1f); } //fill corners between bridges and hexs 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); //UV waterShore.AddTriangleUV( new Vector2(0f, 0f), new Vector2(0f, 1f), new Vector2(0f, nextNeighbor.IsUnderWater ? 0f : 1f)); } }
public void secondWaterCornerTest() { Vector3 corner = new Vector3(HexMetrics.innerRadius, 0f, 0.5f * HexMetrics.outerRadius); Vector3 expected = corner * HexMetrics.waterFactor; HexDirection direction = HexDirection.NE; Vector3 actual = HexMetrics.GetSecondWaterCorner(direction); Assert.AreEqual(expected, actual); }
//水体的边缘 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); //add bridge //Vector3 bridge = HexMetrics.GetWaterBridge(direction); Vector3 center2 = neighbor.Position; center2.y = center.y; EdgeVertices e2 = new EdgeVertices( center2 + HexMetrics.GetSecondSolidCorner(direction.Opposite()), center2 + HexMetrics.GetFirstSolidCorner(direction.Opposite()) ); //河岸direction方向有river进 if (cell.HasRiverThroughEdge(direction)) { TriangulateEstuary(e1, e2, cell.IncomingRiver == direction); } //如果没有river进入水体 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); } //add triangle 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)); } }
/// <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) { // 为匹配岸基网格,将边界位置进行扰动 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 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); } 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 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) ); } }
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 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)) { //计算水面跟河流的交点 float factor = (cell.WaterSurfaceY - cell.RiverSurfaceY) / (neighbor.RiverSurfaceY - cell.RiverSurfaceY); factor = factor * (1 - HexMetrics.kSolidFactor) * 2 / (2 - HexMetrics.kWaterFactor - HexMetrics.kSolidFactor) + (HexMetrics.kSolidFactor - HexMetrics.kWaterFactor) / (2 - HexMetrics.kWaterFactor - HexMetrics.kSolidFactor); TriangulateEstuary(e1, e2, cell.IncomingRiver == direction, factor); } 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 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) ); } }
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 center2 = neighbor.Position; center2.y = center.y; EdgeVertices e2 = new EdgeVertices( center2 + HexMetrics.GetSecondSolidCorner(direction.Opposite()), center2 + HexMetrics.GetFirstSolidCorner(direction.Opposite()) ); 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 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) ); } }
/// <summary> /// Creates geometry for open water (no land neighbors). /// </summary> void TriangulateOpenWater(HexDirection direction, HexCell cell, HexCell neighbor, Vector3 center) { // Careful to find the WATER corner not the solid corner // Careful to get the WATER bridge Vector3 c1 = center + HexMetrics.GetFirstWaterCorner(direction); Vector3 c2 = center + HexMetrics.GetSecondWaterCorner(direction); Water.AddTriangle(center, c1, c2); Vector3 indices; indices.x = indices.y = indices.z = cell.Index; Water.AddTriangleCellData(indices, weights1); if (direction <= HexDirection.SE && neighbor != null) { Vector3 bridge = HexMetrics.GetWaterBridge(direction); Vector3 e1 = c1 + bridge; Vector3 e2 = c2 + bridge; Water.AddQuad(c1, c2, e1, e2); indices.y = neighbor.Index; Water.AddQuadCellData(indices, weights1, weights2); // The tripple connection triangle for water surface if (direction <= HexDirection.E) { HexCell nextNeighbor = cell.GetNeighbor(direction.Next()); if (nextNeighbor == null || !nextNeighbor.IsUnderwater) { return; } Water.AddTriangle(c2, e2, c2 + HexMetrics.GetWaterBridge(direction.Next())); indices.z = nextNeighbor.Index; Water.AddTriangleCellData(indices, weights1, weights2, weights3); } } }
/// <summary> /// 三角化开阔水体单元 /// </summary> /// <param name="direction"></param> /// <param name="cell"></param> /// <param name="neighbor"></param> /// <param name="center"></param> void TriangulateOpenWater(HexDirection direction, HexCell cell, HexCell neighbor, Vector3 center) { Vector3 c1 = center + HexMetrics.GetFirstWaterCorner(direction); Vector3 c2 = center + HexMetrics.GetSecondWaterCorner(direction); water.AddTriangle(center, c1, c2); Vector3 indices; indices.x = indices.y = indices.z = cell.Index; water.AddTriangleCellData(indices, weights1); if (direction <= HexDirection.SE && neighbor != null) { //HexCell neighbor = cell.GetNeighbor(direction); //if (neighbor == null || !neighbor.IsUnderwater) //{ // return; //} Vector3 bridge = HexMetrics.GetWaterBridge(direction); Vector3 e1 = c1 + bridge; Vector3 e2 = c2 + bridge; water.AddQuad(c1, c2, e1, e2); indices.y = neighbor.Index; water.AddQuadCellData(indices, weights1, weights2); if (direction <= HexDirection.E) { HexCell nextNeighbor = cell.GetNeighbor(direction.Next()); if (nextNeighbor == null || !nextNeighbor.IsUnderwater) { return; } water.AddTriangle(c2, e2, c2 + HexMetrics.GetWaterBridge(direction.Next())); indices.z = nextNeighbor.Index; water.AddTriangleCellData(indices, weights1, weights2, weights3); } } }
private 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; water.AddTriangleCellData(indices, weights1); water.AddTriangleCellData(indices, weights1); water.AddTriangleCellData(indices, weights1); 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); 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; 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); } }
/// <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); } }
/// <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); } }
private void TriangulateWaterShore(HexDirection dir, HexCell cell, HexCell neighbor, Vector3 center) { var e1 = new EdgeVertices( center + HexMetrics.GetFirstWaterCorner(dir), center + HexMetrics.GetSecondWaterCorner(dir) ); 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); var indices = new Vector3(cell.Index, neighbor.Index, cell.Index); water.AddTriangleCellData(indices, weights1); water.AddTriangleCellData(indices, weights1); water.AddTriangleCellData(indices, weights1); water.AddTriangleCellData(indices, weights1); var 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; var e2 = new EdgeVertices( center2 + HexMetrics.GetSecondSolidCorner(dir.Opposite()), center2 + HexMetrics.GetFirstSolidCorner(dir.Opposite()) ); if (cell.HasRiverThroughEdge(dir)) { TriangulateEstuary(e1, e2, cell.HasIncomingRiver && cell.IncomingRiver == dir, 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 nextNeighbor = cell.GetNeighbor(dir.Next()); if (nextNeighbor != null) { var 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; } var v3 = center3 + (nextNeighbor.IsUnderwater ? HexMetrics.GetFirstWaterCorner(dir.Previous()) : HexMetrics.GetFirstSolidCorner(dir.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); } } }
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; water.AddTriangleCellData(indices, weights1); water.AddTriangleCellData(indices, weights1); water.AddTriangleCellData(indices, weights1); water.AddTriangleCellData(indices, weights1); 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); } 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); } 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; } 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) ); indices.z = nextNeighbor.Index; waterShore.AddTriangleCellData(indices, weights1, weights2, weights3); } }