参考:ReverseNormals - Unify Community Wiki
モデルのポリゴン・メッシュの一部が裏返っている場合の修正。下の例は、水平面で上向きに揃える。
// ReverseMesh (Flip Mesh) // First Version 2015/06/02 by A.Y.@XOOMS // Last Update 2015/06/02 by A.Y.@XOOMS // using UnityEngine; using System.Collections; using System.Collections.Generic; using Xooms; namespace Xooms{ [RequireComponent(typeof(MeshFilter))] public class ReverseMesh : MonoBehaviour { //Public Variables public int screening = 0; //Private Variables //Public Functions //-------------- // Initialization void Start () { MeshFilter filter = GetComponent<MeshFilter>(); if (filter != null) { Mesh mesh = filter.mesh; Vector3[] verts = mesh.vertices; for (int m=0;m<mesh.subMeshCount;m++) { int[] triangles = mesh.GetTriangles(m); for (int i=0;i<triangles.Length;i+=3) { Vector3 v1 = verts[triangles[i+1]]-verts[triangles[i]]; Vector3 v2 = verts[triangles[i+2]]-verts[triangles[i]]; Vector3 v1v2 = Vector3.Cross(v1,v2); if(screening==0||((screening<0)&&(v1v2.y < 0))||((screening>0)&&(v1v2.y > 0))) { int temp = triangles[i + 0]; triangles[i + 0] = triangles[i + 1]; triangles[i + 1] = temp; } } mesh.SetTriangles(triangles, m); } mesh.RecalculateNormals(); } } } }
全頂点は mesh.verticesで取得できる。要素はVector3。
mesh.GetTriagnes()で返される整数配列の要素は、3つずつ組みで各三角ポリゴンの頂点を示す。0.1,2がひとつめのポリゴン、3,4,5が2つめ…となる。
これらを組み合わせて、各ポリゴンの頂点座標が得られる。
if(screening==0||((screening<0)&&(v1v2.y < 0))||((screening>0)&&(v1v2.y > 0))))
のところは、法線ベクトルの向きでスクリーニングしている。
・screening==0 の場合はすべてのメッシュを反転
・screeningが正(負)の場合は、法線ベクトルが正(負)のメッシュのみ反転する。
本線ベクトルは2辺の外積から求め、そのY座標の正負で判断している。三角ポリゴンの頂点の2つを入れ替えることで、メッシュの「裏返し」を実現している。
メッシュの向きを最設定後、mesh.RecalculateNormals() で、頂点法線を再計算する。