이전에 행렬에 대한 포스팅을 한 적이 있다.
카메라를 알고 싶다면 행렬을 먼저 알아야 한다.
[행렬 포스팅] https://velog.io/@invisible_thorn/%EC%88%9C%EC%84%9C%EA%B0%80-%EC%A4%91%EC%9A%94%ED%95%98%EB%8B%A4%EA%B3%A0-y6883q5q
참고 해주십사
class Scene : public Component // transform
{
public:
Scene();
virtual ~Scene();
Scene* m_pParentScene = nullptr;
Vector2F m_RelativeScale = { 1,1 }; // 상대 크기
float m_RelativeRotation = 0; // 상대 회전
Vector2F m_RelativeLocation = { 0,0 }; // 상대 위치
D2D1_MATRIX_3X2_F m_RelativeTransform; // 상대 복합 변환
D2D1_MATRIX_3X2_F m_WorldTransform; // 부모 반영 최종 변환
void SetParent(Scene* pParentScene) { m_pParentScene = pParentScene; }
Vector2F GetWorldLocation()
{
Vector2F out;
out.x = m_WorldTransform._31;
out.y = m_WorldTransform._32;
return out;
}
virtual void Update();
virtual void Render();
};
Scene::Scene()
{
m_RelativeTransform = m_WorldTransform = D2D1::Matrix3x2F::Identity();
}
Scene::~Scene()
{
}
void Scene::Update()
{
// 행렬 공식 -> 상대 복합 변환
m_RelativeTransform =
D2D1::Matrix3x2F::Scale(D2D1::SizeF(m_RelativeScale.x, m_RelativeScale.y))
* D2D1::Matrix3x2F::Rotation(m_RelativeRotation)
* D2D1::Matrix3x2F::Translation(m_RelativeLocation.x, m_RelativeLocation.y);
if (m_pParentScene != nullptr)
{
m_WorldTransform = m_RelativeTransform * m_pParentScene->m_WorldTransform;
}
else m_WorldTransform = m_RelativeTransform;
}
void Scene::Render()
{
}
우선 로컬좌표계를 구해준다.
m_RelativeTransform =
D2D1::Matrix3x2F::Scale(D2D1::SizeF(m_RelativeScale.x, m_RelativeScale.y))
* D2D1::Matrix3x2F::Rotation(m_RelativeRotation)
* D2D1::Matrix3x2F::Translation(m_RelativeLocation.x, m_RelativeLocation.y);
이전 행렬 포스팅에서도 언급했듯이
Scale, Rotation, Translation 순서를 지켜 행렬 곱을 구한다.
그리고 이렇게 로컬좌표를 갖는 오브젝트가 따라다니는 부모 오브젝트가 있다면
로컬 좌표와 부모 오브젝트의 월드 좌표를 곱해 해당 자식 오브젝트의 월드 좌표를 구할 수 있다.
부모가 없는 경우는 로컬 좌표가 월드 좌표가 된다.
패드립 아님
그럼 이제 카메라의 위치를 알아보자!
class CameraScene : public Scene
{
public:
D2D1_MATRIX_3X2_F m_CameraMatrix;
virtual void Update();
};
void CameraScene::Update()
{
__super::Update();
m_CameraMatrix = m_WorldTransform
* D2D1::Matrix3x2F::Translation(-SCREEN_WIDTH * 0.5f, -SCREEN_HEIGH * 0.5);
// 카메라의 바운드 박스
GetOwner()->m_BoundBox.m_Extend.x = SCREEN_WIDTH * 0.5f;
GetOwner()->m_BoundBox.m_Extend.y = SCREEN_HEIGH * 0.5f;
// 카메라의 WorldTransform을 역행렬 -> 카메라의 이동과 오브젝트의 이동은 반대
D2D1InvertMatrix(&m_CameraMatrix);
}
(카메라의) 월드 행렬에 어떠한 값을 곱하면 단위행렬이 나오는 데, 이때 어떠한 값은 카메라의 역행렬이다.
일단 translation의 변화만 있을 때는 -camerapos.x, -camerapos.y 를 해주고자 하는 것이다.
물체와 카메라의 이동방향을 생각해보자.
화면에 물체가 있을 때 카메라를 오른쪽으로 움직이면 물체는 왼쪽으로 가는 것처럼 보인다.
즉, 카메라의 반대 방향으로 translation값을 주면 되는 것이다.
(3행 1열, 2열만 변경됨)
여기에 컬링 개념까지 붙여 카메라 - 물체간의 콜라이더를 체크한다면
센터 행렬 * 오브젝트의 행렬(이미지) * 월드 좌표 * 카메라의 역행렬 연산을 함으로서 가능해진다.
3D 카메라의 변환 파이프라인은 여기서 연산이 추가되는데 이는 D3D 엔진을 만들면서 추가로 작성해볼 예정이다. ㅇㅅㅇ