Unityな日々(Unity Geek)

Unityで可視化アプリを開発するための試行錯誤の覚書

ポリゴン・メッシュを裏返す

参考: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() で、頂点法線を再計算する。