[Unity3D]

[UNITY3D] 면 뒤집힘 현상.

PforPepsi 2012. 8. 22. 15:36

이 글을 쓰는 이유는... Max -> Unity로 바꿀때 면이 자주 뒤집혀서 나의 성깔이 돌아갈 것 같아서이다.

먼저 면이 돌아간다는 것의 기본적인 이유는 삼각형 index가 거꾸로 배치되어 있기 때문인데... 이를 해결하는 스크립트를 제시하고자 한다.


using UnityEngine;
using System.Collections;
using System.Collections.Generic;
 
public class FLIP : MonoBehaviour {
     
    Mesh m;
     
    // Use this for initialization
    void Start () {
         
        if(GetComponent<SkinnedMeshRenderer>())
            m = GetComponent<SkinnedMeshRenderer>().sharedMesh;
         
        for(int i = 0 ; i < m.vertices.Length; i++){
            m.vertices[i] = new Vector3(m.vertices[i].x + 100f, m.vertices[i].y, m.vertices[i].z);
        }
        List<Vector3> vertices = new List<Vector3>();
        List<Vector3> normals = new List<Vector3>();
         
        List<int> triangles = new List<int>();
         
        List<Vector2> uv1 = new List<Vector2>();
        List<Vector4> tangents = new List<Vector4>();
        List<BoneWeight> boneWeights = new List<BoneWeight>();
        List<Matrix4x4> bindposes = new List<Matrix4x4>();
         
        for(int i = 0; i < m.vertices.Length; i++){
            vertices.Add(m.vertices[i]);
            normals.Add(m.normals[i]);
            uv1.Add(m.uv[i]);
            tangents.Add(m.tangents[i]);
        }      
         
        for(int i = m.triangles.Length - 1; i >= 0; i--){
            triangles.Add(m.triangles[i]);
        }
         
        for(int i = 0; i < m.boneWeights.Length; i++){
            boneWeights.Add(m.boneWeights[i]); 
        }
         
        for(int i = 0; i < m.bindposes.Length; i++){
            bindposes.Add(m.bindposes[i]); 
        }
         
        m.Clear();
         
        m.vertices = vertices.ToArray();
        m.triangles = triangles.ToArray();
        m.uv = uv1.ToArray();
        m.normals = normals.ToArray();
        m.tangents = tangents.ToArray();
        m.boneWeights = boneWeights.ToArray();
        m.bindposes = bindposes.ToArray();
    }
     
    // Update is called once per frame
    void Update () {
     
    }
}






여기서  주의해야 할 것은. 내가 불러오는 Mesh의 데이터는 SkinnedMeshRenderer에 붙어있는 mesh라는 것이다. 따라서 SkinnedMeshRenderer가 아닌, MeshFilter라면 GetComponent 부분을 바꿔주기 바란다.

또한 Mesh 정보를 바꿔 줄 떄의 주의점은, 부분변환은 적용이 안된다는 것이다.(이유 모름). 

가령 현재 문제는 triangle의 인덱스 순서가 잘못 되어있다고 말했는데, 이러면 triangle의 인덱스만 바꿔주면 되지만, 위의 예시처럼 정점에서 부터 노말값까지 다 새로 박아주는 이유는 적용이 안되서이다. 따라서 Clear()를 통해 Mesh정보를 비워주고, 새로운 정보를 입력해줘야 한다.