Created
October 10, 2021 19:01
-
-
Save Journeyman1337/46f47de48370718ca0a300766ed17b14 to your computer and use it in GitHub Desktop.
camera and transform
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "Camera.hpp" | |
Camera::Camera() : view_changed(true), view_matrix(1.0f), projection_changed(true), projection_matrix(1.0f), view_projection_changed(true), view_projection_matrix(1.0f), projection(Projection::Orthographic), orthographic_size(0.0f), perspective_fov(90.0f), screen_dimensions(1.0f, 1.0f) | |
{ | |
} | |
const glm::mat4& Camera::GetViewMatrix() | |
{ | |
if (this->view_changed == true) | |
{ | |
this->view_matrix = glm::lookAt(this->position, this->position + this->GetForwardDirection(), this->position + this->GetUpDirection()); | |
this->view_changed = false; | |
this->view_projection_changed = true; | |
} | |
return this->view_matrix; | |
} | |
const glm::mat4& Camera::GetProjectionMatrix() | |
{ | |
if (this->projection_changed == true) | |
{ | |
if (this->projection == Projection::Perspective) | |
{ | |
this->projection_matrix = glm::perspectiveFov(this->perspective_fov, this->screen_dimensions.x, this->screen_dimensions.y, 0.1f, 100.0f); | |
} | |
else if (this->projection == Projection::Orthographic) | |
{ | |
float orthographic_width = this->orthographic_size * screen_dimensions.x; | |
float orthographic_height = this->orthographic_size * screen_dimensions.y; | |
this->projection_matrix = glm::ortho(orthographic_width / 2, orthographic_width / 2, -orthographic_height / 2, orthographic_height / 2); | |
} | |
this->projection_changed = false; | |
this->view_projection_changed = true; | |
} | |
return this->projection_matrix; | |
} | |
const glm::mat4& Camera::GetViewPorjectionMatrix() | |
{ | |
if (this->view_changed == true || this->projection_changed == true || view_projection_changed == true) | |
{ | |
this->view_projection_matrix == this->GetProjectionMatrix() * this->GetViewMatrix(); | |
this->view_projection_changed = false; | |
} | |
return this->view_projection_matrix; | |
} | |
float Camera::GetPerspectiveFov() const | |
{ | |
return this->perspective_fov; | |
} | |
float Camera::GetOrthographicSize() const | |
{ | |
return this->orthographic_size; | |
} | |
Camera::Projection Camera::GetProjection() const | |
{ | |
return this->projection; | |
} | |
const glm::vec2& Camera::GetScreenDimensions() const | |
{ | |
return this->screen_dimensions; | |
} | |
void Camera::SetProjection(Projection projection) | |
{ | |
this->projection_changed = true; //even if Camera* is casted to Transform*, this still gets set correctly... | |
this->projection = projection; | |
} | |
void Camera::SetPerspectiveFov(float fov) | |
{ | |
this->perspective_fov = fov; | |
this->projection_changed = true; | |
} | |
void Camera::SetOrthographicSize(float size) | |
{ | |
this->orthographic_size = size; | |
this->projection_changed = true; | |
} | |
void Camera::SetScreenDimensions(const glm::vec2& dimensions) | |
{ | |
this->projection_changed = true; | |
this->screen_dimensions = dimensions; | |
} | |
void Camera::SetPosition(const glm::vec3& position) | |
{ | |
this->view_changed = true; | |
Transform::SetPosition(position); | |
} | |
void Camera::SetRotation(const glm::quat& rotation) | |
{ | |
this->view_changed = true; | |
Transform::SetRotation(rotation); | |
} | |
void Camera::SetScale(const glm::vec3& scale) | |
{ | |
Transform::SetScale(scale); | |
} | |
void Camera::Translate(const glm::vec3& translation) | |
{ | |
this->view_changed = true; | |
Transform::Translate(translation); | |
} | |
void Camera::Scale(const glm::vec3& scale) | |
{ | |
Transform::Scale(scale); | |
} | |
void Camera::ScaleScalar(const float& scalar) | |
{ | |
Transform::ScaleScalar(scalar); | |
} | |
void Camera::Rotate(const glm::quat& rotation) | |
{ | |
this->view_changed = true; | |
Transform::Rotate(rotation); | |
} | |
void Camera::RotateEuler(const glm::vec3& angles) | |
{ | |
this->view_changed = true; | |
Transform::RotateEuler(angles); | |
} | |
void Camera::LookAt(const glm::vec3& target_position) | |
{ | |
this->view_changed = true; | |
Transform::LookAt(target_position); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include "Transform.hpp" | |
#include <glm/glm.hpp> | |
class Camera : public Transform | |
{ | |
public: | |
enum class Projection | |
{ | |
Perspective, | |
Orthographic | |
}; | |
protected: | |
bool view_changed; | |
glm::mat4 view_matrix; | |
bool projection_changed; | |
glm::mat4 projection_matrix; | |
bool view_projection_changed; | |
glm::mat4 view_projection_matrix; | |
Projection projection; | |
float perspective_fov; | |
glm::vec2 screen_dimensions; | |
float orthographic_size; | |
public: | |
Camera(); | |
~Camera() = default; | |
Camera(const Camera& other) = delete; | |
using Transform::Transform; | |
const glm::mat4& GetViewMatrix(); | |
const glm::mat4& GetProjectionMatrix(); | |
const glm::mat4& GetViewPorjectionMatrix(); | |
float GetPerspectiveFov() const; | |
float GetOrthographicSize() const; | |
Projection GetProjection() const; | |
const glm::vec2& GetScreenDimensions() const; | |
void SetProjection(Projection projection); | |
void SetPerspectiveFov(float fov); | |
void SetOrthographicSize(float size); | |
void SetScreenDimensions(const glm::vec2& dimensions); | |
void SetPosition(const glm::vec3& position) override; | |
void SetRotation(const glm::quat& rotation) override; | |
void SetScale(const glm::vec3& scale) override; | |
void Translate(const glm::vec3& translation) override; | |
void Scale(const glm::vec3& scale) override; | |
void ScaleScalar(const float& scalar) override; | |
void Rotate(const glm::quat& rotation) override; | |
void RotateEuler(const glm::vec3& angles) override; | |
void LookAt(const glm::vec3& target_position) override; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "Transform.hpp" | |
#include "Camera.hpp" | |
#include <glm/ext/quaternion_transform.hpp> | |
#include <glm/gtx/transform.hpp> | |
Transform::Transform() : position(0.0f, 0.0f, 0.0f), rotation(), scale(1.0f, 1.0f, 1.0f), model_changed(true), model_matrix(1.0f) | |
{ | |
} | |
const glm::mat4& Transform::GetModelMatrix() | |
{ | |
if (this->model_changed == true) | |
{ | |
// when you multiply glm objects it goes in opposite order. | |
// first scale, then rotation, then translation. | |
this->model_matrix = glm::mat4(1.0f); | |
glm::scale(this->model_matrix, this->scale); | |
glm::mat4 rotation_matrix = glm::toMat4(this->rotation); | |
this->model_matrix *= rotation_matrix; | |
glm::translate(this->model_matrix, this->position); | |
} | |
return this->model_matrix; | |
} | |
const glm::vec3& Transform::GetPosition() const | |
{ | |
return this->position; | |
} | |
const glm::quat& Transform::GetRotation() const | |
{ | |
return this->rotation; | |
} | |
const glm::vec3& Transform::GetScale() const | |
{ | |
return this->scale; | |
} | |
glm::vec3 Transform::GetEulerAngles() const | |
{ | |
return glm::eulerAngles(this->rotation); | |
} | |
glm::vec3 Transform::GetForwardDirection() const | |
{ | |
return this->rotation * glm::vec3(0.0f, 1.0f, 0.0f); | |
} | |
glm::vec3 Transform::GetBackwardDirection() const | |
{ | |
return this->rotation * glm::vec3(0.0f, -1.0f, 0.0f); | |
} | |
glm::vec3 Transform::GetRightDirection() const | |
{ | |
return this->rotation * glm::vec3(1.0f, 0.0f, 0.0f); | |
} | |
glm::vec3 Transform::GetLeftDirection() const | |
{ | |
return this->rotation * glm::vec3(-1.0f, 0.0f, 0.0f); | |
} | |
glm::vec3 Transform::GetUpDirection() const | |
{ | |
return this->rotation * glm::vec3(0.0f, 0.0f, 1.0f); | |
} | |
glm::vec3 Transform::GetDownDirection() const | |
{ | |
return this->rotation * glm::vec3(0.0f, 0.0f, -1.0f); | |
} | |
void Transform::SetPosition(const glm::vec3& position) | |
{ | |
this->model_changed = true; | |
this->position = position; | |
} | |
void Transform::SetRotation(const glm::quat& rotation) | |
{ | |
this->model_changed = true; | |
this->rotation = rotation; | |
} | |
void Transform::SetScale(const glm::vec3& scale) | |
{ | |
this->model_changed = true; | |
this->scale = scale; | |
} | |
void Transform::Translate(const glm::vec3& translation) | |
{ | |
this->model_changed = true; | |
this->position += translation; | |
} | |
void Transform::Scale(const glm::vec3& scale) | |
{ | |
this->model_changed = true; | |
this->scale *= scale; | |
} | |
void Transform::ScaleScalar(const float& scalar) | |
{ | |
this->model_changed = true; | |
this->scale *= scalar; | |
} | |
void Transform::Rotate(const glm::quat& rotation) | |
{ | |
this->model_changed = true; | |
this->rotation *= rotation; | |
} | |
void Transform::RotateEuler(const glm::vec3& angles) | |
{ | |
this->model_changed = true; | |
glm::rotate(this->rotation, angles.x, this->GetRightDirection()); | |
glm::rotate(this->rotation, angles.y, this->GetForwardDirection()); | |
glm::rotate(this->rotation, angles.z, this->GetUpDirection()); | |
} | |
void Transform::LookAt(const glm::vec3& target_position) | |
{ | |
this->model_changed = true; | |
auto new_direction = glm::normalize(this->position - target_position); | |
glm::vec3 right = glm::normalize(glm::cross(glm::vec3(0.0f, 1.0f, 0.0f), new_direction)); | |
glm::vec3 up = glm::cross(new_direction, right); | |
this->rotation = glm::conjugate(glm::toQuat(glm::lookAt(this->position, target_position, up))); | |
} | |
glm::mat4 GetMVP(Transform& transform, Camera& camera) | |
{ | |
return camera.GetProjectionMatrix() * camera.GetViewMatrix() * transform.GetModelMatrix(); | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <glm/glm.hpp> | |
#include <glm/gtx/quaternion.hpp> | |
class Transform | |
{ | |
protected: | |
glm::vec3 position; | |
glm::quat rotation; | |
glm::vec3 scale; | |
bool model_changed; | |
glm::mat4 model_matrix; | |
public: | |
Transform(); | |
~Transform() = default; | |
Transform(const Transform& other) = delete; | |
const glm::mat4& GetModelMatrix(); | |
const glm::vec3& GetPosition() const; | |
const glm::quat& GetRotation() const; | |
const glm::vec3& GetScale() const; | |
glm::vec3 GetEulerAngles() const; | |
glm::vec3 GetForwardDirection() const; | |
glm::vec3 GetBackwardDirection() const; | |
glm::vec3 GetRightDirection() const; | |
glm::vec3 GetLeftDirection() const; | |
glm::vec3 GetUpDirection() const; | |
glm::vec3 GetDownDirection() const; | |
virtual void SetPosition(const glm::vec3& position); | |
virtual void SetRotation(const glm::quat& rotation); | |
virtual void SetScale(const glm::vec3& scale); | |
virtual void Translate(const glm::vec3& translation); | |
virtual void Scale(const glm::vec3& scale); | |
virtual void ScaleScalar(const float& scalar); | |
virtual void Rotate(const glm::quat& rotation); | |
virtual void RotateEuler(const glm::vec3& angles); | |
virtual void LookAt(const glm::vec3& target_position); | |
}; | |
class Camera; | |
glm::mat4 GetMVP(Transform& transform, Camera& camera); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment