본문 바로가기

나만 보는 곳

높이맵 상에서 현재 위치의 y값(높이) 구하기 [DirectX]

a1 ㅡ  a3

  l     ㅣ

a0 ㅡ  a2

 

 4개의 점으로 이루어진 사각형 내에 한 지점(Vector3)의 높이를 알고 싶을 때

 

1단계

 a0, a1, a2 로 이루어진 삼각 폴리곤과 a3, a2, a1로 이루어진 삼각 폴리곤 중 어떤 폴리곤에

속하는 지 알아낸다.

 

Vector3 vPos;                 // 현재 나의 위치

int x = (int)vPos.x;           // 정수 부분

int z = (int)vPos.z;           // 정수 부분

 

float fDeltaX = vPos.x - x; // 소수 부분

float fDeltaZ = vPos.z - z; // 소수 부분

 

( 1.f 로 판단하는 것은 정사각형에서만 가능하다. 직사각형의 경우 다른 식이 필요 )

if(fDeltaX + fDeltaZ < 1.f)

    a0, a1, a2 폴리곤에 속함

else

    a3, a2, a1 폴리곤에 속함

 

2단계

 어떤 폴리곤에 속하는 지 알아냈다면, 이제 높이를 구해줄 수 있다.

 

[ vPos.y : 나의 현재 위치에 해당하는 높이 값 ]

    2-1. a0, a1, a2 폴리곤에 속하는 경우

        Vector3 v01 = a1 - a0;    // a0 -> a1 벡터

        Vector3 v02 = a2 - a0;    // a0 -> a2 벡터

        vPos.y = a0.y + ( fDeltaZ * v01 + fDeltaX * v02  ).y;

 

    2-2 a3, a2, a1 폴리곤에 속하는 경우 

        // 삼각형이 뒤집어져 있으므로, delta값들을 조정해주어야 한다.

        fDeltaX = 1.f - fDeltaX;

        fDeltaZ = 1.f - fDeltaZ;

 

        Vector3 v31 = a1 - a3;    // a3 -> a1 벡터

        Vector3 v32 = a2 - a3;    // a3 -> a2 벡터

        vPos.y = a3.y + ( fDeltaX * v31 + fDeltaZ * v32 ).y;

 

 

 

 

다른 방식) 

    각 폴리곤의 법선을 구해놓은 뒤에 현재 내 포지션의 x, z값을 평면의 방정식을 이용해서 y값을 도출할 수 있다.

평면의 방정식 : n Dot (p0 - pos) = 0

-> n : 법선, p0 : 평면 위의 점, pos : 현재 나의 위치

 

Normal Dot (p0.x - pos.x + p0.y - pos.y + p0.z - pos.z) = 0

Normal.x * (p0.x - pos.x) + Normal.y * (p0.y - pos.y) + Normal.z * (p0.z - pos.z) = 0

따라서, pos.y = (Normal.x * (p0.x - pos.x) + Normal.z * (p0.z - pos.z)) / Normal.y + p0.y