1 분 소요

지난번 정점 8개 큐브 만들기에 이어서 이번엔 정점24개를 가진 큐브를 만들어 볼 것이다.

Cube 작성

정점위치 참조 테이블

한 위치에 같은 정점이 3개가 만들어지는데 이 정점의 위치를 매번 계산하는 것 보단 테이블로 만들고 면이 테이블에 있는 정점 위치 정보를 가져오게 하는 것이 좋을 것이다.

그러기 위해선 각 면에서 사용할 정점 위치index를 지정해 줘야한다.
먼저 큐브의 각 면들의 방향을 표현한 enum을 선언한다.

    public enum Direction
    {
        FORWARD, // (0, 0, 1)
        RIGHT,   // (1, 0, 0)
        UP,      // (0, 1, 0)
        BACK,    // (0, 0, -1)
        LEFT,    // (-1, 0, 0)
        DOWN     // (0, -1, 0)
    }

그 다음 면에서 사용하는 정점 Index를 정한다.
유니티에선 Z축이 Forward이기에 Z축 기준으로 정점을 구성해 준다.

imagevertex 순서


Direction enum에서 설계한 방향을 토대로 면의 정점을 만든다.

    int[][] faceNumber =
    {
        new int[]{0,1,2,3},
        new int[]{5,0,3,6},
        new int[]{5,4,1,0},
        new int[]{4,5,6,7},
        new int[]{1,4,7,2},
        new int[]{3,2,7,6},
    };

정점 위치 테이블

정점들의 위치 데이터를 가진 테이블을 만들어준다.
Scale을 적용하기 위해 아다마르 곱 을 해준다.

    Vector3 scale = new Vector3(width, height, width);
    List<Vector3> vertices = new List<Vector3>();
    // 정점들 위치 배열
    vSet.Add(Vector3.Scale(new Vector3(half, half, half), scale));
    vSet.Add(Vector3.Scale(new Vector3(-half, half, half), scale));
    vSet.Add(Vector3.Scale(new Vector3(-half, -half, half), scale));
    vSet.Add(Vector3.Scale(new Vector3(half, -half, half), scale));
    vSet.Add(Vector3.Scale(new Vector3(-half, half, -half), scale));
    vSet.Add(Vector3.Scale(new Vector3(half, half, -half), scale));
    vSet.Add(Vector3.Scale(new Vector3(half, -half, -half), scale));
    vSet.Add(Vector3.Scale(new Vector3(-half, -half, -half), scale));
아다마르 곱 (Hadamard Product)

벡터와 벡터를 각 성분 끼리만 곱하는 행렬 곱이다.


Cube 구현

Cube의 면은 6개, 면에 존재하는 정점은 4개 이므로 총 24개의 정점을 만든다.
면마다 정점이 필요한 이유는 이전 포스트에서도 말했다시피

정점 하나가 가질 수 있는 uv 정보는 1개 까지라 면 3개에 대한 정보를 가질 수 없다.
그래서 면마다 정점을 만들어주는 것이다.

for(int faceDir = 0; faceDir < 6; faceDir++)
{
    for(int faceIndex = 0; faceIndex < 4; faceIndex++)
    {
        int faceVertexIndex = faceNumber[faceDir][faceIndex];
        vertices.Add(vSet[faceVertexIndex]);
    }

정점에 대응하는 uv정보와 면을 구성하는 삼각형을 그리기 위해 triangles에 정점 번호를 넣어준다.

    uvs.Add(new Vector2(0,1));
    uvs.Add(new Vector2(1,1));
    uvs.Add(new Vector2(1,0));
    uvs.Add(new Vector2(0,0));

    int triangleIndex = faceDir * 4;
    triangles.Add(triangleIndex + 0);
    triangles.Add(triangleIndex + 1);
    triangles.Add(triangleIndex + 3);

    triangles.Add(triangleIndex + 1);
    triangles.Add(triangleIndex + 2);
    triangles.Add(triangleIndex + 3);
}

지금까지 작성한 데이터들을 Mesh로 만들어 MeshFilter에 넣어준다.

    Mesh mesh = new Mesh();
    mesh.vertices = vertices.ToArray();
    mesh.uv = uvs.ToArray();
    mesh.triangles = triangles.ToArray();
    mesh.RecalculateBounds();

    GetComponent<MeshFilter>().mesh = mesh;

image완성된 Cube

댓글남기기