GameForFun

블로그 이미지
by PforPepsi

TAG CLOUD

  • Total hit
  • Today hit
  • Yesterday hit


이번 글에서는 작업중이던 도형 자르기에 대해서 얘기해보자 합니다.
제가 구현한 사항에서는 볼록한 도형만 처리됩니다.

자르는 방법에는 2가지로 나눠보도록 하겠습니다.

1. Ray를 이용한 자르기 방법.

2. Collider를 이용한 자르기 방법.

위 두가지 방법은 크게 다른점은 없습니다. 단지, 실제 칼날을 쓸것이냐, 가상의 칼날을 쓸것이냐에 따른 차이가 존재할 뿐입니다.

1. Ray를 이용
-> Ray를 이용하는 것은 의외로 간단합니다. 먼저 물체가 잘리는 조건을 정하고 진행하도록 하겠습니다. 
물체가 잘리는 조건: 물체를 완벽하게 그어야 된다.(물체 중간에서 멈추면 물체가 잘리지 않는다).
위 조건대로 방법을 보자면 다음과 같습니다.
마우스를 누른다(물체에 맞았나? Y: 물체를 저장하고, 해당 위치를 저장 N: 스킵)
마우스를 뗀다(아직도 Ray가 저장된 물체 위에 있나? Y: 안잘린다 N: 자르는 함수 실행)

2. Collider를 이용
-> 이것이 현재 사용되는 방법입니다. 어떤 물체에 rigidbody와 collider를 붙이고, OnCollisionEnter(Collision col)에서 col.contacts를 통해 충돌 위치들을 저장합니다
마찬가지로 OnCollisionExit(Collision col) col.contacts를 통해 빠져나갈때의 충돌 위치를 저장합니다.
이러면 어느위치에서부터 어느 위치까지 칼을 지나게했는지 알 수 있습니다.
이 두 점을 바탕으로 물체를 자르는 것입니다.

실제 물체 자르기 동작

한 오브젝트는 다음과 같이 이루어져 있습니다. Vertices, Triangles, Normals, Tangents, uv 등등 몇가지 더 추가요소가 있습니다만, 현재는 Vertex, triangle, normal
 만이 조작되는 상태입니다.
Vertices는 점을 의미합니다.
Triangles는 int형 배열인데, 어떤 vertex가 한 삼각형을 이루는지 알려주는 배열입니다.
3단위로 끊어 읽어야 합니다. 또한 사용자가 바라보는 방향에서  시계방향으로 값을 넣어줘야 보입니다. 
Normal은 vertices와 1:1매칭이되는 vector3형 배열입니다. 

위에서 한 동작은 자르는 기준을 마련하는 행동이었습니다. 따라서 이제는 어떻게 실제로 자르는지를 지정해줘야 하는데, 이는 Unity에서 제공하는 Plane을 사용하여 구현하였습니다. 물체를 지나는 점의 시작과 끝, 추가로 정한 (검의 위치 혹은 플레이어 위치)를 토대로 평면(P)을 하나 생성합니다.

해당 물체의 triangle들을 순차적으로 돌면서 그에 매치되는 점들을 가져와 3점이 모두 P의 양(+)/음(-)의 방향에 있다면 Plane 기준으로 Mesh A(+),B(-)에 저장합니다.
만일 모두 음/양의 방향이 아니라면 그 삼각형은 평면에 의해 잘리는 것으로 판단되어, 동일한 방향의 점 S1,S2 와 한개의 다른 점 O1 를 잇는 선을 그어 평면과의 교점을 C1,C2라고 잡습니다.  그러면 다음과 같은 생각을 할 수 있습니다.

1. S1,S2,C1,C2를 바탕으로 새로운 삼각형 2개를 구성하기
2. O1,C1,C2를 바탕으로 새로운 삼각형 1개를 구성하기

위의 2가지를 구현하면, 깔끔하게 물체를 자를 수 있게 됩니다.
위의 2가지 점에서 상세하게 고려해야 할 것은 

1. 시계방향의 판정
2. (S1,S2), (O1)이 각각 A,B 어느 Mesh에 속하게 되는가. 

2번은 1번에 비해서 상당히 쉬운 문제입니다.
제일 큰 문제는 시계방향의 판정이라고 볼 수 있습니다.
시계방향의 판정은 해당 점들의 평균값을 구하고, 한 vertex의 normal값을 가져와 그에 따라 시계방향으로 정렬한 뒤, vertices와 triangles를 구성해주는 방법이 있습니다.

단, 위의 방법은 재정렬을 지속적으로 하는 것이므로 약간의 성능 부하의 가능성이 존재합니다. 따라서, 다음과 같이 생각해 봅시다.

1. S1과 P1, O1은 한 직선 위에 존재한다.
2. S2와 P2, O1은 한 직선 위에 존재한다.
3. normal 값을 알 수 있다.

위의 세 조건을 통해, 재정렬을 하지 않아도  충분히 if else 문으로만 처리를 가능합니다.
(S1,S2,C1,C2)로 이루어지는 사각형의 경우 두 삼각형은 항상 다음과 같은 세트로 존재합니다 (S1,S2,C1), (S2,C1,C2). 이해가 안가신다면 그려보시는게 편합니다.
여튼, 각 세트를 3점을 토대로 plane을 생성합니다. new plane(S1,S2,C1) 하고, 생성한 plane의 normal값과 저희가 알고있는 normal 값의 dot product가 +라면 제대로 생성된 것이고, 아니라면 역순으로 지정해주시면 됩니다.

이러한 방법을 통해 깔끔하게 물체를 자르 실 수 있습니다.

면 매꾸기
- 면을 매꾸는 방법은 볼록 물체에선 쉽습니다. 
생각해야 할 것은 다음과 같습니다.
1. 새로생긴 점들
2. 새로생길 면의 방향
3. normal값 설정해주기.
위의 3가지를 처리하면 물체를 배는 면이 매꿔지는 것을 처리할 수 있습니다.



'[Unity3D]' 카테고리의 다른 글

UI 제작.  (0) 2012.10.11
[UNITY3D] 면 뒤집힘 현상.  (1) 2012.08.22
자르기 구현  (2) 2012.05.25
Editor에서 변경한 자료가 반영이 안될때.  (0) 2012.05.17
자체개발 카메라 애니메이션  (0) 2012.05.10
AND

ARTICLE CATEGORY

목록들 (118)
[Unity3D] (39)
그래픽관련 (13)
잉여잉여 (25)
프로그래밍 (27)
노래♬ (3)
Game_Design(기획) (3)

RECENT ARTICLE

RECENT COMMENT

RECENT TRACKBACK

CALENDAR

«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

ARCHIVE