1、简介
2、技术详解与实现原理
简介
本篇文章介绍将如何任意对mesh进行无规则切割,如下图,这是一张Unity的Terrain,通过自己指定的切割形状把需要的部分切割了出来,注意,这种算法不是只有地形可用,是针对mesh做的,图中只是示例。
题外话:在无缝大世界中,往往一张大地图的地表贴图数量会很多比如有10多张,在某些地方比如下雪和秋天的交界处,往往这个地方的地形贴图是混合有两种类型的刷子贴图,如下图所示,这样shader里混合图通道需要更多,要的刷子纹理也越多,为了避免这个问题,因此需要将地形根据区域无规则切分。
技术详解与实现原理
开始之前先说一下以Unity为列子的Mesh里数据如何构建的,如下图,Triangles数组存储的是所有三角形对应于vertices数组里的顶点,triangles从坐标0~n依次存储了每个三角形三个顶点在vertices下的位置,uv也是跟vertices对应的,知道这些后我们就可以对mesh任意操作了。
步骤:
- 给定一个需要切割出来的区域线段,如文章第一张图所给出的线段那样。
- 将区域内的mesh切割出来并重建。
开始
黑色的三角形组成的图形是一块Mesh,红色的线框是切割所要的区域,这个线段是操作者给出来的,箭头表示线段是顺时针绘制。
寻找完全在线框内三角形
首先把完全在线框内的三角形提取出来,这里的完全判断法是保证三角形三个顶点在线框内就算,不计算交叉情况。
判断一个点是否在线框内,用点向两边发射平行于x轴的射线,这两条射线只要都有交点并且交点的个数都是奇数,那么就是在线框内。
算法实现:首先排除与线段两点相交情况,与线段相交的判断,只要判断点的y轴在线段两个端点之间就行,而判断线段在点的那边这需要用到叉乘,如下图,线段按照瞬时间绘制,我们把每一段线段起始点与判断的点相连成一个向量,图中有四种连接情况需要判断。
- 箭头向下的线段,黑色叉乘绿色,为正则为左边,否则为右边
- 箭头向上的线段,黑色叉乘绿色,为正则为右边,否则为左边
-
被切了1刀的三角形处理
绿色圈中的三角形,这些三角形是被线段切了一刀的类型。
我们要判断三角形三条边哪两条边与线段相交,利用直线方程计算交点可用参考这篇文章:https://www.cnblogs.com/zany-hui/articles/7927462.html,当计算出了两个交点。
直线方程和图中计算都是在一个平面上计算的,假设图中我们这个平面是y轴投影平面,计算出交点的时候需要计算y位置在哪,我们可用使用等比计算出来。
如下图,假设被切的线段两点x距离为x,y距离为y,切割点与另一个x点距离为x1,y距离为y1,那么就有x/x1 = y/y1,这里只有y1是未知数,所以可求得。
两点确定后,先找出被切割的两条边的共同点,两个点与这个点组成一个三角形,然后另外一边有4个顶点,需要划一条线分开两个三角形,这条线画哪一边可用根据两种情况的三角形哪种更接近等边三角形就画哪一种这种方式。
对了这里还需要判断两个点在线框内还是一个点在线框内,判断出就可以判断是舍弃构造出一个三角形的那边还是舍弃构造出两个三角形那边。
3组三角形分好后,画三角形顺序怎么判断呢?以unity顺时针构造三角形为法线正面为例子,3个顶点随意画两条线段组成方向向量,如下图,右边向量叉乘左边向量,为正,交点是第一个点,第二个点是连接左边向量的那个点,否则第一个点不变第二个点与第三个点位置调换,这里不会出现等于0,等于0就不是三角形了。
被切了2刀或更多刀的三角形处理
如下图所示,特别是左下角的三角形被切的乱七八糟的,这种情况往往处理起来比较复杂,为了简单起见,我们先计算这个三角形有几个点在线框内,只取开始切割的点和结束切割的那两个点,这样就跟上面一样计算。