Picking은 마우스를 클릭했을 때 클릭한 화면의 좌표를 통해 어떤 삼각형을 선택했는지 확인할 수 있다.
D3DXIntersectTri함수는 정점3개와 Ray의 시작점, 방향벡터를 받아
Ray의 시작점부터 정점 3개가 이루는 평면의 충돌여부와 충돌점까지의 거리를 알 수 있다.
우리는 VIBuffer안에서 D3DXIntersectTri함수를 통해 버퍼의 어떤 삼각형과 충돌했는지 알아낼 것이다.
VIBuffer 내부에서 계산해야하므로 마우스를 클릭한 지점으로 쏘는 Ray를 VIBuffer의 로컬 좌표계까지
변환해야한다. 마우스 클릭은 뷰포트부터 이루어지므로 로컬좌표계까지는 긴 여정이 될 것이다.
뷰포트 -> NDC
vMousePos.x = ptMouse.x / (rcClient.right * 0.5f) - 1.f;
vMousePos.y = -ptMouse.y / (rcClient.bottom * 0.5f) + 1.f;
vMousePos.z = 0.f; /* near평면을 클릭하였기 때문에. */
(0~WinSizeX,0~WinSizeY) 뷰포트 좌표계에서 (-1~1,-1~1)인 NDC좌표계로 변환한다.
NDC-> 뷰 스페이스
_float4x4 ProjMatrix;
m_pGraphic_Device->GetTransform(D3DTS_PROJECTION, &ProjMatrix);
D3DXMatrixInverse(&ProjMatrix, nullptr, &ProjMatrix);
/* 뷰스페이스 상의 마우스 위치. */
D3DXVec3TransformCoord(&vMousePos, &vMousePos, &ProjMatrix);
m_vMouseRayPos = _float3(0.f, 0.f, 0.f);
m_vMouseRay = vMousePos - m_vMouseRayPos;
그리고 뷰 스페이스로 변환하기 위해 프로젝션 행렬의 역행렬을 MousePos(마우스 좌표)에 곱한다.
TransformCoord로 곱해야 하는 이유가 좌표 변환 관련해서 뭐 있었는데 아직은 정확히 모르겠다 ㅇㅇ..
ray의 시작점 mouseraypos(mouseray시작점)는 카메라이기 때문에 뷰스페이스에서의 카메라의 위치는 원점이다.
ray의 방향벡터는 그래서 vMousePos 자체이다.
그 후로 월드 변환, 로컬 변환은 같은 방식으로 뷰 변환 행렬의 역행렬, 월드 변환 행렬의 역행렬을 곱해주면 된다.
mouseraypos는 위치벡터니까 coord로 ray는 방향벡터니까 normal로 곱해주면 된다.
_bool CPicking::Intersect_Triangle_InLocal(const _float3 * pPointA, const _float3 * pPointB, const _float3 * pPointC, _float3 * pOut)
{
_float fU, fV, fDist;
_bool isColl = { false };
isColl = (_bool)D3DXIntersectTri(pPointA, pPointB, pPointC, &m_vMouseRayPos_Local, &m_vMouseRay_Local, &fU, &fV, &fDist);
if (true == isColl)
{
*pOut = m_vMouseRay_Local * fDist + m_vMouseRayPos_Local;
}
return isColl;
}
ㅈ
그리고 D3DXIntersectTri함수에서 정점 3개와 mouseraypos,mouseray를 받는데, fU, fV, fDist가 결과로 나온다.
fU와 fV는 0->1번째 정점에서 충돌점의 비율, 0->2번째 정점에서 충돌점의 비율인데 중요하지는 않다.
중요한 건 fDist, mouseraypos에서 충돌점까지의 거리이다. D3DXIntersectTri의 반환 값은 bool로
아예 충돌하지 않는다면 false, 거리가 멀더라도 충돌한다면 true를 반환한다.
충돌점의 좌표는 mouseraypos + mouseray*fDist로 구할 수 있다.
'Today I Learned' 카테고리의 다른 글
| 23.06.14 - 알파 테스팅, 알파 블렌딩에서 정렬 (0) | 2023.06.14 |
|---|---|
| 23.06.12 - Cube Mapping, Skybox (0) | 2023.06.12 |
| 23.06.08 - 빌보드, 평면의 방정식을 이용한 지형 타기 (0) | 2023.06.08 |
| 23.06.07 - SetSamplerState, MipMap(밉맵), 높이 맵 (0) | 2023.06.07 |
| 23.05.30 - 직교 투영 행렬 만들기 (0) | 2023.05.30 |