지형위에 플레이어 띄우기
엔진 프로젝트의 트랜스폼 클래스에서 새로운함수를 만들자
(지형위에 올리는 기능)
void Stand_OnTerrain(class CVIBuffer_Terrain pVIBuffer,_matrix pTerrainWorldMatrix)
-위치정보를 받아야함(트랜스폼 클래스 안에있음)
-버퍼에 대한 정보필요(VI버퍼를 받아오자)
-지형의 월드 좌표를 받아오자.
Get_State(CTranfrom::STATE_POSITIION)을 통해 월드 포지션을 가져오자.
인자로받아온 pTerrainWorldMatrix의 역행렬 구하자.(D3DXMatrixInverse 이용)
D3DXVec3TranformCoord(월드포스,터레인매트릭스의 역) 으로 곱해주자.
-3차원 벡터에 4번쨰인자 1을 추가해 연산을 수행해준다.(위치가 적용됨)
이를 통해 지형의 로컬포스로 구할수있다.
Get_Plain()
어떤 정보를 리턴해줘여 할까?
점의 좌표? -> 플레이어는 월드좌표지만 버텍스들은 현재 로컬좌표다.(이때문에 Stand_OnTerrain에서 월드 좌표를 받는다).
플레이어의 로컬위치 * 플레이어의 월드행렬 = 월드행렬안에있다.
월드 행렬 * 지형 월드행렬의 역행렬 = 로컬 위치를 구할수있다.
어떤 폴리곤위에있는지 구해보자
네컨_프로토 에서 받은 fInterval을 멤버변수로 저장해두자.
복사본으로 진행하기때문에 복사생성자에서 m_fInterval복사해주자.
VerticesX,Z 도 해주자!
_uint iIndex 연산해주자 (이때 꼭 인트로 형변환 해주어야한다!)
타일의 인덱스는 왼쪽 하단 정점의 인덱스이다 이걸로 세점의 인덱스를 구할수있다.
iIndices를 선언해주자. 인덱스의 4개점을 보관한다.
인터벌이 1이니 직선의방정식과 내적을 이용하지 않아도 구할수있다.
인터벌 - 플레이어 인덱스.x > 인터벌 - 플레이어.y 라면 위 삼각형 아니라면 반대이다.
락함수는 프레임드랍이 매우 심하다. -> 속도를위해 메모리를 좀더 소모하자.
멤버변수 pVerticesPos를 사용하자. 모든 버텍스버퍼의 위치를 저장하기위한 배열이다.[NumVertices] 만큼 크기를 할당해주자.
네컨프로토에서 동적할당하고 제로메모리로 초기화.
버텍스 버퍼를 채울때 여기에다도 저장해주자!
복사생성자에서 얕은복사로 넘겨주자.(지울때 조심해야한다)
->원본에서 지워질때만 Safe_Delete해줘야한다.
->클론인지 알기위해 컴포넌트에 불변수 하나 추가 이걸로 클론인지를 판별하자.
->컴포넌트 기본생성자에선 이를 false로 복사생성자에선 true로 넣어주자!
다시 Get_Plane으로 돌아와서
내 정점의 위치에서 버텍스정점의 위치를 빼서 RatioX,Z를 구하자
(Z는 버텍스 정점에서 내 정점의 위치를 빼자)
X>Z 라면 위쪽 우상단 삼각형
{
//점 세개를 알고있으므로 D3DXPlaneFromPoints로 평면을 구해주자 이때 넣어주는 순서는 꼭 시계방향이어야한다.
//m_pVertices에서 버텍스르 꺼내서넘겨주자.
]
위해서 구한 평면을 리턴해주자.
VI버퍼 터레인 헤더 추가해주자.
Get_Plane 구현 끝.
트랜스폼 클래스의 Stand_OnTerrain 함수로 돌아가자.
Get_Plane 함수를 통해 평면을 리턴받았다.
/지형 로컬에서 플레이어가 지형위에 있을때의 XYZ를 구하자./
D3DXPlaneDotCoord
a b c d
x y z 1 - >평면방정식에 특정좌표를 넣은값 즉 평면과 좌표간의 거리를 구해주는 함수다.
이거리를 vLocalPos.y에서 빼주면 지형위에있는 y를 구할수있다.
이를 지형의 월드 매트릭스와 곱해주고 트랜스폼에서 셋_스테이트해주자.
플레이어에서 함수 호출
CPlayer의 Tick 함수에 Stand_OnTerrain함수를 호출해주자.
게임인스턴스를 통해 터레인의 컴포넌트를 가져오자.(CVIBuffer_Terrain)
이번엔 지형의 트랜스폼 가져오자.
후면출력 켜주고
Desc안넘겨주고있다 넘겨주게 수정하자.