본문 바로가기
개발/Unity

유니티 - 절차적 메시로 정사면체 그리기 (Make Tetrahedron with Procedural Mesh)

by 피로물든딸기 2022. 11. 5.
반응형

Unity 전체 링크

 

절차적 메시를 이용하여 정사면체를 만들어보자.

 

길이가 a인 정삼각형이 있다고 가정하자.

정삼각형 넓이 공식은 다음과 같다.

 

정삼각형의 중심은 다음과 같다. (링크 참고)

 

아래의 그림을 참고하자.

 

 

그리고 정사면체의 높이는 다음과 같다.

 

정사면체의 부피정삼각형의 넓이(S)정사면체의 높이(H)의 곱을 3으로 나누면 된다.

 

 

따라서, 정사면체의 부피 V는 다음과 같다.

 

정사면체의 중심C라고 할 때, 이 중심은 모든 정사면체에서 높이가 동일하다.

따라서 4개의 사면체의 부피 1개의 정사면체의 부피는 값이 같으므로 아래의 식이 성립한다.

 

 

따라서 정사면체의 중심은 다음과 같다.


위의 식과 절차적 메시로 삼각형 만들기를 바탕으로 ProceduralTetrahedron.cs를 만들어보자.

코드에서 사용할 정점 4개는 아래와 같이 정의한다.

 

위의 좌표를 바탕으로 정점을 정의하고 triangles에 순서대로 값을 넣는다.

    void setMeshData(float size)
    {
        float g = Mathf.Sqrt(3.0f) / 6.0f * size; // 정삼각형의 중점
        float h = Mathf.Sqrt(6.0f) / 3.0f * size; // 정사면체의 높이
        float c = Mathf.Sqrt(6.0f) / 12.0f * size; // 정사면체의 중점

        Vector3 d0 = new Vector3(0, h - c, 0) + offset; 
        Vector3 d1 = new Vector3(-0.5f * size, -c, -g) + offset;
        Vector3 d2 = new Vector3(0, -c, Mathf.Sqrt(3.0f) / 2.0f * size - g) + offset;
        Vector3 d3 = new Vector3(0.5f * size, -c, -g) + offset;

        vertices = new Vector3[] { d0, d1, d2, d3 };

        triangles = new int[] { 0, 3, 1, 0, 2, 3, 0, 1, 2, 1, 3, 2 };
    }

 

빈 오브젝트에 스크립트와 Mesh Filter, Renderer, 머테리얼을 설정하자.

 

사면체가 만들어졌지만 면이 뿌옇게 변하였다.

 

현재 정사면체의 정점은 4개이고, 정점 하나는 면 3개에 대한 노멀을 처리해야 한다.

그런데 하나의 정점하나의 정보만 가지므로, 정사면체의 정점은 12개여야 한다. (실제 큐브의 정점의 개수도 24개다.)

 

따라서 아래와 같이 코드를 수정한다.

    void setMeshData(float size)
    {
        float g = Mathf.Sqrt(3.0f) / 6.0f * size; // 정삼각형의 중점
        float h = Mathf.Sqrt(6.0f) / 3.0f * size; // 정사면체의 높이
        float c = Mathf.Sqrt(6.0f) / 12.0f * size; // 정사면체의 중점

        Vector3 d0 = new Vector3(0, h - c, 0) + offset; 
        Vector3 d1 = new Vector3(-0.5f * size, -c, -g) + offset;
        Vector3 d2 = new Vector3(0, -c, Mathf.Sqrt(3.0f) / 2.0f * size - g) + offset;
        Vector3 d3 = new Vector3(0.5f * size, -c, -g) + offset;

        vertices = new Vector3[] { d0, d1, d2, d0, d2, d3, d0, d3, d1, d1, d3, d2 };

        triangles = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
    }

 

완성된 정사면체는 다음과 같다.

정점이 4개인 정사면체가 흐릿해지는 현상이 사라졌다.

 

콜라이더만 보면 아래와 같다.

 

최종 코드는 다음과 같다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(MeshRenderer), typeof(MeshFilter))]
public class ProceduralTetrahedron : MonoBehaviour
{
    public float size = 1.0f;
    public Vector3 offset = new Vector3(0, 0, 0);

    Mesh mesh;
    Vector3[] vertices;
    int[] triangles;

    void OnValidate()
    {
        if (mesh == null) return;

        if (size > 0 || offset.magnitude > 0)
        {
            setMeshData(size);
            createProceduralMesh();
        }
    }

    void Start()
    {
        mesh = GetComponent<MeshFilter>().mesh;

        setMeshData(size);
        createProceduralMesh();
    }

    void setMeshData(float size)
    {
        float g = Mathf.Sqrt(3.0f) / 6.0f * size; // 정삼각형의 중점
        float h = Mathf.Sqrt(6.0f) / 3.0f * size; // 정사면체의 높이
        float c = Mathf.Sqrt(6.0f) / 12.0f * size; // 정사면체의 중점

        Vector3 d0 = new Vector3(0, h - c, 0) + offset; 
        Vector3 d1 = new Vector3(-0.5f * size, -c, -g) + offset;
        Vector3 d2 = new Vector3(0, -c, Mathf.Sqrt(3.0f) / 2.0f * size - g) + offset;
        Vector3 d3 = new Vector3(0.5f * size, -c, -g) + offset;

        vertices = new Vector3[] { d0, d1, d2, d0, d2, d3, d0, d3, d1, d1, d3, d2 };

        triangles = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
    }

    void createProceduralMesh()
    {
        mesh.Clear();
        mesh.vertices = vertices;
        mesh.triangles = triangles;
        mesh.RecalculateNormals();

        Destroy(this.GetComponent<MeshCollider>());
        this.gameObject.AddComponent<MeshCollider>();
    }
}

 

Unity Plus:

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Unity Pro:

 

Unity Pro

The complete solutions for professionals to create and operate.

unity.com

 

Unity 프리미엄 학습:

 

Unity Learn

Advance your Unity skills with live sessions and over 750 hours of on-demand learning content designed for creators at every skill level.

unity.com

반응형

댓글