3-7 矩形连接区域阶梯化

  在上一章中,我们创建了计算阶梯连接区域中各个顶点位置和颜色的方法。在这一章中,我们要使用这些方法对矩形连接区域进行三角剖分。计算出矩形连接区域阶梯化后各个顶点的位置和颜色。
  首先,我们回到HexMesh.TriangulateConnection方法中,我们注释掉关于构建矩形连接区域,并为其顶点赋值颜色的代码。取代这部分代码的是一个新阶梯化连接区域的方法。

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


//进行矩形颜色混合区域的三角面片构建和赋值顶点颜色
//AddQuad(v1, v2, v3, v4);
//AddQuadColor(cell.color, neighbor.color);
//以上方法注释掉,使用新的 TriangulateEdgeTerraces 进行替换
TriangulateEdgeTerraces(v1, v2, cell, v3, v4, neighbor);


}

/// <summary>
/// 阶梯化连接区域
/// </summary>
/// <param name="beginLeft">cell到neighbor连接区域的第一个起点</param>
/// <param name="beginRight">cell到neighbor连接区域的第二个起点</param>
/// <param name="beginCell">cell自身实例,用于获取颜色</param>
/// <param name="endLeft">连接区域 连接到的neighbor的第一个终点</param>
/// <param name="endRight">连接区域 连接到的neighbor的第二个终点</param>
/// <param name="endCell">连接到的neighbor实例,用于获取颜色</param>
private void TriangulateEdgeTerraces(
Vector3 beginLeft, Vector3 beginRight, HexCell beginCell,
Vector3 endLeft, Vector3 endRight, HexCell endCell
)
{
AddQuad(beginLeft, beginRight, endLeft, endRight);
AddQuadColor(beginCell.color, endCell.color);
}

  根据上一章中使用插值进行阶梯化的思路,这里先构建阶梯的第一个面。

HexCell.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
private void TriangulateEdgeTerraces(
Vector3 beginLeft, Vector3 beginRight, HexCell beginCell,
Vector3 endLeft, Vector3 endRight, HexCell endCell
)
{
//这里先生成阶梯的第一个矩形面片。通过给定插值来计算出矩形面片的另外两个顶点
Vector3 v3 = HexMetrics.TerraceLerp(beginLeft, endLeft, 1);
Vector3 v4 = HexMetrics.TerraceLerp(beginRight, endRight, 1);
Color c2 = HexMetrics.TerraceLerp(beginCell.color, endCell.color, 1);

AddQuad(beginLeft, beginRight, v3, v4);
AddQuadColor(beginCell.color, c2);
}

  生成第一个阶梯面片后,我们直接跳过中间步骤,将剩余部分用一个矩形面片连接起来。

HexMesh.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private void TriangulateEdgeTerraces(
Vector3 beginLeft, Vector3 beginRight, HexCell beginCell,
Vector3 endLeft, Vector3 endRight, HexCell endCell
)
{
//这里先生成阶梯的第一个矩形面片。通过给定插值来计算出矩形面片的另外两个顶点
Vector3 v3 = HexMetrics.TerraceLerp(beginLeft, endLeft, 1);
Vector3 v4 = HexMetrics.TerraceLerp(beginRight, endRight, 1);
Color c2 = HexMetrics.TerraceLerp(beginCell.color, endCell.color, 1);

AddQuad(beginLeft, beginRight, v3, v4);
AddQuadColor(beginCell.color, c2);

//连接阶梯的剩余区域
AddQuad(v3, v4, endLeft, endRight);
AddQuadColor(c2, endCell.color);
}

  通过观察3-6章的示意图可以发现,除了阶梯的第一个矩形面片和最后的连接区域,其余部分可以通过一个循环来生成。思路就是将通过插值计算得出的两个顶点,作为下一个矩形面片的起始点,利用插值再计算出新矩形面片的两个终点。计算颜色也是这个思路。

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
private void TriangulateEdgeTerraces(
Vector3 beginLeft, Vector3 beginRight, HexCell beginCell,
Vector3 endLeft, Vector3 endRight, HexCell endCell
)
{


AddQuad(beginLeft, beginRight, v3, v4);
AddQuadColor(beginCell.color, c2);

//阶梯的其他矩形面片,可以通过循环来生成
//旧的矩形面片终点V3 V4,就是新面片的起点 V1 V2
//然后再利用插值计算新面片的终点即可
//颜色计算同理
for (int i = 2; i < HexMetrics.terraceSteps; i++)
{
Vector3 v1 = v3;
Vector3 v2 = v4;
Color c1 = c2;
v3 = HexMetrics.TerraceLerp(beginLeft, endLeft, i);
v4 = HexMetrics.TerraceLerp(beginRight, endRight, i);
c2 = HexMetrics.TerraceLerp(beginCell.color, endCell.color, i);
AddQuad(v1, v2, v3, v4);
AddQuadColor(c1, c2);
}

//连接阶梯的剩余区域
AddQuad(v3, v4, endLeft, endRight);
AddQuadColor(c2, endCell.color);
}

  这样,我们就将之前的矩形连接区域转换成了阶梯状连接区域。并且可以自定义阶梯的段数。但是我们发现一个问题,就是在两个高度相同的地图单元之间,也进行了不必要的阶梯化,这样就产生了多于的三角面。在下一章中,我们会将高度进行分类,从而解决这个问题。

Github代码