Merge othographic and perspective camera component

This commit is contained in:
Riyyi
2021-01-18 11:53:17 +01:00
parent e08eec3b36
commit 543814c63c
4 changed files with 47 additions and 53 deletions
+12 -5
View File
@@ -29,17 +29,24 @@ namespace Inferno {
glm::mat4 transform { 1.0f }; // Identity matrix glm::mat4 transform { 1.0f }; // Identity matrix
}; };
struct OrthographicCameraComponment { enum CameraType {
float zoomLevel = 1.0f; Orthographic,
glm::vec3 rotateAxis { 0.0f, 0.0f, 1.0f }; Perspective,
glm::mat4 projection { 1.0f }; // Identity matrix
}; };
struct PerspectiveCameraComponent { struct CameraComponent {
CameraType type = CameraType::Perspective;
// Orthographic
float zoomLevel = 1.0f;
glm::vec3 rotateAxis { 0.0f, 0.0f, 1.0f };
// Perspective
float fov = 90.0f; float fov = 90.0f;
float pitch = 0.0f; float pitch = 0.0f;
float yaw = -90.0f; float yaw = -90.0f;
glm::vec3 up { 0.0f, 1.0f, 0.0f }; glm::vec3 up { 0.0f, 1.0f, 0.0f };
glm::mat4 projection { 1.0f }; // Identity matrix glm::mat4 projection { 1.0f }; // Identity matrix
}; };
+1 -8
View File
@@ -23,17 +23,10 @@ namespace Inferno {
cameraSystem->initialize(); cameraSystem->initialize();
CameraSystem::the().setRegistry(m_registry); CameraSystem::the().setRegistry(m_registry);
#if 1
Entity camera = createEntity("Camera Entity"); Entity camera = createEntity("Camera Entity");
camera.add<PerspectiveCameraComponent>(); camera.add<CameraComponent>();
auto& cameraTransform = camera.get<TransformComponent>(); auto& cameraTransform = camera.get<TransformComponent>();
cameraTransform.translate.z = 1.0f; 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* renderSystem = new RenderSystem();
renderSystem->initialize(); renderSystem->initialize();
+32 -38
View File
@@ -24,16 +24,16 @@ namespace Inferno {
void CameraSystem::update() void CameraSystem::update()
{ {
auto orthoView = m_registry->view<TransformComponent, OrthographicCameraComponment>(); auto view = m_registry->view<TransformComponent, CameraComponent>();
for (auto [entity, transform, orthographic] : orthoView.each()) { for (auto [entity, transform, camera] : view.each()) {
updateOrthographic(transform, orthographic);
if (camera.type == CameraType::Orthographic) {
updateOrthographic(transform, camera);
}
else if (camera.type == CameraType::Perspective) {
updatePerspective(transform, camera);
} }
auto perspectiveView = m_registry->view<TransformComponent, PerspectiveCameraComponent>();
for (auto [entity, transform, perspective] : perspectiveView.each()) {
updatePerspective(transform, perspective);
} }
} }
@@ -45,16 +45,10 @@ namespace Inferno {
glm::mat4 CameraSystem::projectionView() glm::mat4 CameraSystem::projectionView()
{ {
auto orthoView = m_registry->view<TransformComponent, OrthographicCameraComponment>(); auto view = m_registry->view<TransformComponent, CameraComponent>();
for (auto [entity, transform, orthographic] : orthoView.each()) { for (auto [entity, transform, camera] : view.each()) {
return orthographic.projection * transform.transform; return camera.projection * transform.transform;
}
auto perspectiveView = m_registry->view<TransformComponent, PerspectiveCameraComponent>();
for (auto [entity, transform, perspective] : perspectiveView.each()) {
return perspective.projection * transform.transform;
} }
ASSERT_NOT_REACHED(); ASSERT_NOT_REACHED();
@@ -62,7 +56,7 @@ namespace Inferno {
return glm::mat4 { 1.0f }; return glm::mat4 { 1.0f };
} }
void CameraSystem::updateOrthographic(TransformComponent& transform, OrthographicCameraComponment& orthographic) void CameraSystem::updateOrthographic(TransformComponent& transform, CameraComponent& camera)
{ {
// Update camera rotation // Update camera rotation
@@ -109,13 +103,13 @@ namespace Inferno {
float zoomSpeed = ZOOM_SENSITIVITY * (1.0f / 60.0f); float zoomSpeed = ZOOM_SENSITIVITY * (1.0f / 60.0f);
if (Input::isKeyPressed(KeyCode("GLFW_KEY_EQUAL"))) { if (Input::isKeyPressed(KeyCode("GLFW_KEY_EQUAL"))) {
orthographic.zoomLevel -= zoomSpeed; camera.zoomLevel -= zoomSpeed;
} }
if (Input::isKeyPressed(KeyCode("GLFW_KEY_MINUS"))) { if (Input::isKeyPressed(KeyCode("GLFW_KEY_MINUS"))) {
orthographic.zoomLevel += zoomSpeed; camera.zoomLevel += zoomSpeed;
} }
orthographic.zoomLevel = std::max(orthographic.zoomLevel, 0.25f); camera.zoomLevel = std::max(camera.zoomLevel, 0.25f);
orthographic.zoomLevel = std::min(orthographic.zoomLevel, 10.0f); camera.zoomLevel = std::min(camera.zoomLevel, 10.0f);
// Update camera matrix // Update camera matrix
@@ -125,39 +119,39 @@ namespace Inferno {
// World space -> View space: view matrix // World space -> View space: view matrix
transform.transform = { transform.transform = {
glm::translate(glm::mat4(1.0f), transform.translate) * 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) }; transform.transform = { glm::inverse(transform.transform) };
// View space -> Clip space: projection matrix // View space -> Clip space: projection matrix
float aspectRatio = Application::the().getWindow().getAspect(); float aspectRatio = Application::the().getWindow().getAspect();
orthographic.projection = { camera.projection = {
glm::ortho(-aspectRatio * orthographic.zoomLevel, aspectRatio * orthographic.zoomLevel, glm::ortho(-aspectRatio * camera.zoomLevel, aspectRatio * camera.zoomLevel,
-orthographic.zoomLevel, orthographic.zoomLevel, -1.0f, 1.0f) -camera.zoomLevel, camera.zoomLevel, -1.0f, 1.0f)
}; };
// Clip space -> Screen space: viewport transform // Clip space -> Screen space: viewport transform
// Is done in the fragment shader using the settings of glViewport // 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 // Get mouse movement offset compared to last frame
float xOffset = Input::getXOffset() * MOUSE_SENSITIVITY; float xOffset = Input::getXOffset() * MOUSE_SENSITIVITY;
float yOffset = Input::getYOffset() * MOUSE_SENSITIVITY; float yOffset = Input::getYOffset() * MOUSE_SENSITIVITY;
perspective.yaw += xOffset; camera.yaw += xOffset;
perspective.pitch += yOffset; camera.pitch += yOffset;
// Prevent gimbal lock // Prevent gimbal lock
if (perspective.pitch > 89.0f) perspective.pitch = 89.0f; if (camera.pitch > 89.0f) camera.pitch = 89.0f;
if (perspective.pitch < -89.0f) perspective.pitch = -89.0f; if (camera.pitch < -89.0f) camera.pitch = -89.0f;
// Update camera rotation, by calculating direction vector via yaw and pitch // Update camera rotation, by calculating direction vector via yaw and pitch
transform.rotate = { transform.rotate = {
cos(glm::radians(perspective.pitch)) * cos(glm::radians(perspective.yaw)), cos(glm::radians(camera.pitch)) * cos(glm::radians(camera.yaw)),
sin(glm::radians(perspective.pitch)), sin(glm::radians(camera.pitch)),
cos(glm::radians(perspective.pitch)) * sin(glm::radians(perspective.yaw)) cos(glm::radians(camera.pitch)) * sin(glm::radians(camera.yaw))
}; };
transform.rotate = glm::normalize(transform.rotate); transform.rotate = glm::normalize(transform.rotate);
// The direction vector is based on // The direction vector is based on
@@ -182,11 +176,11 @@ namespace Inferno {
} }
if (Input::isKeyPressed(KeyCode("GLFW_KEY_A"))) { if (Input::isKeyPressed(KeyCode("GLFW_KEY_A"))) {
transform.translate = { transform.translate - 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"))) { if (Input::isKeyPressed(KeyCode("GLFW_KEY_D"))) {
transform.translate = { transform.translate + 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 // Up / down movement
if (Input::isKeyPressed(KeyCode("GLFW_KEY_SPACE"))) { if (Input::isKeyPressed(KeyCode("GLFW_KEY_SPACE"))) {
@@ -202,11 +196,11 @@ namespace Inferno {
// Is done in Object::update() // Is done in Object::update()
// World space -> View space: view matrix // 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 // View space -> Clip space: projection matrix
float aspect = Application::the().getWindow().getAspect(); 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 // Clip space -> Screen space: viewport transform
// Is done in the fragment shader using the settings of glViewport // Is done in the fragment shader using the settings of glViewport
+2 -2
View File
@@ -31,8 +31,8 @@ namespace Inferno {
static inline CameraSystem& the() { return *s_instance; } static inline CameraSystem& the() { return *s_instance; }
private: private:
void updateOrthographic(TransformComponent& transform, OrthographicCameraComponment& orthographic); void updateOrthographic(TransformComponent& transform, CameraComponent& camera);
void updatePerspective(TransformComponent& transform, PerspectiveCameraComponent& perspective); void updatePerspective(TransformComponent& transform, CameraComponent& camera);
std::shared_ptr<entt::registry> m_registry; std::shared_ptr<entt::registry> m_registry;