快速碰撞检测:Opencascade 层次包围盒的使用

使用BVH的场景

BVH可用在碰撞检测、光线追踪等场景,但由于项目的局限性,本文仅针对碰撞检测做出一定的介绍。

怎么确定BVH的使用方向

众所周知,在Opencascade中,模型是由TopoDS和AIS_Shape共同组成的,TopoDS控制模型的拓扑结构,AIS_Shape控制模型的显示样式。基于这个前提下,我先给出结论:需要用布尔运算计算出的新模型,就用TopoDS相关的布尔运算。如果是想做碰撞检测、光追,就用AIS_Shape中的Mesh(三角网格)计算

在碰撞检测中,操作TopoDS和AIS_Shape的区别

TopoDS是模型的根本,所以官方提供了一般的TopoDS算法,比如BRepExtrema_DistShapeShapeBRepAlgoAPI_Common等方法。这些方法虽然可以计算出模型的距离或者新模型,但计算的时间太长了,根本无法满足项目的要求。

简单来说,如果要计算两个模型的距离,就算BRepExtrema_DistShapeShape只需要几秒钟的计算,但在实时碰撞检测的情况下,这个时间是远远无法满足软件要求的。这也是为什么需要引入AIS_Shape(Mesh计算)

模型 在碰撞检测中的计算时间
TopoDS_Shape 方法多样,但很多计算多余,且耗时
AIS_Shape(Mesh) 计算超级快,我的项目里至少提速50倍,但用起来不方便,没有现成的BVH方法直接操作自己的模型

BVH操作AIS_Shape(三角网格)的具体方法

我这里一直说AIS_Shape,只是想泛指渲染的数据,我想大部分新手一开始接触Opencascade都对AIS_Shape有所了解,而不是其他专业的概念

构建好BVH容器

// Define BVH Builder
	opencascade::handle <BVH_LinearBuilder <Standard_Real, 3> > aLBuilder = new BVH_LinearBuilder <Standard_Real, 3>();

	// Create the ShapeSet
	opencascade::handle <BVH_BoxSet <Standard_Real, 3, std::vector<BVH_Vec3d>> > aTriangleBoxSet[2]; // 我需要计算两个Shape的距离,所以是声明两个BoxSet

上述代码中,容器是通过智能指针构建的,这也是很重要的一点。虽然也可以直接声明一个局部变量,但后续移动遍历、拷贝变量的时候会特别耗时,会导致算法变得很慢

提取TopoDS每个面的网格信息

上文说到BVH操作Mesh不太方便,也是因为这个问题。我们需要手动的提取出TopoDS的网格信息,比如:

TopoDS_Shape A = BRepBuilderAPI_Transform(tool.toolHeads[toolNum]->Shape(), tool.toolHeads[toolNum]->Transformation()).Shape();
TopTools_IndexedMapOfShape aMapShapes;
TopExp::MapShapes(A, TopAbs_FACE, aMapShapes);
for (Standard_Integer iS = 1; iS <= aMapShapes.Extent(); ++iS)
{
   
	TopoDS_Face face = TopoDS::Face(aMapShapes(iS));
	TopLoc_Location aLoc;
	Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation(face, aLoc);
	const int aNbTriangles = aTriangulation->NbTriangles();
	//...
}

上述代码中,有2个要注意的点:

  1. TopoDS要经过BRepBuilderAPI_Transform移动,移动的依据是渲染出来的AIS_Shape,因为Opencascade中,AIS_Shape的移动不会带着TopoDS跑,如果想要准确的三角网格信息,需要把TopoDS和AIS_Shape的位置关联起来,再用BRep_Tool::Triangulation
  2. 需要遍历每个面,将每个面进行三角网格划分。

将网格数据存入BVH_BoxSet

我们需要先声明几个变量,这几个变量的作用是初始化BVH_Box。

	// Define BVH Builder
	opencascade::handle <BVH_LinearBuilder <Standard_Real, 3> ><
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值