//传入六边形的一个方向,渲染这个方向相关的Mesh void Triangulate(HexDirection d, HexCell cell) { Vector3 center = cell.Position; Vector3 v1 = center + HexMetrics.GetFirstSolidCornet(d); Vector3 v2 = center + HexMetrics.GetSecondSolidCornet(d); //将三角形细分为三分,以便于更好地随机化 //e1,e2,e3皆为本方顶点 Vector3 e1 = Vector3.Lerp(v1, v2, 0.25f); Vector3 e2 = Vector3.Lerp(v1, v2, 0.5f); Vector3 e3 = Vector3.Lerp(v1, v2, 0.75f); if (cell.HasRiver) { if (cell.HasRiverThroughEdge(d)) { e2.y = cell.StreamBedY; TriangulateWithRiver(d, cell, center, v1, e1, e2, e3, v2); } else { TriangulatAdjacentToRiver(d, cell, center, v1, e1, e2, e3, v2); } } else { //内部三角形,颜色为纯色 AddTriangle4(center, v1, e1, e2, e3, v2, cell.Color); } TriangulateConnection(d, cell, v1, e1, e2, e3, v2); }
//仅当河道中存在河道时才会调用 //绘制河道 void TriangulateWithRiver(HexDirection direction, HexCell cell, Vector3 center, Vector3 v1, Vector3 e1, Vector3 e2, Vector3 e3, Vector3 v2) { //如果为河流的尽头,则仅仅弯下去一个角,其他角不受影响 if (cell.HasRiverBeginOrEnd) { Vector3 centerRiver = center; centerRiver.y = cell.StreamBedY; float lerpVal = 0.5f; Vector3 mL = Vector3.Lerp(v1, center, lerpVal); Vector3 mR = Vector3.Lerp(v2, center, lerpVal); Vector3 m1 = Vector3.Lerp(e1, center, lerpVal); Vector3 m2 = Vector3.Lerp(e2, centerRiver, lerpVal); Vector3 m3 = Vector3.Lerp(e3, center, lerpVal); AddTrapezoid(mL, m1, m2, m3, mR, v1, e1, e2, e3, v2, cell.Color); AddTriangle4(center, mL, m1, m2, m3, mR, cell.Color); } //如果是直线穿过的河流,则将六边形中间挖一个类似矩形的空间,会影响几乎所有的角 else if (cell.RiverState == riverState.Dif3) { Vector3 cL = center + HexMetrics.GetFirstSolidCornet(direction.Previous()) * 0.25f; Vector3 cR = center + HexMetrics.GetSecondSolidCornet(direction.Next()) * 0.25f; center.y = cell.StreamBedY; float lerpVal = 0.5f; Vector3 mL = Vector3.Lerp(v1, cL, lerpVal); Vector3 mR = Vector3.Lerp(v2, cR, lerpVal); Vector3 m1 = Vector3.Lerp(e1, cL, lerpVal); Vector3 m2 = Vector3.Lerp(e2, center, lerpVal); Vector3 m3 = Vector3.Lerp(e3, cR, lerpVal); AddTrapezoid(mL, m1, m2, m3, mR, v1, e1, e2, e3, v2, cell.Color); AddTrapezoid(cL, cL, center, cR, cR, mL, m1, m2, m3, mR, cell.Color); } //一度只差 else if (cell.RiverState == riverState.Dif1) { if (cell.HasRiverThroughEdge(direction.Previous())) { Vector3 c1 = Vector3.Lerp(v1, center, 2 / 3f); c1.y = cell.StreamBedY; Vector3 c2 = Vector3.Lerp(v1, center, 1 / 3f); Vector3 c3 = Vector3.Lerp(v1, center, 1 / 5f); Vector3 leftMid = Vector3.Lerp(v2, center, 0.5f); Vector3 m1 = Vector3.Lerp(e3, center, 0.5f); Vector3 m2 = Vector3.Lerp(e2, c1, 0.5f); Vector3 m3 = Vector3.Lerp(e1, c2, 0.5f); AddTrapezoid(c3, m3, m2, m1, leftMid, v1, e1, e2, e3, v2, cell.Color); AddTriangle(m1, leftMid, center, cell.Color); AddQuad(c1, center, m2, m1, cell.Color); AddQuad(c2, c1, m3, m2, cell.Color); AddTriangle(c3, m3, c2, cell.Color); } else if (cell.HasRiverThroughEdge(direction.Next())) { Vector3 c1 = Vector3.Lerp(v2, center, 2 / 3f); c1.y = cell.StreamBedY; Vector3 c2 = Vector3.Lerp(v2, center, 1 / 3f); Vector3 c3 = Vector3.Lerp(v2, center, 1 / 5f); Vector3 rightMid = Vector3.Lerp(v1, center, 0.5f); Vector3 m1 = Vector3.Lerp(e1, center, 0.5f); Vector3 m2 = Vector3.Lerp(e2, c1, 0.5f); Vector3 m3 = Vector3.Lerp(e3, c2, 0.5f); AddTrapezoid(rightMid, m1, m2, m3, c3, v1, e1, e2, e3, v2, cell.Color); AddTriangle(m1, center, rightMid, cell.Color); AddQuad(m2, m1, c1, center, cell.Color); AddQuad(m3, m2, c2, c1, cell.Color); AddTriangle(c3, c2, m3, cell.Color); } } //两度只差 else if (cell.RiverState == riverState.Dif2) { if (cell.HasRiverThroughEdge(direction.Previous2())) { Vector3 cL = Vector3.Lerp(center + HexMetrics.GetFirstSolidCornet(direction.Previous()) * 0.5f, center + HexMetrics.GetSecondSolidCornet(direction.Previous()) * 0.5f, 0.5f); Vector3 cR = Vector3.Lerp(center + HexMetrics.GetFirstSolidCornet(direction.Next2()) * 0.25f, center + HexMetrics.GetSecondSolidCornet(direction.Next2()) * 0.25f, 0.5f); center.y = cell.StreamBedY; Vector3 mL = Vector3.Lerp(cL, v1, 0.5f); Vector3 mR = Vector3.Lerp(cR, v2, 0.5f); Vector3 m1 = Vector3.Lerp(cL, e1, 0.5f); Vector3 m2 = Vector3.Lerp(center, e2, 0.5f); Vector3 m3 = Vector3.Lerp(cR, e3, 0.5f); AddTrapezoid(mL, m1, m2, m3, mR, v1, e1, e2, e3, v2, cell.Color); AddTrapezoid(cL, cL, center, cR, cR, mL, m1, m2, m3, mR, cell.Color); } else if (cell.HasRiverThroughEdge(direction.Next2())) { Vector3 cL = Vector3.Lerp(center + HexMetrics.GetFirstSolidCornet(direction.Previous2()) * 0.25f, center + HexMetrics.GetSecondSolidCornet(direction.Previous2()) * 0.25f, 0.5f); Vector3 cR = Vector3.Lerp(center + HexMetrics.GetFirstSolidCornet(direction.Next()) * 0.5f, center + HexMetrics.GetSecondSolidCornet(direction.Next()) * 0.5f, 0.5f); center.y = cell.StreamBedY; Vector3 mL = Vector3.Lerp(cL, v1, 0.5f); Vector3 mR = Vector3.Lerp(cR, v2, 0.5f); Vector3 m1 = Vector3.Lerp(cL, e1, 0.5f); Vector3 m2 = Vector3.Lerp(center, e2, 0.5f); Vector3 m3 = Vector3.Lerp(cR, e3, 0.5f); AddTrapezoid(mL, m1, m2, m3, mR, v1, e1, e2, e3, v2, cell.Color); AddTrapezoid(cL, cL, center, cR, cR, mL, m1, m2, m3, mR, cell.Color); } } }
//补全空缺 void TriangulatAdjacentToRiver(HexDirection direction, HexCell cell, Vector3 center, Vector3 v1, Vector3 e1, Vector3 e2, Vector3 e3, Vector3 v2) { //尽头或源头的情况 if (cell.HasRiverBeginOrEnd) { if (cell.HasRiverThroughEdge(direction.Previous())) { Vector3 leftMid = Vector3.Lerp(center, v1, 0.5f); TriangulatAdjacentToRiverLeft(center, v1, e1, e2, e3, v2, cell.Color, leftMid); } else if (cell.HasRiverThroughEdge(direction.Next())) { Vector3 rightMid = Vector3.Lerp(center, v2, 0.5f); TriangulatAdjacentToRiverRight(center, v1, e1, e2, e3, v2, cell.Color, rightMid); } else { AddTriangle4(center, v1, e1, e2, e3, v2, cell.Color); } } //平直流过 else if (cell.RiverState == riverState.Dif3) { if (cell.HasRiverThroughEdge(direction.Previous())) { Vector3 centerX = center + HexMetrics.GetSecondSolidCornet(direction) * 0.25f; Vector3 leftMid = Vector3.Lerp(centerX, v1, 0.5f); TriangulatAdjacentToRiverLeft(centerX, v1, e1, e2, e3, v2, cell.Color, leftMid); } else if (cell.HasRiverThroughEdge(direction.Next())) { Vector3 centerX = center + HexMetrics.GetFirstSolidCornet(direction) * 0.25f; Vector3 rightMid = Vector3.Lerp(centerX, v2, 0.5f); TriangulatAdjacentToRiverRight(centerX, v1, e1, e2, e3, v2, cell.Color, rightMid); } } //锐角转弯 else if (cell.RiverState == riverState.Dif1) { if (cell.HasRiverThroughEdge(direction.Previous())) { Vector3 leftMid = Vector3.Lerp(center, v1, 0.5f); TriangulatAdjacentToRiverLeft(center, v1, e1, e2, e3, v2, cell.Color, leftMid); } else if (cell.HasRiverThroughEdge(direction.Next())) { Vector3 rightMid = Vector3.Lerp(center, v2, 0.5f); TriangulatAdjacentToRiverRight(center, v1, e1, e2, e3, v2, cell.Color, rightMid); } else { AddTriangle4(center, v1, e1, e2, e3, v2, cell.Color); } } //平缓转弯 else if (cell.RiverState == riverState.Dif2) { if (cell.HasRiverThroughEdge(direction.Previous()) && cell.HasRiverThroughEdge(direction.Next())) { Vector3 centerX = Vector3.Lerp(center + HexMetrics.GetFirstSolidCornet(direction) * 0.5f, center + HexMetrics.GetSecondSolidCornet(direction) * 0.5f, 0.5f); Vector3 mL = Vector3.Lerp(v1, centerX, 0.5f); Vector3 m1 = Vector3.Lerp(e1, centerX, 0.5f); Vector3 m2 = Vector3.Lerp(e2, centerX, 0.5f); Vector3 m3 = Vector3.Lerp(e3, centerX, 0.5f); Vector3 mR = Vector3.Lerp(v2, centerX, 0.5f); AddTriangle4(centerX, mL, m1, m2, m3, mR, cell.Color); AddTrapezoid(mL, m1, m2, m3, mR, v1, e1, e2, e3, v2, cell.Color); } else if (cell.HasRiverThroughEdge(direction.Previous())) { Vector3 centerX = Vector3.Lerp(center + HexMetrics.GetFirstSolidCornet(direction.Next()) * 0.25f, center + HexMetrics.GetSecondSolidCornet(direction.Next()) * 0.25f, 0.5f); Vector3 leftMid = Vector3.Lerp(v1, centerX, 0.5f); TriangulatAdjacentToRiverLeft(centerX, v1, e1, e2, e3, v2, cell.Color, leftMid); } else if (cell.HasRiverThroughEdge(direction.Next())) { Vector3 centerX = Vector3.Lerp(center + HexMetrics.GetFirstSolidCornet(direction.Previous()) * 0.25f, center + HexMetrics.GetSecondSolidCornet(direction.Previous()) * 0.25f, 0.5f); Vector3 rightMid = Vector3.Lerp(v2, centerX, 0.5f); TriangulatAdjacentToRiverRight(centerX, v1, e1, e2, e3, v2, cell.Color, rightMid); } else { Vector3 centerX = Vector3.Lerp(center + HexMetrics.GetFirstSolidCornet(direction) * 0.25f, center + HexMetrics.GetSecondSolidCornet(direction) * 0.25f, 0.5f); AddTriangle4(centerX, v1, e1, e2, e3, v2, cell.Color); } } }