3-17 双Cliff类型三角形连接区域构建

  在上一章中,我们完成了SSFSlope-Cliff两种连接类型及其变体的三角形连接区域的构建。现在我们来完成最后一种情况,也就是最低的bottom地图单元与left和right地图单元的高度差都大于1,并且left和right地图单元的高度差为1,这种组合类型。我们将这种组合命名为Cliff-Cliff-Slope类型,简写为CCS。而且由于lefr和right两个地图单元之间高度差为1,如果right地图单元比较高,就简写为CCSR类型,如果left地图单元比较高,就简写为CCSL类型。CCSR类型和CCSL类型分别如下图所示:

  我们对这两种组合的抽象表示如下图所示:

  其实细心挂差可以发现,不论是CCSL或者CCSR,它们与Slope-Cliff类型及其镜像是上下翻转的。这里我们只需要继续调用TriangulateCornerCliffTerracesTriangulateCornerTerracesCliff方法进行三角面片的构建就可以了。我们需要做的只是判断连接类型,并且确认输入参数顺序正确即可。代码如下:

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
private void TriangulateCorner(
Vector3 bottom, HexCell bottomCell,
Vector3 left, HexCell leftCell,
Vector3 right, HexCell rightCell)
{


//bottom最低,与left和right高差都大于1,并且left和right高差为1,称为 CCS类型
//如果left比right高1,那么就是CCSL,反之right比left高1,那就是CCSR
if (leftCell.GetEdgeType(rightCell) == HexEdgeType.Slope)
{
//CCSR
if (leftCell.Elevation < rightCell.Elevation)
{
TriangulateCornerCliffTerraces(right, rightCell, bottom, bottomCell, left, leftCell);
}
//CCSL
else
{
TriangulateCornerTerracesCliff(left, leftCell, right, rightCell, bottom, bottomCell);
}
return;
}


}

  我们虽然完成了CCSLCCSR两种类型的三角形连接区域的构建,但是通过观察运行效果我们发现会产生一些奇怪的三角面片,这是因为我们之前计算插值的时候,都是从上到下进行的,现在上下翻转之后,计算的结果为负数,所以就构建出了奇怪的三角面片。解决这个问题也很简单,就是在计算插值之前,先判断结果是否为负数,如果是负数,那就乘以`-1``变为正数即可。代码如下:

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
private void TriangulateCornerTerracesCliff(
Vector3 begin, HexCell beginCell,
Vector3 left, HexCell leftCell,
Vector3 right, HexCell rightCell)
{
float b = 1f / (rightCell.Elevation - beginCell.Elevation);
if (b < 0)
{
b = -b;
}


}

private void TriangulateCornerTerracesCliff(
Vector3 begin, HexCell beginCell,
Vector3 left, HexCell leftCell,
Vector3 right, HexCell rightCell)
{
float b = 1f / (leftCell.Elevation - beginCell.Elevation);
if (b < 0)
{
b = -b;
}


}

  这样,我们就完成了最后一个组合类型的三角形连接区域的构建,CCSR类型和CCSL类型完成后分别如下图所示:

 最后还有一种情况,就是三个相邻的地图单元,彼此之间的高度差都大于1,那么他们的三角形连接区域其实就是默认的三角形。

 至此我们已经将所有类型的三角形连接区域构建方法完成了,但是在TriangulateCorner方法中,冗余的判断代码还是比较多的。下一章中,我们将对TriangulateCorner方法中,判断连接类型的代码进行一定的整理和优化,为之后的其他功能做准备。

Github代码