BVH 层次包围结构

46 篇文章 0 订阅
46 篇文章 0 订阅

学习目标

  • 使用BVH优化选择

知识点

  • BVH

1-BVH 原理

BVH(Bounding Volume Hierarchy)是一种层次包围结构,适用于对数量较多的几何对象进行碰撞检测或光线追踪。

在BVH中,所有的几何物体都会被包在包围体里面,包围体外面还会包着一个更大的包围体,以此递归地包裹下去,最终形成的根节点会包裹着整个场景。

这种结构对于物体较多的场景中非常有效。

解释一下BVH区域划分的原理:

1.计算包裹所有物体的最大的包围盒。

2.寻找包围盒中长宽中最大的那一项,将其拆成2个子包围盒。

3.把属于子包围盒的物体存入其中。

4.若子包围盒中的物体数量大于区域划分的最小数量,递归执行步骤1。

2-BVH 对象

BVH对象负责计算图形集群的层次包围结构,其整体代码如下:

  • /src/lmm/physics/BVH.ts
  • 简单解释一下其封装思路。

    BVH 需要一个用于区域划分的图形集合,这里的图形就是Graph2D对象。

    与此同时,我们还得附带此对象的包围盒,用于区域划分。

    所以,我们要传输给BVH 的图形数据就是这样的:

Graph2D图形的包围盒会随坐标系而变,所以我不在BVH中计算其包围盒。

BVH对象只专注于计算层次包围结构,其具体的计算流程我在代码里都有详细注释,所以不再赘述。

接下来,我们把BVH 显示出来看看。

3-BVHHelper 对象

BVHHelper 是专门用于显示BVH 的辅助对象。

  • /src/lmm/helper/BVHHelper.ts

其原理就是把划分出来的区域用矩形画出来。

4-BVH的显示示例

我提前准好了一堆用于测试BVH的图形数据。

  • /src/examples/dataLib/RectStore.ts
  • 接下来建立一个vue页面,用于显示BVH。

  • /src/examples/BVH01.vue

效果如下:

解释一下其过程。

1.基于之前的RectStore.ts 示例化一堆矩形,并对其进行随机旋转。

2.计算每个矩阵在世界坐标系内的包围盒,然后将其存入targets。

rectObj.getWorldBoundingBox() 方法可以获取图形在世界坐标系内的包围盒,其源码如下:

geometry.getBoundingBoxByMatrix(matrix) 方法可以获取几何体在某个坐标系内的包围盒。

3.基于targets,实例化BVH包围盒。

4.显示包围盒。

5.对于BVH 包围盒的颜色,我也可以根据图形在BVH 中的索引值设置成不同的颜色。

我们可以根据BVH 节点的索引位置让其显示不同的颜色。

现在,我们已经掌握了BVH 的代码实现。接下来我们可以将其应用到第二个面试题里。

5-射线与BVH的求交

我们可以再之前的PhysicUtils.ts 文件里,定义一个射线与BVH求交的方法。

  • /src/lmm/physics/PhysicUtils.ts

rootBox.traverse(fun1,fun2) 方法会从外向内遍历BVH 划分出的区域,其中的两个参数都是回调函数。

fun2 会判断射线是否与相应区域的包围盒相交,若不相交,就不再向内遍历包围盒。

fun1 是在fun2返回true的前提下执行的,若相应区域的包围盒是最内部的包围盒,便判断射线是否与此包围盒中的图形相交。

6-使用BVH优化选择示例

我们接着第二个面试题,创建多个障碍物,演示一下如何用BVH优化选择。

建立一个新的vue页面。

  • /src/examples/BVH02.vue

效果如下:

当前示例中的技术点咱们都说过,剩下的都是业务逻辑,我都有详细注释,大家可以自己看。

总结

这一篇我们说了BVH的原理和代码实现,它适合在元素较多的场景里做选择。

原文链接:https://juejin.cn/post/7407621980574875711

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值