#tile #mesh #collision #voxel #gamedev #convex-hull

soft-edge

从网格和堆叠的瓦片图中高效地创建3D碰撞网格的位操作技巧

5个版本

0.2.3 2021年12月2日
0.2.2 2021年11月28日
0.2.1 2021年11月28日
0.2.0 2021年11月27日
0.1.0 2021年11月26日

#1312 in 算法

MIT/Apache

67KB
967

Soft-Edge:从网格和堆叠的瓦片图中高效地创建3D碰撞网格的位操作技巧

难以理解的哭泣吉他声和磁带回声声 - Wata (Boris - Soft Edge)

soft-edge 是一个库,它提供处理3D网格的实用工具,其中单元格是作为单位立方体子集的凸包定义的碰撞体。

它提供的内容

  • Vertex,表示单位立方体的顶点,作为索引在 0..8
  • VertexSet,表示单位立方体顶点的子集,作为1字节位集
  • Atom,表示单位立方体顶点的有效凸非共面子集
  • CompoundHull,表示一个可剪切的凸包的复合体
  • HullFacet,表示一个可能被剪切的原子复合体的多边形。从原子的复合体计算出的船体面将始终按逆时针方向缠绕。

为什么?

如果你之前尝试过使用基于瓦片的地图构建游戏物理系统,你可能遇到过“裂缝问题”。这是指如果有两个相邻的瓦片,本应平滑地移动到它们之间的“裂缝”(从数学上讲,由于这两个瓦片的顶点是共享的,因此这个裂缝不存在),但物体却被卡在裂缝上,因为在碰撞检测过程中,物体被某种力量移入一个瓦片,并最终意外地与一个未暴露的边缘发生碰撞。

软边缘CompoundHull类型表示一种编码的瓦片碰撞器,它具有一个join_exteriors方法,可以消除两个瓦片之间任何未暴露的边缘,留下无法引起裂缝问题的表面多边形。此外,这些裁剪操作非常快,只需三个位操作(也许因为它们只在一个事物的子集上执行,所以可能需要更多,但仍然很快。)

它起作用吗?

嗯,我想应该是的。所有的测试都通过了,至少是这样?

这个包中的许多东西都是专门化/暴力破解/手写的查找表。我已经修复了我能找到的所有错误,但我确信还有更多的错误隐藏在某个地方,可能是在位标志或类似的错误中。尽管大多数位操作都是通过bitvec包来执行的,目的是尽可能地避免这种情况。

顶点编号

顶点按以下方式编号

  v3      v7
    *----*
v2 /| v6/|
  *----* |   +Y
  | *--|-*   ^ ^ +Z
  |/v1 |/v5  |/
  *----*     +--> +X
 v0    v4

为了方便起见,顶点索引和单位立方体坐标之间的转换

// v0 is the origin.
v0 <=> {0, 0, 0} <=> 0b000
v1 <=> {0, 0, 1} <=> 0b001
v2 <=> {0, 1, 0} <=> 0b010
v3 <=> {0, 1, 1} <=> 0b011
v4 <=> {1, 0, 0} <=> 0b100
v5 <=> {1, 0, 1} <=> 0b101
v6 <=> {1, 1, 0} <=> 0b110
v7 <=> {1, 1, 1} <=> 0b111

这是作为一个位表示形式 0bXYZ 得到的,其中X位表示X轴是否为1,Y位表示Y轴是否为1,等等。

顶点索引去重时的“精确”坐标

为了方便顶点去重(例如,对于索引三角形网格)起见,大多数输出坐标,如CompoundHull的片(HullFacet)都使用Exact类型表示。这封装了nalgebraPoint3<i32>,基本上只是您预期的相同坐标,但在每个轴上放大了2倍。这允许我们以无错误的方式表示面的质心,并且还提供了一个可哈希的类型,可以用来构建映射顶点到索引的集合。

一般来说,您期望我如何使用这个?

  1. 将您的碰撞图编码为字节网格,这些字节对应于有效的Atom。使用VertexSet::from_u8将字节反序列化为VertexSet,然后尝试使用Atom::try_new从它们构建原子。
  2. 构建一个由原子网格元素组成的CompoundHull的三维网格,然后对于网格中的每个水桶,在适当的轴上将其与邻居连接。
  3. 将这些连接的复合水桶的片提取为HullFacet,然后使用它们构建您的碰撞几何形状。这将最终形成一个非常非凸的网格,您可能需要将其分解为凸子网格(但不必这样做,如果您在多边形上直接进行碰撞,并且只允许穿过其“表面”侧的法线接触。)

软边缘试图生成具有正确 winding order(逆时针)的船体片,这应该允许您轻松计算它们的法线。如果不这样做,这是一个错误,必须修复。

许可证

根据以下之一授权

由您选择。

贡献

除非您明确声明,否则您根据 Apache-2.0 许可证定义的任何有意提交以包含在作品中并由您提交的贡献,应如上所述双重许可,不附加任何额外条款或条件。

依赖关系

~4.5MB
~99K SLoC