Mesh(三)快速切割網格
依舊搬舊博客的,因為代碼量比較大,所以直接給工程和部分講解。
最早整這個是因為當時玩合金裝備時,有個子彈時間的切割,可以任意切割所有模型.就好奇的也整了個.
最終效果
思路:
- 確定切線的平面
- 根據切面將模型的頂點分類切面的上/下 兩部分。
- 對頂點間的連線進行頂點補充,並順序連接頂點。
- 將切開的剖面頂點進行排序、補面、設置UV等。
講解:
為了方便這裡我們拿BOX舉例。
當一個box被裁切時,我們根據裁切面,將模型的頂點分為兩類,頂點0145為模型A,頂點3267為模型B,同時A組和B組按順序記錄每個頂點的信息。
然後我們按照之前的網格的頂點索引,依次判斷連接當前兩個模型的頂點。
結果如下:
這時候我們需要在被切的面上,補充頂點,並且連接.
回到一開始被切的時候,我們來分析被切的面.
如圖,一個平面是兩個三角面,一個三角面被切割時,我們需要補充2個頂點.這時候我們就需要判斷三角面上2個頂點的位置,然後依次連接他們,形成面.
如圖:當三角形abc被x軸切開時,
我們先求出ab和oa在y軸上的投影:
既 oay = Vector.Dot(a-o,y-o);
bay = Vector.Dot(a-b,y-o);
然後求出他們在y軸上的投影比:
scale = oay/bay;
然後d的位置就相當於以a為起點,在ab的方向移動了scale的比例.
d = a+(b-a)*scale;
e同理.
這樣,我們根據網格的連接順序,以此連接aed,bdc,cde,再把頂點以此加入到各自歸屬的模型中.就得到了如下的模型:
最後我們需要把這個空白的剖面填充,不需要添加頂點,但需要把當前的標記出來的頂點,進行合理的排序連接.幸運的是,我們之前生成的頂點都是兩個重疊在一起的,因為每個三角面生成2個頂點而三角面是互相拼接的.而不重疊的頂點都是互相連接的,在排序的過程中,刪除掉重複的頂點.
當獲得正確的頂點順序:只需要012,023,034,,,,這樣依次連接他們就可以把剖面填充上.
最後我們需要給每個頂點合適的uv,來填充貼圖.
映射uv就看個人的需求了,可以用box或者球形映射等,來滿足需求.
常規排序
那如何對凸多邊形上內任意若干的頂點進行連接呢。
這時候我們需要根據凸多邊形的外切線和角度來確定下個頂點的位置。
這裡只提供思路,代碼太長就不貼了,而且在模型切割上效率不如上面的高。
首先將頂點都轉換到切線尋找凸多邊形的外切線向量。
然後逐頂點對比角度。
如果兩個頂點與切線共線,我們就比較距離,一個頂點只有2個頂點連接他。第一次共線距離為近的排序,第二次共線距離為遠的排序。
凹多邊形
有人問凹多邊形如何填充,呵呵,如果填充凹多邊形,要先把凹多邊形分割成若干個凸多邊形進行填充。
GitHub地址:
carefreeq/SplitMesh
推薦閱讀: