本文主要是介绍csg体素构造表示形式(Constructive Solid Geometry),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
csg的全称是Constructive Solid Geometry,也就是体素构造表示形式。godot引擎中有支持。主要用于一些形状间的结合,通过联合,相交,相减的操作来组成一个新的网格体。这种技术在有号距离场的形状距离识别中也有相应的应用。Prototyping levels with CSG — Godot Engine (stable) documentation in English
核心方法是mergeBrushes
intersectsInclusive
intersectsInclusive首先会看a面和b面是否aabb相交,如果相交则会进入具体的相交计算,也就进入updateFaces中。
重点1:updateFaces
updateFaces这里会去掉一些顶点很接近的,而且updateFaces主要看相交情况,首先通过isPointOver和hasPoint看是否相交,其中isPointOver是判断(n.dot(point) > d);也就是如果这个数量为3则说明B面的三个顶点都在A面的另一面,这样是不会有相交的。
然后通过sat的轴分离方式查看是否相交。
SAT:
sat是基于轴分离来判断是否两个凸多边形相交,这里的做法是拿两个三角形的所有边叉乘,叉乘出的结果再跟刚刚拿出的两个三角形的边做点乘找出投影位置,然后两个投影距离相减,拿到投影的最大偏移和最小偏移,如果最大偏移还小于0或者最小偏移还大于0则说明两个三角形是不相交的。
具体原理在这里有写,向量运算实现碰撞系统_llsansun的博客-CSDN博客
如果相交则添加新的面,
insertFace:
这里主要看insertFace,
这里首先看是否A面包含B面的点,如果包含直接加入点,如果不包含,如果两个点都在面的同一边则不加,如果不在并且他们有相交距离则加入点。
findEdgeIntersections和addVertexIdxSorted
然后通过findEdgeIntersections来找是否是边缘相交,如果是边缘相交则要做特殊处理,不然会有缺陷,比如边缘被删除了那么整个mesh的形状就和原来的形状不一致了,如果有边缘则要添加面来补足。检查边是否存在,通过检查相交段是否与边平行。如果对点在线段上,将其索引也添加到线段索引中。 在新边缘周围创建两个新面,并删除该面。
mergeFaces:
然后就执行mergeFaces,这里他会把相近的顶点去掉,不然他加入到面中,扁平的多个顶点的面也会去掉,以及如果是边缘,在新边缘周围创建两个新面,并删除该面。
addFace:
然后通过addFacesToMesh和addFace的方式,让点和uv加入到meshMerge中,记录顶点的合并信息。然后加入到faces中,这个faces是用于后面的面的法线方向步进后看是否有相交的其他面用的,具体在markInsideFaces中。
重点2:markInsideFaces
然后执行markInsideFaces,这里是关键的合并记录中,通过createBvh创建层级数据结构二叉树,然后遍历所有的faces,intersectsInclusive看是否a的面和b面是否有相交
bvhInside
有相交才进入到具体的bvhInside判断,bvhInside这里的判断是遍历所有面,然后通过当前bvh中的面然后执行intersectsRay,遍历A面的当前中心位置以及法线方面查看是否有相交的属于另一个来源面的三角形(也就是fromA的面和fromB的面比较,如果都是fromA或者都是fromB则不比较),但是intersectsRay只是针对AABB的判断。
然后后面通过isPointInTriangle来检查两个面是否共面。
rayIntersectsTriangle
然后如果有相交再执行rayIntersectsTriangle具体的三角形的中心点和法线方向的另一个来源的三角形是否有相交。如果有则说明是再里面的三角形,记录inside为true。
最后他判断如果面内的法线与其他面相交奇数次则认为碰撞。
重点3:inside
然后在CSGBrushOperation::mergeBrushes的时候检测利用inside来组合三角形。
OPERATION_UNION
如果是OPERATION_UNION则如果inside是true的话就不结合到顶点和uv中。
OPERATION_INTERSECTION
如果是OPERATION_INTERSECTION则inside是false的话就不结合顶点和uv,也就是没有相交的部分不加入三角形中,只有相交才加入。
OPERATION_SUBTRACTION
如果是OPERATION_SUBTRACTION则如果面来自于b面的结合并且不是inside的,则不结合顶点和uv,如果不是来自于b面的但是相交也不结合。意思就是如果a和b面是不是在同一个面上的而且相交的则要记录顶点。
最终返回mergedBrush这个CSGBrush。
这篇关于csg体素构造表示形式(Constructive Solid Geometry)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!