/// <summary> /// 填充河道细胞中其他没有河道的顶面部分 /// 在此函数中处理河流和道路共存的情况 /// </summary> /// <param name="direction"></param> /// <param name="cell"></param> /// <param name="center"></param> /// <param name="e"></param> void TriangulateAdjacentToRiver(HexDirection direction, HexCell 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.GetSoliEdgeMiddle(direction) * (HexMetrics.innerToOuter * 0.5f); } else if (cell.HasRiverThroughEdge(direction.Previous2())) { //当前方向的前一个方向和后两个方向上都有河道 //就是笔直的河道,这是靠近前一个方向上的 center += HexMetrics.GetFirstSolidCorner(direction) * 0.25f; } } else if (cell.HasRiverThroughEdge(direction.Previous()) && cell.HasRiverThroughEdge(direction.Next2())) { //当前方向的后一个方向和前两个方向上都有河道 //就是笔直的河道,这是靠近后一个方向上的 center += HexMetrics.GetSecondSolidCorner(direction) * 0.25f; } EdgeVertices m = new EdgeVertices( Vector3.Lerp(center, e.v1, 0.5f), Vector3.Lerp(center, e.v5, 0.5f) ); TriangulateEdgeStrip(m, cell.Color, e, cell.Color); TriangulateEdgeFan(center, m, cell.Color); if (!cell.IsUnderwater && !cell.HasRoadThroughEdge(direction)) { features.AddFeature(cell, (center + e.v1 + e.v5) * (1f / 3f)); } }
/// <summary> /// 道路河流共存的时候 /// </summary> /// <param name="direction"></param> /// <param name="cell"></param> /// <param name="center"></param> /// <param name="e"></param> void TriangulateRoadAdjacentToRiver(HexDirection direction, HexCell 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) { //细胞中有河流的开始或结束 //中心点道路往河流的相反方向偏移1/3位置 roadCenter += HexMetrics.GetSoliEdgeMiddle(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.GetSecondSolidCorner(direction); } else { if (!hasRoadThroughEdge && !cell.HasRoadThroughEdge(direction.Previous())) { //河流截断道路后,如果一段没有连接的道路,将返回不在绘制 //即此中心如果是道路开头或结尾 //河流截断后一遍将不绘制对应面片 return; } corner = HexMetrics.GetFirstSolidCorner(direction); } roadCenter += corner * 0.5f; center += corner * 0.25f; } else if (cell.IncomingRiver == cell.OutgoingRiver.Previous()) { //之字型河流,即出和入河流是相邻的情况 //道路在河流汇合处偏移 roadCenter -= HexMetrics.GetSecondCorner(cell.IncomingRiver) * 0.2f; } else if (cell.IncomingRiver == cell.OutgoingRiver.Next()) { //之字型河流,即出和入河流是相邻的情况 //道路在河流汇合处偏移 roadCenter -= HexMetrics.GetFirstCorner(cell.IncomingRiver) * 0.2f; } else if (previousHasRiver && nextHasRiver) { //河流出入间隔一个单位的方向,即呈现弧形的河流,弧形内部的情况 if (!hasRoadThroughEdge) { //头尾部分,截断后多余部分返回不绘制 return; } Vector3 offset = HexMetrics.GetSoliEdgeMiddle(direction) * HexMetrics.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; } roadCenter += HexMetrics.GetSoliEdgeMiddle(middle) * 0.25f; } 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); //Debug.Log("Direction:" + direction); } if (nextHasRiver) { //当前方向的下一位方向存在河流时 //道路中心,中间的右点,和单元格中心之间添加一个三角形 TriangulateRoadEdge(roadCenter, mR, center); } }
/// <summary> /// 细胞中心河流河道的绘制方法 /// 有流入和有流出的情况 /// </summary> /// <param name="direction"></param> /// <param name="cell"></param> /// <param name="center"></param> /// <param name="e"></param> void TriangulateWithRiver(HexDirection direction, HexCell cell, Vector3 center, EdgeVertices e) { Vector3 centerL, centerR; if (cell.HasRiverThroughEdge(direction.Opposite())) { //通过前一个方向得到中心点往左偏移的位置 centerL = center + HexMetrics.GetFirstSolidCorner(direction.Previous()) * 0.25f; //通过下一个方向得到中心点往右偏移的位置 centerR = center + HexMetrics.GetSecondSolidCorner(direction.Next()) * 0.25f; } else if (cell.HasRiverThroughEdge(direction.Next())) { //同一个细胞中,如果当前方向相邻1个单位方向上有河道,那么相连处河道拓宽,让河流能通过 centerL = center; centerR = Vector3.Lerp(center, e.v5, 2f / 3f); } else if (cell.HasRiverThroughEdge(direction.Previous())) { //同一个细胞中,如果当前方向相邻1个单位方向上有河道,那么相连处河道拓宽,让河流能通过 centerL = Vector3.Lerp(center, e.v1, 2f / 3f); centerR = center; } else if (cell.HasRiverThroughEdge(direction.Next2())) { //同一个细胞中,如果当前方向相邻2个单位方向上有河道 centerL = center; centerR = center + HexMetrics.GetSoliEdgeMiddle(direction.Next()) * (0.5f * HexMetrics.innerToOuter); } else { //同一个细胞中,如果当前方向相邻2个单位方向上有河道 centerL = center + HexMetrics.GetSoliEdgeMiddle(direction.Previous()) * (0.5f * HexMetrics.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 = center.y = e.v3.y; TriangulateEdgeStrip(m, cell.Color, e, cell.Color); 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); if (!cell.IsUnderwater) { bool reversed = cell.IncomingRiver == direction; TriangulateRiverQuad(centerL, centerR, m.v2, m.v4, cell.RiverSurfaceY, 0.4f, reversed); TriangulateRiverQuad(m.v2, m.v4, e.v2, e.v4, cell.RiverSurfaceY, 0.6f, reversed); } }