블로그는 나의 힘!
[ Programing ]/DirtectX92010. 1. 29. 10:03
피킹 이란?
☞ View 포트의 2D좌표로 지정된 장소에 있는 비주얼 개체를 장면 내에서 찾는 것.

종류
Ray Pick - 마우스 좌표에서 z축으로 레이를 쏴 해당하는 object를 찾아 내는 방법.
•.Dot Pick - 마우스 좌표를 점으로 적용해 object를 찾아 내는 방법.
Buffer Pick - 마우스 좌표 피킹한 것을 버퍼에 저장, 해당 오브젝트만 검색해서 빨리 찾아 내는 방법.

피킹 과정
1 ) 로컬 좌표계 상에서 정의된 3D 객체의 정점들을 화면 좌표계 기준으로 변환한다.
2 ) 마우스의 위치를 얻는다.    ( 화면 좌표계 기준으로 )  
3 ) 변환된 3D 객체의 화면 좌표계 상의 범위(Object)와 마우스의 위치를 비교해 점이 Object 안에 포함됐는지를 판별 한다.



1. 3D 객체의 정점들을 화면 좌표계 기준으로 변환 
첫째, 기본적 공식 파이프 라인 중.
P' = P * World * View * Projection
로컬 좌표계 정점( P )가 투영 좌표계 기준( P' )되기까지  렌더링 파이프라인 과정을 나타낸 것
곱하는 순서대로 월드, 뷰, 투영 변환 

둘째, View와  Projection 값을 가져온다.
g_pd3dDevice->SetTransform( D3DTS_VIEW, matView ); 
Direct3D 에서는 각각의 파이프라인 변환들을 SetTransform()으로 View 지정
마찬가지로 Projection 값도 가져 온다.

셋째, 해당 공식을 이용 하여,
MATRIXA16 matResult;  
matResult = g_matWorld * g_matView * g_matProj;  
D3DXVec3TransformCoord( &vertex, &vertex, &matResult ); 
P' = P * World * View * Projection -> P' = P * matResult
D3DXVec3TransformCoord() 벡터와 행렬을 곱해주는 함수. 
- 인자로 주어진 벡터와 행렬을 곱해 결과(벡터)를 넘겨 변환된 정점( P' )의 위치 값을 구한다. 

넷째, 스크린 좌표 기준으로 전환 한다.
스크린 위치 좌표 = (( -1.0f -투영 좌표 ) /2.0f ) *윈도우 길이 
화면 좌표계 기준으로 정점을 한번 더 변환해야 하는데 파이프 라인 과정에서는 없으므로 직접 구현해야 한다.
ScreenPos.x =  ( -1.0f - vertex.x ) / ( -2.0f ) * WindowWidth; 
얻은 P'는 투영 좌표계로 기준으로 변환된 정점이다. 
투영 변환은 무조건 카메라 절두체를 ( -1,-1,-1 ) 과 ( 1, 1, 1 )범위의 정육면체로 만들어 버린다. 
절두체가 -1.0f 과 1.0f 범위를 갖게 되니 그 절두체에 포함된 모든 정점 또한 투영 변환 뒤에는 -1.0f 와 1.0f 의 범위를 갖게 된다



2. 마우스의 위치 
POINT pt;
    RECT Rect;
    GetCursorPos( &pt );           // 마우스 커서의 화면 좌표.GetWindowRect( g_hwnd,&Rect);   // 윈도우 사이즈 및 위치.
    float DX = pt.x - Rect.left;     // 윈도우 기준으로 바꿈.  float DY = pt.y - Rect.top;            
    pt.x = DX;pt.y = DY;

- 다음으로 마우스 포인트 위치를 화면 좌표계 기준으로 얻어온다.
- API 함수를 통해 바로 받아 올수 있다.
- 전역( 전체 화면 ) 좌표를 윈도우 기준의 좌표로 변환한다.



3. Object 안에 포함됐는지를 판별 
1 번 과정에서 로컬 좌표계로 정의된 3D 객체의 정점들을 화면 좌표계 기준( 2D )으로 바꿨으며,
2 번 과정에서 마우스로 선택한 지점을 화면 좌표계 기준으로 얻어왔다.

이제 남은 일은 2번에서 얻은 마우스 포인트 좌표를 1번에 적용해 변환 후 얻은 영역에 포함 되는 지 판별하기만 하면 된다.





참고 자료 : GP로 막가 블로그
http://blog.naver.com/kzh8055/140053041553        - [3D Programming] 피킹( Picking ) 기법 
http://blog.naver.com/kzh8055/140053121675        - 점과 선분 과의 관계 - 2차원에서 점이 다각형 안에 포함되는지 판별


※ 해당 자료 및 소스[카테고리 - 공부 - 기타]'피킹_Q강의'라고 있으니 참고 하실분들은 참고 하시길 바란다.

Posted by Mister_Q