4-10 连接六边形边缘与连接区域边缘

  在上一章中,我们对每个六边形完成了细分,从之前的6个三角面片,增加到了18个三角面片。细节更加丰富。但是六边形边缘和其相邻的连接区域,还存在着破面与重面的问题,在这一章中,我们来修复这些问题。
  对矩形连接区域的细分也会用到新增的顶点信息,所以要将这些信息传递到TriangulateConnection方法中,代码如下:

HexMesh.cs
1
2
3
4
5
6
7
8
9
10
11
private void Triangulate(HexDirection direction, HexCell cell)
{


//因为对六边形的每个边进行了细分,所以要把新的顶点也传入构建矩形连接区域的方法中
//这样矩形区域使用新增的顶点后边缘之间才能吻合
if (direction <= HexDirection.SE)
{
TriangulateConnection(direction, cell, v1, e1, e2, v2);
}
}

  接着,我们要修改TriangulateConnection方法的参数列表,增加新的顶点参数,代码如下:

HexMesh.cs
1
2
3
4
5
6
7
//六边形增加了新的顶点,这里要修改参数列表,接收新的顶点
private void TriangulateConnection(
HexDirection direction, HexCell cell,
Vector3 v1, Vector3 e1, Vector3 e2, Vector3 v2)
{

}

  我们还需要计算与这个矩形连接区域相邻的另一个地图单元上的新增顶点信息。代码如下:

HexMesh.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private void TriangulateConnection(
HexDirection direction, HexCell cell,
Vector3 v1, Vector3 e1, Vector3 e2, Vector3 v2)
{


Vector3 v3 = v1 + bridge;
Vector3 v4 = v2 + bridge;
v3.y = v4.y = neighbor.Position.y;

//这里要计算与矩形连接区域相邻的,另一侧cell新增的两个顶点位置信息
Vector3 e3 = Vector3.Lerp(v3, v4, 1f / 3f);
Vector3 e4 = Vector3.Lerp(v3, v4, 2f / 3f);


}

  最后,我们使用新的顶点信息构建矩形连接区域,这里我们先忽略阶梯化的问题,先解决在同一平面下不产生破面与重叠。代码如下:

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
private void TriangulateConnection(
HexDirection direction, HexCell cell,
Vector3 v1, Vector3 e1, Vector3 e2, Vector3 v2)
{


if (cell.GetEdgeType(direction) == HexEdgeType.Slope)
{
TriangulateEdgeTerraces(v1, v2, cell, v3, v4, neighbor);
}
else
{
//这里使用新增的顶点进行连接区域的构建
AddQuad(v1, e1, v3, e3);
AddQuadColor(cell.color, neighbor.color);
AddQuad(e1, e2, e3, e4);
AddQuadColor(cell.color, neighbor.color);
AddQuad(e2, v2, e4, v4);
AddQuadColor(cell.color, neighbor.color);
}


}

  至此我们就完成了地图单元与矩形连接区域产生破面与重面的问题。不过现在只是两个地图单元在相同高度的情况,阶梯化之后仍然存在问题。我们先将阶梯化的问题暂缓,现在我们为TriangulateConnection方法增加了参数,在方法内还要计算相邻地图单元一条边上的两个顶点,这样看来不太符合面向对象的思想。接下来我们会将这些计算过程进行封装,对现有的一些方法进行简化。

Github代码