File components.hpp
File List > atlas > core > scene > components.hpp
Go to the documentation of this file
#pragma once
#include <core/application.hpp>
#include <core/geometry/mesh.hpp>
#include <glm/ext/quaternion_transform.hpp>
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/quaternion.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtx/matrix_decompose.hpp>
namespace atlas {
struct tag {
std::string TagMetadata = "";
};
struct transform {
glm::highp_vec3 Position{ 0.f };
glm::highp_vec4 QuaternionRotation{ 0.f, 0, 0, 1 };
glm::highp_vec3 Rotation{ 0.f };
glm::highp_vec3 Scale{ 1.f };
};
struct rigidbody3d {
rigidbody3d() = default;
enum class body_type { e_static = 0, e_dynamic = 1, e_kinematic = 2 };
body_type type = body_type::e_static;
bool hax_fixation = false;
void* body_at_runtime =
nullptr; // for storing the actual data of the body
};
struct box_collider3d {
box_collider3d() = default;
box_collider3d(const box_collider3d&) = default;
float density = 1.0f;
float friction = 0.5f;
float restitution = 0.0f;
float restitutionThreshold = 0.5f;
glm::vec3 offset = { 0.f, 0.f, 0.f };
glm::vec3 size = { 0.5f, 0.5f, 0.5f };
};
// Defines several possible options for camera movement. Used as abstraction
// to stay away from window-system specific input methods
enum CameraMovement { forward, backward, left, right, up, down };
// An abstract camera class that processes input and calculates the
// corresponding Euler Angles, Vectors and Matrices for use in OpenGL
struct light {
glm::vec3 Position{ 1.f };
};
struct reload {
bool on_reload = false;
bool on_texture_reload = false;
};
// struct rendertarget3d {
// std::string model_path; // used to load in a model
// std::string Filepath; // used for texture
// // bool is_model_dirty=false; // checks if the model is needing to
// reload bool is_texture_dirty=false; // checking if texture is needing
// to reload
// };
struct material {
glm::vec4 color{ 1.f };
std::string model_path = "";
std::string texture_path =
""; // This just contains the path to load the texture
std::vector<std::string> texture_filepaths;
bool model_reload = false;
bool texture_reload = false;
};
// An abstract camera class that processes input and calculates the
// corresponding Euler Angles, Vectors and Matrices for use in OpenGL
class camera {
// Default camera values
// const float yaw = -90.0f;
// const float PITCH = 0.0f;
// const float ZOOM = 45.0f;
public:
camera() = default;
// constructor with vectors
camera(float p_aspect_ratio,
glm::vec3 position = glm::vec3(0.0f, 1.50f, 0.0f),
glm::vec3 up = glm::vec3(0.0f, -1.0f, 0.0f),
float yaw = -90.0f,
float pitch = 0.0f)
: MovementSpeed(5.f)
, MouseSensitivity(0.1f)
, Zoom(45.0f)
, camera_mouse_sensitivity(0.1f) {
Position = position;
WorldUp = up;
EulerRotation = { yaw, pitch, 1.f };
AspectRatio = p_aspect_ratio;
update_camera();
}
// returns the view matrix calculated using Euler Angles and the LookAt
// Matrix
[[nodiscard]] glm::mat4 get_view() const { return View; }
[[nodiscard]] glm::mat4 get_projection() const { return Projection; }
// processes input received from any keyboard-like input system. Accepts
// input parameter in the form of camera defined ENUM (to abstract it
// from windowing systems)
void process_keyboard(CameraMovement p_direction, float p_delta_time) {
float velocity = MovementSpeed * p_delta_time;
if (p_direction == CameraMovement::forward)
Position += get_front() * velocity;
if (p_direction == CameraMovement::backward)
Position -= get_front() * velocity;
if (p_direction == CameraMovement::left)
Position -= Right * velocity;
if (p_direction == CameraMovement::right)
Position += Right * velocity;
if (p_direction == CameraMovement::up) {
Position += Up * velocity;
}
if (p_direction == CameraMovement::down) {
Position -= Up * velocity;
}
}
// processes input received from a mouse input system. Expects the
// offset value in both the x and y direction.
void process_mouse_movement(float p_x,
float p_y,
bool p_constraint_pitch = true) {
p_x *= MouseSensitivity;
p_y *= MouseSensitivity;
EulerRotation.x += p_x;
EulerRotation.y += p_y;
// make sure that when pitch is out of bounds, screen doesn't get
// flipped
if (p_constraint_pitch) {
if (EulerRotation.y > 89.0f) {
EulerRotation.y = 89.0f;
}
if (EulerRotation.y < -89.0f) {
EulerRotation.y = -89.0f;
}
}
// update Front, Right and Up Vectors using the updated Euler angles
update_camera();
}
// processes input received from a mouse scroll-wheel event. Only
// requires input on the vertical wheel-axis
void process_mouse_scroll(float yoffset) {
Zoom -= (float)yoffset;
if (Zoom < 1.0f) {
Zoom = 1.0f;
}
if (Zoom > 45.0f) {
Zoom = 45.0f;
}
}
void set_movement_speed(float p_sensitivity) {
camera_movement_sensitivity = p_sensitivity;
MovementSpeed = camera_movement_sensitivity;
}
void set_mouse_speed(float p_sensitivity) {
camera_mouse_sensitivity = p_sensitivity;
}
[[nodiscard]] float camera_sensitivity() const {
return camera_mouse_sensitivity;
}
private:
// calculates the front vector from the Camera's (updated) Euler Angles
void update_camera() {
// calculate the new Front vector
// glm::vec3 front;
// front.x = cos(glm::radians(EulerRotation.x)) *
// cos(glm::radians(EulerRotation.y)); front.y =
// sin(glm::radians(EulerRotation.y)); front.z =
// sin(glm::radians(EulerRotation.x)) *
// cos(glm::radians(EulerRotation.y)); Front =
// glm::normalize(front); also re-calculate the Right and Up vector
Right = glm::normalize(glm::cross(
get_front(),
WorldUp)); // normalize the vectors, because their length
// gets closer to 0 the more you look up or
// down which results in slower movement.
Left = glm::normalize(glm::cross(-get_front(), WorldUp));
Up = glm::normalize(glm::cross(Right, get_front()));
Down = glm::normalize(glm::cross(-Right, WorldUp));
}
public:
void update_proj_view() {
Projection =
glm::perspective(glm::radians(Zoom), AspectRatio, .1f, 50000.f);
View = glm::lookAt(Position, Position + get_front(), Up);
}
[[nodiscard]] glm::vec3 get_front() const {
glm::vec3 front_values;
front_values.x = cos(glm::radians(EulerRotation.x)) *
cos(glm::radians(EulerRotation.y));
front_values.y = sin(glm::radians(EulerRotation.y));
front_values.z = sin(glm::radians(EulerRotation.x)) *
cos(glm::radians(EulerRotation.y));
return glm::normalize(front_values);
}
public:
// camera Attributes
glm::vec3 Position;
// glm::vec3 Front;
glm::vec3 Up;
glm::vec3 Down;
glm::vec3 Right;
glm::vec3 Left;
glm::vec3 WorldUp;
glm::mat4 Projection;
glm::mat4 View;
float AspectRatio = 0.f;
// euler Angles
// {x: Yaw, y: Pitch, z: Roll}
glm::vec3 EulerRotation;
// camera options
float MovementSpeed{};
float MouseSensitivity{};
float Zoom{};
// float camera_mouse_sensitivity = 0.1f;
float camera_mouse_sensitivity = 2.5f;
float camera_movement_sensitivity = 2.5f;
// toggling between cameras and checking if our current
bool IsMainCamera = false;
};
}; // namespace atlas