Program Listing for File PolarCamera.cpp¶
↰ Return to documentation for file (Source\Camera\Src\PolarCamera.cpp
)
#include "Camera/PolarCamera.h"
#include "Math/Transform.h"
#include "Math/Geometry.h"
#include "Utils/Macros.h"
namespace Azura {
namespace {
const Vector3f UNIT_LOOK = Vector3f(0, 0, 1);
const Vector3f UNIT_RIGHT = Vector3f(1, 0, 0);
const Vector3f UNIT_UP = Vector3f(0, 1, 0);
const Vector3f UNIT_EYE = Vector3f(0, 0, 0);
} // namespace
PolarCamera::PolarCamera(U32 width, U32 height)
: Camera(width, height) {
PolarCamera::Recompute();
}
PolarCamera::PolarCamera(U32 width, U32 height, float thethaDeg, float phiDeg, float zoom)
: Camera(width, height), m_theta(Math::ToRadians(thethaDeg)), m_phi(Math::ToRadians(phiDeg)), m_zoom(zoom) {
PolarCamera::Recompute();
}
void PolarCamera::Recompute() {
const Matrix4f transform = Matrix4f::FromRotationMatrix(Matrix4f::RotationY(m_theta)) *
Matrix4f::FromRotationMatrix(Matrix3f::RotationX(m_phi)) *
Matrix4f::FromTranslationVector(Vector3f(0, 0, 1) * m_zoom);
m_look = Transform::Downgrade(transform * Vector4f(UNIT_LOOK, 0.0f));
m_up = Transform::Downgrade(transform * Vector4f(UNIT_UP, 0.0f));
m_right = Transform::Downgrade(transform * Vector4f(UNIT_RIGHT, 0.0f));
// Position must be affected by Translation
m_eye = Transform::Downgrade(transform * Vector4f(UNIT_EYE, 1.0f));
m_view = Transform::LookAt(m_ref, m_eye, m_up);
m_proj = Transform::Perspective(45.0f, 16.0f / 9.0f, 0.1f, 100.0f);
m_viewProj = m_proj * m_view;
m_invViewProj = m_viewProj.Inverse();
}
void PolarCamera::OnMouseEvent(MouseEvent mouseEvent) {
if (mouseEvent.m_internalType != MouseEventType::Drag)
{
return;
}
const float anglePerPixel = 5;
RotateAboutUp(mouseEvent.m_eventX * anglePerPixel * m_sensitivity);
RotateAboutRight(mouseEvent.m_eventY * anglePerPixel * m_sensitivity);
Recompute();
}
void PolarCamera::OnKeyEvent(KeyEvent keyEvent) {
if (keyEvent.m_internalType == KeyEventType::KeyPress) {
switch (keyEvent.m_key) {
case KeyboardKey::W:
m_moveUpFactor = 1;
break;
case KeyboardKey::S:
m_moveUpFactor = -1;
break;
case KeyboardKey::D:
m_moveRightFactor = -1;
break;
case KeyboardKey::A:
m_moveRightFactor = 1;
break;
case KeyboardKey::Q:
m_zoomFactor = 1;
break;
case KeyboardKey::E:
m_zoomFactor = -1;
break;
case KeyboardKey::Unmapped:
case KeyboardKey::Esc:
case KeyboardKey::Up:
case KeyboardKey::Down:
case KeyboardKey::Left:
case KeyboardKey::Right:
case KeyboardKey::T:
case KeyboardKey::Y:
default:
break;
}
} else if (keyEvent.m_internalType == KeyEventType::KeyRelease) {
switch (keyEvent.m_key) {
case KeyboardKey::W:
m_moveUpFactor = 0;
break;
case KeyboardKey::S:
m_moveUpFactor = 0;
break;
case KeyboardKey::D:
m_moveRightFactor = 0;
break;
case KeyboardKey::A:
m_moveRightFactor = 0;
break;
case KeyboardKey::Q:
m_zoomFactor = 0;
break;
case KeyboardKey::E:
m_zoomFactor = 0;
break;
case KeyboardKey::Unmapped:
case KeyboardKey::Esc:
case KeyboardKey::Up:
case KeyboardKey::Down:
case KeyboardKey::Left:
case KeyboardKey::Right:
case KeyboardKey::T:
case KeyboardKey::Y:
default:
break;
}
}
}
void PolarCamera::SetZoom(float value) {
m_zoom = value;
}
void PolarCamera::SetZoomAndRecompute(float value) {
SetZoom(value);
Recompute();
}
void PolarCamera::RotateAboutUp(float deg) {
m_theta += Math::ToRadians(deg);
}
void PolarCamera::RotateAboutRight(float deg) {
m_phi += Math::ToRadians(deg);
}
void PolarCamera::TranslateAlongLook(float amount) {
m_zoom += amount;
}
void PolarCamera::SetStepSize(float value) {
m_stepSize = value;
}
void PolarCamera::Update(float timeDelta) {
const float distance = m_stepSize * timeDelta;
bool needsRecompute = false;
if (m_moveUpFactor != 0) {
RotateAboutRight(distance * m_moveUpFactor);
needsRecompute = true;
}
if (m_moveRightFactor != 0) {
RotateAboutUp(distance * m_moveRightFactor);
needsRecompute = true;
}
if (m_zoomFactor != 0) {
TranslateAlongLook(distance * m_zoomFactor);
needsRecompute = true;
}
if (needsRecompute) {
Recompute();
}
}
} // namespace Azura