4-12 阶梯连接区域的细分

  在上一章中,我们创建了对计算细分顶点与构建三角面片的方法进行了抽象,将这些步骤分别封装在了不同的结构体和方法中。在这一章中我们将使用这些方法,来进行阶梯连接区域的细分。
  要进行阶梯连接与其的细分,就需要把新的顶点信息传递到TriangulateEdgeTerraces方法中,在判断两个相邻地图单元连接方式为Slope时,进行阶梯状连接区域的构建。代码如下:

HexCell.cs
1
2
3
4
5
6
7
8
9
10
11
12
private void TriangulateConnection(HexDirection direction, HexCell cell, EdgeVertices e1)
{


if (cell.GetEdgeType(direction) == HexEdgeType.Slope)
{
//这里也使用EdgeVertices计算的顶点来构建矩形
TriangulateEdgeTerraces(e1.v1, e1.v4, cell, e2.v1, e2.v4, neighbor);
}


}

  接下来,要修改TriangulateEdgeTerraces方法的参数列表,新的参数是与阶梯连接区域相邻的两个边,而不是一组顶点。然后假设EdgeVertices里有插值计算函数,这就可以让我们简化TriangulateEdgeTerraces方法而不是使其变得更复杂。代码如下:

HexMesh.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/// <summary>
/// 构建阶梯状连接区域
/// 这里不再使用单一的顶点,而是直接使用cell与阶梯区域相连接的边,通过计算得出边上的顶点位置以及每个顶点的颜色
/// </summary>
/// <param name="begin">第一个cell与相邻阶梯化区域的边上顶点</param>
/// <param name="beginCell">第一个cell的实例</param>
/// <param name="end">第二个cell与相邻阶梯化区域的边上顶点</param>
/// <param name="endCell">第二个cell的实例</param>
private void TriangulateEdgeTerraces(EdgeVertices begin, HexCell beginCell, EdgeVertices end, HexCell endCell)
{
//通过插值计算出相邻cell边的每个坐标点
EdgeVertices e2 = EdgeVertices.TerraceLerp(begin, end, 1);
//通过插值计算出相邻cell边每个坐标点的颜色
Color c2 = HexMetrics.TerraceLerp(beginCell.color, endCell.color, 1);

//构建阶梯的第一段
TriangulateEdgeStrip(begin, beginCell.color, e2, c2);

//循环生成中间部分
for (int i = 2; i < HexMetrics.terraceSteps; i++)
{
EdgeVertices e1 = e2;
Color c1 = c2;
e2 = EdgeVertices.TerraceLerp(begin, end, i);
c2 = HexMetrics.TerraceLerp(beginCell.color, endCell.color, i);
TriangulateEdgeStrip(e1, c1, e2, c2);
}

//构建阶梯的最后一段
TriangulateEdgeStrip(e2, c2, end, endCell.color);
}

  最后,回到EdgeVertices.cs中,创建TerraceLerp方法,这个方法是使用插值计算阶梯连接区域中,每一段的顶点位置。代码如下:

EdgeVertices.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public struct EdgeVertices
{


/// <summary>
/// 通过两个cell的边,计算出阶梯连接区域,每一段上顶点的位置
/// </summary>
/// <param name="a">阶梯连接区域起始边</param>
/// <param name="b">姐弟连接区域结束边</param>
/// <param name="step">插值</param>
/// <returns>插值为step时,当前段落上每个顶点的位置信息</returns>
public static EdgeVertices TerraceLerp(EdgeVertices a, EdgeVertices b, int step)
{
EdgeVertices result;
result.v1 = HexMetrics.TerraceLerp(a.v1, b.v1, step);
result.v2 = HexMetrics.TerraceLerp(a.v2, b.v2, step);
result.v3 = HexMetrics.TerraceLerp(a.v3, b.v3, step);
result.v4 = HexMetrics.TerraceLerp(a.v4, b.v4, step);
return result;
}
}

  至此,我们就完成了经过细分之后阶梯连接区域的构建。在下一章中,我们将修复之前暂缓的斜面与阶梯连接区域破面的问题。

[Github代码](