작업물/DirectX 11

[ DirectX11 3D Project ] 카메라의 이동

Lero God 2018. 8. 9. 17:34

DirectX 11 프로젝트 진행한 작업을 정리 해두기 위해 기록 하겠습니다.


이번 글에서는 W, A, S, D 키와 이동키를 눌러 카메라를 움직이는 방법을 정리하겠습니다.


먼저 카메라를 이동시킵니다.  카메라는 바라보는 방향으로 이동합니다. 바라보는 방향을 구하려면 카메라가 바라보는 위치에서 현재 카메라의 위치를 빼주면 나옵니다. 벡터의 방향만 알면 되니까 정규화 합니다. 바라보는 방향벡터를 구했으면 앞과 뒤로 이동할 때 쓸 수 있습니다. 카메라의 바라보는 방향을 구하는 함수는 CameraClass에 추가했습니다.


const XMFLOAT3 CameraClass::GetCameraForwardDirection()
{
	XMFLOAT3 cameraPosition(m_positionX, m_positionY, m_positionZ);
	XMVECTOR cameraPositionVector = XMLoadFloat3(&cameraPosition);
	XMVECTOR lookAtVector = XMLoadFloat3(&m_lookAtVector);
	XMVECTOR directionVector = XMVector3Normalize(lookAtVector - cameraPositionVector);
	XMStoreFloat3(m_forwardDirection, directionVector);

	return *m_forwardDirection;
}


카메라를 왼쪽과 오른쪽으로 이동 시키기 위해선 카메라가 바라보는 방향의 오른쪽 방향을 구해야 합니다. 카메라의 오른쪽 방향벡터는 업벡터와 앞으로 보는 방향벡터를 외적해서 구합니다. 이 벡터도 방향만 알면 되기 때문에 정규화 합니다.


const XMFLOAT3 CameraClass::GetCameraRightDirection()
{
	XMFLOAT3 upDirectrion(0, 1, 0);
	XMVECTOR upVector(XMLoadFloat3(&upDirectrion));
	XMVECTOR rightVector = XMVector3Normalize(XMVector3Cross(upVector, XMLoadFloat3(m_forwardDirection)));
	XMStoreFloat3(m_rightDirection, rightVector);

	return *m_rightDirection;
}


키입력에 대한 처리는 SystemClass에서 합니다. 사용할 키들을 배열에 넣어놓고 각 프레임마다 함수에서 입력을 받았는지 확인합니다. 입력을 받았으면 GraphicsClass의 함수를 호출해서 키에 대한 처리를 맡깁니다. 


void SystemClass::KeyInput()
{
	for (int i = 0; i < MAX_USING_KEYS; ++i)
	{
		if(m_Input->IsKeyPressed(m_usingKeys[i]))
		{
			m_Graphics->KeyInput(m_usingKeys[i]);
		}
	}
}


GraphicsClass에선 받은 키입력의 종류에 맞는 처리를 합니다.


void GraphicsClass::KeyInput(const unsigned int key)
{
	switch (key)
	{
	case DIK_W:
	case DIK_A:
	case DIK_S:
	case DIK_D:
	case DIK_UP:
	case DIK_LEFT:
	case DIK_DOWN:
	case DIK_RIGHT:
	{
		CameraMove(key);
		break;
	}
	}
}


카메라를 이동시키는 함수는 아까 방향벡터를 구하는 함수들을 호출해서 카메라의 위치를 이동 시킵니다. 카메라를 이동 시킬 때 변경해야 하는 값은 카메라의 위치와 카메라가 바라보는 위치 두개입니다.


void GraphicsClass::CameraMove(const unsigned int key)
{
	XMFLOAT3 cameraPosition = m_Camera->GetPosition();
	XMFLOAT3 lookAt = m_Camera->GetLookAtVector();
	XMFLOAT3 cameraForwardDirection = m_Camera->GetCameraForwardDirection();
	XMFLOAT3 cameraRightDirection = m_Camera->GetCameraRightDirection();

	switch (key)
	{
	case DIK_W:
	case DIK_UP:
	{
		cameraPosition.x += cameraForwardDirection.x * 0.05f;
		cameraPosition.y += cameraForwardDirection.y * 0.05f;
		cameraPosition.z += cameraForwardDirection.z * 0.05f;
		lookAt.x += cameraForwardDirection.x * 0.05f;
		lookAt.y += cameraForwardDirection.y * 0.05f;
		lookAt.z += cameraForwardDirection.z * 0.05f;
		break;
	}

	case DIK_A:
	case DIK_LEFT:
	{
		cameraPosition.x -= cameraRightDirection.x * 0.05f;
		cameraPosition.y -= cameraRightDirection.y * 0.05f;
		cameraPosition.z -= cameraRightDirection.z * 0.05f;
		lookAt.x -= cameraRightDirection.x * 0.05f;
		lookAt.y -= cameraRightDirection.y * 0.05f;
		lookAt.z -= cameraRightDirection.z * 0.05f;
		break;
	}

	case DIK_S:
	case DIK_DOWN:
	{
		cameraPosition.x -= cameraForwardDirection.x * 0.05f;
		cameraPosition.y -= cameraForwardDirection.y * 0.05f;
		cameraPosition.z -= cameraForwardDirection.z * 0.05f;
		lookAt.x -= cameraForwardDirection.x * 0.05f;
		lookAt.y -= cameraForwardDirection.y * 0.05f;
		lookAt.z -= cameraForwardDirection.z * 0.05f;
		break;
	}

	case DIK_D:
	case DIK_RIGHT:
	{
		cameraPosition.x += cameraRightDirection.x * 0.05f;
		cameraPosition.y += cameraRightDirection.y * 0.05f;
		cameraPosition.z += cameraRightDirection.z * 0.05f;
		lookAt.x += cameraRightDirection.x * 0.05f;
		lookAt.y += cameraRightDirection.y * 0.05f;
		lookAt.z += cameraRightDirection.z * 0.05f;
		break;
	}
	}

	m_Camera->SetPosition(cameraPosition);
	m_Camera->SetLookAtVector(lookAt);
}



이제 매 프레임마다 키 입력을 받았는지 확인해 W, A, S, D, 화살표 키를 눌렀을 때 카메라를 이동 시킬 수 있습니다. 다음은 카메라를 회전시키는 작업을 하겠습니다.



'작업물 > DirectX 11' 카테고리의 다른 글

[ DirectX11 3D Project ] 카메라 줌인, 줌아웃, 회전  (0) 2018.08.24