使用Lua实现带有面和边界缘的模型的数据结构。

我正在制作一个具有不规则网格的游戏,我被推荐使用 Winged Edge 数据结构。阅读它所用于的内容似乎很直接,但我根本不知道如何实施。

我的最终目标是能够检测我点击了哪些面,以及哪些面邻接于被点击的面。有人能够可能指引我方向吗?

不规则网格设计

点赞
用户1190664
用户1190664

经过进一步的阅读和讨论,我成功地编写了一个非常不错的 Winged Edge 库。它是在 MIT 许可下发布的,所以如果有人想使用它,你随时欢迎!

https://github.com/karai17/Lua-Winged-Edge

它的工作方式如下:

Winged Edge 的关键特性在于每组数据都与其他组数据相关联。每个顶点列出与它相连的所有边,每条边列出连接的顶点和面,每个面列出连接的顶点和边。这种设计的有用性在下面将变得更加明显。

首先,我解析了一个 Wavefront Object 文件以获取顶点和面的列表。每个顶点都有 XYZ 坐标,每个面都有一个与之相连的顶点列表:

obj.vertices = {
    { x=0, y=0, z=0 },
    { x=1, y=0, z=0 },
    { x=1, y=1, z=0 },
    ...
}

obj.faces = {
    { 1, 2, 3 },
    { 1, 2, 4 },
    { 3, 4, 5, 6 },
    ...
}

然后,我为我的 Winged Edge(WE)对象创建了三个表:vertices、edges 和 faces。我解析了顶点,并创建了 WE 顶点:

WE.vertices = {
    { edges={}, position={ 0, 0, 0 } },
    { edges={}, position={ 1, 0, 0 } },
    ...
}

然后,我解析了面,创建了 WE edge 和 WE face,并填充了所有参考信息。边具有特殊情况,它们不仅参考它们连接到的面,还参考每个面的前一个和下一个边。这非常重要,因为它允许你遍历一个面的边来查找与当前的相邻面:

WE.vertices = {
    { edges={ 1, 2, 3 }, position={ 0, 0, 0 } },
    { edges={ 2, 3, 4 }, position={ 1, 0, 0 } },
    ...
}

WE.edges = {
    { vertices={ 1, 2 }, faces={ face=1, prev_edge=3, next_edge=2 } },
    { vertices={ 2, 3 }, faces={ face=1, prev_edge=1, next_edge=3 } },
    { vertices={ 3, 1 }, faces={ face=1, prev_edge=2, next_edge=1 } },
    ...
}

WE.faces = {
    { edges={ 1, 2, 3 }, vertices={ 1, 2, 3 } },
    { edges={ 2, 3, 4 }, vertices={ 2, 3, 4 } },
    ...
}

通过这种数据结构的设置,你可以创建一个函数来检查一条边属于哪些面,并通过这些边遍历来获取任何特定面相邻面的所有面,并且它们在空间中的位置。

我使用它来检查哪些面包围着我点击的面,以确定我是否可以根据某些游戏逻辑来激活该面,例如,是否已经激活了其中任何一个面。另一个用途是用于泛洪填充面。

有关精确执行等更多详细信息,欢迎查看以上链接中的代码。 :)

2014-05-28 19:24:32