之前的可编辑模型(如正方体,圆台)不涉及复杂的性能瓶颈,但是可编辑曲面不同。它的本质是沿着样条线(Spline)动态生成的拓扑结构,其顶点数量没有硬性上限,而是与路径长度、采样精度以及断面复杂度呈线性甚至几何级数增长。
优化策略
埋点分析与耗时监控
“没有测量就没有优化。” 在盲目优化之前,必须知道瓶颈在哪。实现一个自定义的计时器类(Scoped Timer),在几何生成、碰撞构建等关键函数的入口进行埋点。
1 | struct FScopedTimer |
内存管理:缓存复用与预分配
C++ 中频繁的内存分配是非常昂贵的
- 成员变量缓存: 将
LeftRailRaw,CachedRawPoints等高频使用的数组提升为类的成员变量。每次生成时,调用Reset()而不是Empty()。Reset()会清空数据但保留Capacity(容量),从而避免了底层的内存释放与重新分配。 - 预分配 : 在填充数据前,通过
CalculateVertexCountEstimate()估算大概的顶点数,并调用MeshData.Reserve()。这避免了TArray在Add过程中因为扩容而发生的多次数据搬迁。
智能减面:基于角度的自适应采样
并非所有的路段都需要同等密度的顶点采样。直线段仅需首尾两点确定,而弯道才需要高密度逼近。
- 原理: 计算相邻线段方向向量的点积:
$$\vec{v_1} \cdot \vec{v_2} = \cos(\theta)$$
如果点积接近 1(例如> 0.9998),说明线段几乎共线,中间的顶点是冗余的,可以剔除。 - 效果: 在不损失视觉质量的前提下,大幅减少了生成的三角形数量,进而减轻了 GPU 的光栅化压力。
算法优化:空间哈希加速去环检测
当曲面发生自我交叉(打结)时,我们需要检测并剔除这些几何体。朴素的去环检测需要 $O(N^2)$ 的暴力比对,顶点过多容易卡死线程。
解决方案: 引入空间哈希 (Spatial Hashing)。
实现: 我们将 3D 空间投影到 2D 网格,通过简单的位运算和大质数散射
((X * 73856093) ^ (Y * 19349663)) & (HashSize - 1)将顶点映射到哈希桶中。之后会执行精确的 3D 欧氏距离检测。只要高度(Z轴)差距足够大,即便 2D 投影重叠,也绝不会被错误剔除。提升: 查询复杂度降至接近 $O(1)$,实现实时拖拽去环。