Mesh切割算法/ 3.1 Unity Mesh切割算法詳解
前言
我們?cè)陂_(kāi)發(fā)游戲的時(shí)候經(jīng)常會(huì)有一些特殊的游戲玩法等,需要涉及Mesh切割。比如3D切水果, 在地圖的城墻上挖一個(gè)洞,今天給大家來(lái)分享一個(gè)Mesh切割的算法,幫助大家解決項(xiàng)目中需要用到的Mesh切割的問(wèn)題。本文主要從一下幾個(gè)方面來(lái)講解Mesh切割。
(1) 如何接受玩家的觸摸操作,生成切割面;
(2) 3D模型Mesh對(duì)象中的主要數(shù)據(jù)組成;
(3) 模型Mesh切割算法步驟詳解;

如何接受玩家的觸摸操作,生成切割面
做模型切割的時(shí)候,我們首先要根據(jù)玩家的觸摸操作來(lái)生成一個(gè)切割平面。如圖1所示,根據(jù)玩家的黑色的劃線,我們要基于黑色的劃線來(lái)生成一個(gè)切割平面。主要的步驟如下:
(1) 獲取起點(diǎn)的屏幕坐標(biāo),并結(jié)合3D攝像機(jī),把起點(diǎn)的屏幕坐標(biāo)轉(zhuǎn)到攝像機(jī)的視口坐標(biāo)系下。
(2) 獲取終點(diǎn)的屏幕坐標(biāo),并結(jié)合3D攝像機(jī),把重點(diǎn)的屏幕坐標(biāo)賺到攝像機(jī)的視口坐標(biāo)系下。
(3) 基于攝像機(jī),將起點(diǎn)與終點(diǎn)生成兩條射線出來(lái),并計(jì)算出射線與攝像機(jī)的Near平面的交點(diǎn)。
(4) 有了兩個(gè)點(diǎn)后,就有了一條線,還要有一個(gè)方向才能確定一個(gè)平面(線按照方向移動(dòng),就成了面),這個(gè)方向我們?nèi)ndRay射線的方向?yàn)橄蛄緼。

(5) 把終點(diǎn)-起點(diǎn)得到一個(gè)向量,結(jié)合方向endRay射線方向的像量,來(lái)做叉積,這樣就得到了斜面的旋轉(zhuǎn)后的up向量。如圖所示,同時(shí)斜面過(guò)start, end中的點(diǎn),所以這樣就可以確定切割面出來(lái)。

根據(jù) start與normalVec,就可以確定我們的切割面了,它就是過(guò)start點(diǎn),向上的方向向量為normalVec的平面。
3D模型Mesh對(duì)象中的主要數(shù)據(jù)組成
在詳細(xì)的講解Mesh切割算法之前,先給大家講解一下一個(gè)模型的Mesh數(shù)據(jù)主要包含哪些部分,等下生成新的Mesh的時(shí)候,我們知道每一部分的數(shù)據(jù)都代表什么。Unity中網(wǎng)格數(shù)據(jù)被生成到Mesh對(duì)象里面,一個(gè)Mesh對(duì)象主要包含以下重要的數(shù)據(jù):
頂點(diǎn)數(shù)據(jù): Mesh對(duì)象中的所有的網(wǎng)格頂點(diǎn);
法線數(shù)據(jù): Mesh對(duì)象中每個(gè)頂點(diǎn)所對(duì)應(yīng)的法線數(shù)據(jù);
紋理uv數(shù)據(jù): Mesh對(duì)象中每個(gè)頂點(diǎn)所對(duì)應(yīng)的紋理uv數(shù)據(jù);
三角形頂點(diǎn)索引數(shù)據(jù): Mesh對(duì)象中的每個(gè)面對(duì)應(yīng)的三角形數(shù)據(jù),而三角形是基于頂點(diǎn)索引的。如面A由三個(gè)頂點(diǎn)A1, A2, A3組成,這里是頂點(diǎn)索引,A1由索引,到頂點(diǎn)數(shù)據(jù)里面獲取頂點(diǎn)數(shù)據(jù),由A1索引到法線數(shù)據(jù)里面獲取法線。在Unity里面可以通過(guò)Mesh對(duì)象的接口函數(shù)獲取上面的數(shù)據(jù),如下:
模型Mesh切割算法步驟詳解
確定了切割面以后,接下來(lái)我們來(lái)分析Mesh切割算法的主要步驟:
Step1:?獲取模型坐標(biāo)系下的切割面
將”切割面” point(平面經(jīng)過(guò)的點(diǎn))+normal(平面的up向量)由視口坐標(biāo)轉(zhuǎn)到要切割的模型坐標(biāo)系:
再根據(jù)過(guò)localPoint, 法線向量為localNormal,來(lái)生成一個(gè)Plane平面對(duì)象。這里的平面對(duì)象是相對(duì)于模型的坐標(biāo)系而言的。
Step2:?根據(jù)切割面,來(lái)將物體分成正向部分與反向部分,切割物體后,平面上面的是正向部分(Positive),平面下面的是反向部分(Negative)
Step3:?判斷以下Mesh與平面是否相交,如果Mesh與平面完全沒(méi)有焦點(diǎn),則算法結(jié)束,不用分割Mesh;
Step4:?獲取原來(lái)Mesh中的網(wǎng)格數(shù)據(jù), 并清理切割后存放的正向與反向的Mesh數(shù)據(jù)集合。
Step5:?遍歷所有的頂點(diǎn),看哪些頂點(diǎn)在切割面的上部,哪些頂點(diǎn)在切割面的下步,將他們分開(kāi)放置到PositiveMesh與NegativeMesh中。
Step6:?將切割面與物體的交點(diǎn)計(jì)算出來(lái),為生成新的面做好準(zhǔn)備;
Step7:?根據(jù)新增的點(diǎn)來(lái)生成新的面

Step8:?實(shí)例化一個(gè)新物體,將切割后的2個(gè)Mesh,一個(gè)復(fù)制給原來(lái)的節(jié)點(diǎn),一個(gè)復(fù)制給新創(chuàng)建的節(jié)點(diǎn)。
Unity / 精選推薦
Unity架構(gòu)師進(jìn)階: Mesh切割算法詳解
https://www.bycwedu.com/promotion_channels/1997539005