Browse Source

Merge othographic and perspective camera component

master
Riyyi 4 years ago
parent
commit
543814c63c
  1. 15
      inferno/src/inferno/scene/components.h
  2. 9
      inferno/src/inferno/scene/scene.cpp
  3. 70
      inferno/src/inferno/systems/camera.cpp
  4. 4
      inferno/src/inferno/systems/camera.h

15
inferno/src/inferno/scene/components.h

@ -29,17 +29,24 @@ namespace Inferno {
glm::mat4 transform { 1.0f }; // Identity matrix
};
struct OrthographicCameraComponment {
enum CameraType {
Orthographic,
Perspective,
};
struct CameraComponent {
CameraType type = CameraType::Perspective;
// Orthographic
float zoomLevel = 1.0f;
glm::vec3 rotateAxis { 0.0f, 0.0f, 1.0f };
glm::mat4 projection { 1.0f }; // Identity matrix
};
struct PerspectiveCameraComponent {
// Perspective
float fov = 90.0f;
float pitch = 0.0f;
float yaw = -90.0f;
glm::vec3 up { 0.0f, 1.0f, 0.0f };
glm::mat4 projection { 1.0f }; // Identity matrix
};

9
inferno/src/inferno/scene/scene.cpp

@ -23,17 +23,10 @@ namespace Inferno {
cameraSystem->initialize();
CameraSystem::the().setRegistry(m_registry);
#if 1
Entity camera = createEntity("Camera Entity");
camera.add<PerspectiveCameraComponent>();
camera.add<CameraComponent>();
auto& cameraTransform = camera.get<TransformComponent>();
cameraTransform.translate.z = 1.0f;
#else
Entity camera = createEntity("Camera Entity");
camera.add<OrthographicCameraComponment>();
auto& cameraTransform = camera.get<TransformComponent>();
cameraTransform.translate.z = -1.0f;
#endif
RenderSystem* renderSystem = new RenderSystem();
renderSystem->initialize();

70
inferno/src/inferno/systems/camera.cpp

@ -24,16 +24,16 @@ namespace Inferno {
void CameraSystem::update()
{
auto orthoView = m_registry->view<TransformComponent, OrthographicCameraComponment>();
auto view = m_registry->view<TransformComponent, CameraComponent>();
for (auto [entity, transform, orthographic] : orthoView.each()) {
updateOrthographic(transform, orthographic);
}
auto perspectiveView = m_registry->view<TransformComponent, PerspectiveCameraComponent>();
for (auto [entity, transform, camera] : view.each()) {
for (auto [entity, transform, perspective] : perspectiveView.each()) {
updatePerspective(transform, perspective);
if (camera.type == CameraType::Orthographic) {
updateOrthographic(transform, camera);
}
else if (camera.type == CameraType::Perspective) {
updatePerspective(transform, camera);
}
}
}
@ -45,16 +45,10 @@ namespace Inferno {
glm::mat4 CameraSystem::projectionView()
{
auto orthoView = m_registry->view<TransformComponent, OrthographicCameraComponment>();
for (auto [entity, transform, orthographic] : orthoView.each()) {
return orthographic.projection * transform.transform;
}
auto perspectiveView = m_registry->view<TransformComponent, PerspectiveCameraComponent>();
auto view = m_registry->view<TransformComponent, CameraComponent>();
for (auto [entity, transform, perspective] : perspectiveView.each()) {
return perspective.projection * transform.transform;
for (auto [entity, transform, camera] : view.each()) {
return camera.projection * transform.transform;
}
ASSERT_NOT_REACHED();
@ -62,7 +56,7 @@ namespace Inferno {
return glm::mat4 { 1.0f };
}
void CameraSystem::updateOrthographic(TransformComponent& transform, OrthographicCameraComponment& orthographic)
void CameraSystem::updateOrthographic(TransformComponent& transform, CameraComponent& camera)
{
// Update camera rotation
@ -109,13 +103,13 @@ namespace Inferno {
float zoomSpeed = ZOOM_SENSITIVITY * (1.0f / 60.0f);
if (Input::isKeyPressed(KeyCode("GLFW_KEY_EQUAL"))) {
orthographic.zoomLevel -= zoomSpeed;
camera.zoomLevel -= zoomSpeed;
}
if (Input::isKeyPressed(KeyCode("GLFW_KEY_MINUS"))) {
orthographic.zoomLevel += zoomSpeed;
camera.zoomLevel += zoomSpeed;
}
orthographic.zoomLevel = std::max(orthographic.zoomLevel, 0.25f);
orthographic.zoomLevel = std::min(orthographic.zoomLevel, 10.0f);
camera.zoomLevel = std::max(camera.zoomLevel, 0.25f);
camera.zoomLevel = std::min(camera.zoomLevel, 10.0f);
// Update camera matrix
@ -125,39 +119,39 @@ namespace Inferno {
// World space -> View space: view matrix
transform.transform = {
glm::translate(glm::mat4(1.0f), transform.translate) *
glm::rotate(glm::mat4(1.0f), glm::radians(transform.rotate.z), orthographic.rotateAxis)
glm::rotate(glm::mat4(1.0f), glm::radians(transform.rotate.z), camera.rotateAxis)
};
transform.transform = { glm::inverse(transform.transform) };
// View space -> Clip space: projection matrix
float aspectRatio = Application::the().getWindow().getAspect();
orthographic.projection = {
glm::ortho(-aspectRatio * orthographic.zoomLevel, aspectRatio * orthographic.zoomLevel,
-orthographic.zoomLevel, orthographic.zoomLevel, -1.0f, 1.0f)
camera.projection = {
glm::ortho(-aspectRatio * camera.zoomLevel, aspectRatio * camera.zoomLevel,
-camera.zoomLevel, camera.zoomLevel, -1.0f, 1.0f)
};
// Clip space -> Screen space: viewport transform
// Is done in the fragment shader using the settings of glViewport
}
void CameraSystem::updatePerspective(TransformComponent& transform, PerspectiveCameraComponent& perspective)
void CameraSystem::updatePerspective(TransformComponent& transform, CameraComponent& camera)
{
// Get mouse movement offset compared to last frame
float xOffset = Input::getXOffset() * MOUSE_SENSITIVITY;
float yOffset = Input::getYOffset() * MOUSE_SENSITIVITY;
perspective.yaw += xOffset;
perspective.pitch += yOffset;
camera.yaw += xOffset;
camera.pitch += yOffset;
// Prevent gimbal lock
if (perspective.pitch > 89.0f) perspective.pitch = 89.0f;
if (perspective.pitch < -89.0f) perspective.pitch = -89.0f;
if (camera.pitch > 89.0f) camera.pitch = 89.0f;
if (camera.pitch < -89.0f) camera.pitch = -89.0f;
// Update camera rotation, by calculating direction vector via yaw and pitch
transform.rotate = {
cos(glm::radians(perspective.pitch)) * cos(glm::radians(perspective.yaw)),
sin(glm::radians(perspective.pitch)),
cos(glm::radians(perspective.pitch)) * sin(glm::radians(perspective.yaw))
cos(glm::radians(camera.pitch)) * cos(glm::radians(camera.yaw)),
sin(glm::radians(camera.pitch)),
cos(glm::radians(camera.pitch)) * sin(glm::radians(camera.yaw))
};
transform.rotate = glm::normalize(transform.rotate);
// The direction vector is based on
@ -182,11 +176,11 @@ namespace Inferno {
}
if (Input::isKeyPressed(KeyCode("GLFW_KEY_A"))) {
transform.translate = { transform.translate -
glm::normalize(glm::cross(transform.rotate, perspective.up)) * cameraSpeed };
glm::normalize(glm::cross(transform.rotate, camera.up)) * cameraSpeed };
}
if (Input::isKeyPressed(KeyCode("GLFW_KEY_D"))) {
transform.translate = { transform.translate +
glm::normalize(glm::cross(transform.rotate, perspective.up)) * cameraSpeed };
glm::normalize(glm::cross(transform.rotate, camera.up)) * cameraSpeed };
}
// Up / down movement
if (Input::isKeyPressed(KeyCode("GLFW_KEY_SPACE"))) {
@ -202,11 +196,11 @@ namespace Inferno {
// Is done in Object::update()
// World space -> View space: view matrix
transform.transform = { glm::lookAt(transform.translate, transform.translate + transform.rotate, perspective.up) };
transform.transform = { glm::lookAt(transform.translate, transform.translate + transform.rotate, camera.up) };
// View space -> Clip space: projection matrix
float aspect = Application::the().getWindow().getAspect();
perspective.projection = { glm::perspective(glm::radians(perspective.fov), aspect, NEAR_PLANE, FAR_PLANE) };
camera.projection = { glm::perspective(glm::radians(camera.fov), aspect, NEAR_PLANE, FAR_PLANE) };
// Clip space -> Screen space: viewport transform
// Is done in the fragment shader using the settings of glViewport

4
inferno/src/inferno/systems/camera.h

@ -31,8 +31,8 @@ namespace Inferno {
static inline CameraSystem& the() { return *s_instance; }
private:
void updateOrthographic(TransformComponent& transform, OrthographicCameraComponment& orthographic);
void updatePerspective(TransformComponent& transform, PerspectiveCameraComponent& perspective);
void updateOrthographic(TransformComponent& transform, CameraComponent& camera);
void updatePerspective(TransformComponent& transform, CameraComponent& camera);
std::shared_ptr<entt::registry> m_registry;

Loading…
Cancel
Save