//Description: V-HACD (Volumetric Hierarchical Approximate Convex Decomposition)
//Create Date: 2021-12-14 11:07:39
//Author: channy
支持输入格式:.off和.obj
类 | 方法 | 功能 | 步骤 |
---|---|---|---|
VHACD | ComputeACD | 主入口,包括各项子流程 | |
VHACD | AlignMesh | 初始化基本操作 | 模型对齐,体素化 |
Volume | Voxelize | 体素化 | 根据比例把mesh转化为体素数据,inside/on/outside surface |
VHACD | VoxelizeMesh | 迭代性体素化以寻找最优dim | |
VHACD | ComputePrimitiveSet | 把Volume转化成VoxelSet | 基于voxel或tetrahedron |
VHACD | ComputeACD(const Parameters& params) | pca | |
VoxelSet | ComputeConvexHull | 基于ConvexHull计算ConvexHull | |
VHACD | ComputeConcavity | 计算误差 | |
VHACD | ComputePreferredCuttingDirection | 计算w (Game Engine Gems 3. 11.10) | |
VHACD | ComputeBestClippingPlane | 分割平面 | |
VHACD | MergeConvexHulls | 合并ConvexHulls (Game Engine Gems 3. 11.11) | |
SimplifyConvexHulls / SimplifyConvexHull | 简化mesh,以不共面的四个顶点组成的四面体为基础,不断增加点 | ||
VHACD | ComputeCenterOfMass | 质心 | |
ComputeBB | BoundingBox |
HACD (simplify from bullit library) too slow if there is no opt
VHACD
convexhullDownsampling默认为4 split threshold = concavity + balance + symmetry 其中, concavity = (volumeCH - volume) / TotalVolume concavity = concavityLeft + concavityRight balance = alpha * abs(volumeLeft - volumeRight) / TotalVolume symmetry = beta * w * distance(plane, cuttingDir)
concavity error calculation
The original paper mentions that this error can be tracked many ways, and the implementation used the farthest distance from the original surface to the newly formed surface within the newly formed predictive convex hull. We will use the same definition.
计算concavity error的目的是评估去掉一条边后生成的convex hull相比原模型的“损失”。原论文中表示可以有多种方法追踪这个误差,并使用了原始曲面到新生成曲面的最远距离作为该误差。roblox使用同样的方法。
为了得到该误差需要两方面的信息:
原始模型可量化的特征量
去掉该边后的模型生成的精确的convex hull
The original HACD implementation used a few sample points per triangle as a representation of the original surface (During Step 1 from overview). These points would then be used to raycast from, along the face normals, to find the backface of a convex hull that is impeding concavities. The longest distance from the original surface to the backface was considered the error.
HACD使用一个三角面片中一系列的采样点来表示原始曲面,这些采样点将被用于在法线方向进行raycast检测,以找到影响convex hull的凹面。从原始曲面到凹面的最长距离即为误差。乍看是一回事,但基于不同的三角面片有不同的采样密度,大三角面片的简单模型会有大量的盲点
roblox基于网格距离对每个三角面片进行采样,然后使用BB快速过滤。
继续过滤当前convex hull边界附近的点,raycast。如果误差没有增加,所有返回距离都是0,但一个有问题的convex hull会使得raycasts碰撞
We will uniformly generate surface sample points for every triangle based on a configured grid distance
In summary, the error generation can be described as such:
总结如下:
对每个三角面片进行采样,映射到一个特殊的网格
计算convex hull的BB并过滤所有在BB内部的点
raycast检测是否碰撞
最大距离计为concavity error
如果convex hull没有被挤出原始曲面,返回值应该是0
优化,尽早退出
This method only works well on 3D convex hulls. If the convex hull is flat, the sample points would never be aligned in the directions we would need to test during the formation of 2D convex hulls.
该方案提供了一个很好的稳定性,但只有在3D convex hull中才占优势。如果convex hull比较平滑,采样点将不会被对齐到2D方向上。
In order to properly resolve this, we would have to consider a completely different 2D error calculation process, which would be just as involved as the one we described.
为了解决该问题,roblox使用完全不同的2D error计算过程。
We can compare the area of the sum of the original two convex hulls to the area of the result. If the resulting hull has more area than the sum of the two source hulls, you know it may be closing a concavity, and therefore the square root of the extra area can be treated as the concavity error in this case!
通过比较结果和原始两个convex hull的面积和,如果结果的面积大,表明接近concavity,这时面积差的开方可以作为concavity error。
convex hull generation
After tweaking the concavity error calculation, we used the visual debugger to confirm that we still had issues:
Certain convex hulls that would seal large concavities would still pass the concavity error test with a result of 0. Combining two convex hulls would sometimes cause a vertex to disappear, leaving a hole in the original shape.
消除大凹面的convex hull依旧会返回concavity error = 0
合并convex hull有时会丢失顶点,形成空洞
HACD使用Quickhull算法,当有点共面/共线时有误差
Quickhull通过合并共面三角面片避免上述问题。然而这种方法不能用于区分原始三角面片。
As before with concavity error calculation, we must consider the 2D case as well. In order to protect your Convex Decomposition code from a variety of input data, you MUST implement a 2D Quickhull AS WELL as a 3D Quickhull to allow the combination of coplanar triangles. If we attempt to use the same process for coplanar triangles, it will not work and often delete input vertices or fail.
2D和3D Quickhull
从三个方面改进:
input: triangleMesh (points, triangles)
output: convexHull
基本步骤:先计算整个大凸包,再选取平面切割成小凸包
steps:
input: triangleMesh (points, triangles)
output: convexHull
基本步骤:对每一个三角面看成一个凸包,不断合并,形成最终的凸包
steps: