블로그 이미지
이태원에서 사는 다섯식구의 무직 가장. 흰둥에미

카테고리

분류 전체보기 (184)
Itaewon (2)
ryu's?? (1)
20121210이전 (20)
20130827이전 (147)
soo'study (13)
Total34,674
Today8
Yesterday13

'피킹'에 해당되는 글 2건

  1. 2013.04.30 3D 피킹 정리
  2. 2013.04.07 3D Picking

3D 피킹 정리

20130827이전/DX / 2013.04.30 02:18

2D좌표로 부터 3D공간으로의 Ray는 뽑아냈다고 하자.


폴리곤 덩어리들에 대한 피킹

 - 광선이 각 폴리곤들에 대해 충돌하는지 검출


구에 대한 피킹

 1. 구의 방정식을 이용하는 방법

  구의 방정식     x^2 + y^2 + z^2 = r^2 (원점이 구의 중점, cx, cy, cz을 중점으로 하는 경우 (x-cx)^2 + (y-cy)^2 + (z-cz)^2 = r^2가 됨.)

  직선의 방정식  P(t) = Q + Vt

  광선과 구가 교차하는 점에 대한 구의 방정식은 아래와 같다.

  (qx  + vx*t)^2 + (qy  + vy*t)^2 + (qz  + vz*t)^2 = r^2

  이를 전개하여 정리하는 (vx^2+vy^2+vz^2)t^2 + 2(qxvx + qyvy + qzvz)t + (qx^2 + qy^2 + qz^2) - r^2 = 0 이 되고,

  V^2t^2 + 2QVt + Q^2 - r^2 = 0

  이차 방정식 근의 공식을 이용하면 x = ( -b ± sqrt(b^2 - 4ac) ) / 2a 이므로

  t = ( (-Q·V) ± (Q·V)^2 - V^2(Q^2-r^2) ) / V^2 가 된다.

  이때, D < 0이면 근이 존재하지 않음, 즉 구와 광선이 교차하지 않음

  t가 음수라면 반직선의 방향의 반대쪽, 즉 뒤에서 충돌이 있는 것이므로 필요에 따라 예외 처리


 2. 광선의 시작점에서 구의 중점까지의 벡터를 광선에 투영하여 구하는 경우.

  



위 그림을 이용해서 보자.

 1. H에 해당하는 벡터를 광선의 시작점과 구의 중점을 이용하여 구한다.

 2. 구한 H벡터와 광선의 방향에 해당하는 벡터(정규화되어 있음)를 내적하면 R의 길이(광선의 시작점과 구의 C에서 광선에 내린 수선의 발이 만나는 점까지)가 나온다.

   내적한 값이 음수라면 두 벡터가 둔각이기에 절대 충돌하지 않는다고 평가 가능.

 3. H^2 = R^2 + P^2를 이용하여 P를 구할 수 있다.

 4. P가 r보다 크다면, 충돌하지 않은 것이다.

 5. 이때 P와 r이 같다면, 구에 접하는 한점에서 충돌이 있으며, R이 충돌거리가 된다.

 6. 4, 5 모두 아니면, 두점에서 만나게 되는데 Q의 길이를 구할 수 있다.

 7. 직선의 길이는 충돌하는 두점까지의 직선의 길이는 각각 R-Q와 R+Q가 되며, 직선의 방정식에 대입하여, 충돌지점도 구할 수 있음.


구에 대한 피킹은, 오브젝트를 감싸고 있는 경계구에 우선 적용해 최적화를 위해 좋겠다.


피킹 추가

엊그제 본 글이 생각난김에 정리.

오브젝트 아이디의 고유함과 32비트 렌더 타겟을 이용한 패스트 피킹

http://www.gamedevforever.com/261 <--- 요기서 봤습니다.


로직은 참 심플하다.

1. 오브젝트가 렌더링 될 때, 32bit 렌더타겟에 고유 아이디를 그려준다. (이때, 깊이값이 큰것부터 그린다. DX 자체 깊이정렬해주는 것처럼 렌더타겟도 정렬해주는가, 아니면 자동정렬인가 뭐 암튼)

2. 고유 아이디이기에, 렌더 타겟에는 오브젝트의 상이 맺힌다고 볼수 있겠다.

3. 피킹이 필요한 2D 좌표를 인덱스로하여, 렌더타켓에서 얻어온값을 오브젝트 아이디로 바꾸면 바로 그것이 그것이다..

볼 때 감탄을 해서 기억했다가 퍼왔습니다.

문제되면 말씀해주세요. 부끄러워서 퍼간다고 댓글은 못달았습니다-0-;


  



신고

'20130827이전 > DX' 카테고리의 다른 글

collada format parsing  (0) 2013.04.30
생각난김에 스카이 박스 정리  (0) 2013.04.30
3D 피킹 정리  (0) 2013.04.30
3D Picking  (0) 2013.04.07
짐벌락과 그 해결.  (0) 2013.04.03
월드 좌표계로의 변환  (0) 2013.04.01
Posted by 흰둥에미
TAG 광선, 피킹

3D Picking

20130827이전/DX / 2013.04.07 17:45

정점 파이프라인에서 좌표계의 변환과정을 역으로 하면 됨..

광선 추적

말은 쉬움.

월드변환, 카메라변환, 투영, 뷰포트 변환을 역으로...


순서


마우스 좌표를 이용해 뷰포트상의 위치를 구한다.

뷰포트상의 위치를 언프로젝션한다. 이때 z값을 1.0f로 놓으면 ViewFrustum의 farZ값이 나옴.

farZ는 광선의 방향, 광선의 시작위치는 0,0,0로 셋

위 광선벡터를 View 변환행렬의 역행렬을 이용해 월드좌표계로 변환(이 변환에서 시작위치는 카메라의 위치가 됨)

광선은 현재 월드좌표계에서의 위치와 방향이므로, 충돌 체크할 오브젝트를 동일한 좌표계로 변환(그 역도 가능)


구체적인 순서

1. ViewPort를 얻어온다.

D3DVIEWPORT9 viewPort;

mouseToViewX    = (mouseX - viewPort.X)*2 / viewPort.Width;

mouseToViewY    = -(mouseY - viewPort.Y)*2 / viewPort.Height;

mouseToViewZ    = 1.0f        ///farZ

2. Projection 행렬을 얻어와 언프로젝션

projMatrix;

unprojX    = (mouseToViewX - projMatrix[2][0]) / projMatrix[0][0] * mouseToViewZ;

unprojY    = (mouseToViewY - projMatrix[2][1]) / projMatrix[1][1] * mouseToViewZ;


3. 광선의 시작과 방향셋(뷰 변환이 된 상태에서의 좌표계임)

vectorOrigin    = 0, 0, 0;

vectorDir        = unprojX, unprojY, mouseToView;

viewInverseMatrix;

worldOrigin    = Transform vectorOrigin using viewInverseMatrix;

worldDir        = Transform vectorDir     using viewInverseMatrix;


4. 월드 상에서의 광선이 구해진 상태

이후에는 충돌처리할 폴리곤과, 월드든 로컬이든 좌표계를 맞춰준 후 충돌처리하시오~




신고

'20130827이전 > DX' 카테고리의 다른 글

생각난김에 스카이 박스 정리  (0) 2013.04.30
3D 피킹 정리  (0) 2013.04.30
3D Picking  (0) 2013.04.07
짐벌락과 그 해결.  (0) 2013.04.03
월드 좌표계로의 변환  (0) 2013.04.01
D3DXMATRIX 와 D3DXMATRIXA16  (0) 2013.03.25
Posted by 흰둥에미

최근에 달린 댓글

최근에 받은 트랙백

글 보관함