diff --git a/cmake_modules/gcc.cmake b/cmake_modules/gcc.cmake index a484d89..ae218dd 100644 --- a/cmake_modules/gcc.cmake +++ b/cmake_modules/gcc.cmake @@ -108,7 +108,7 @@ #set(FGL_WARNINGS "${FGL_WARNINGS_GENERIC} -Wpessimizing-move -Wpedantic -Weffc++ -pedantic-errors -Wnoexcept -Wuninitialized -Wunused -Wunused-parameter -Winit-self -Wconversion -Wuseless-cast -Wextra-semi -Wsuggest-final-types -Wsuggest-final-methods -Wsuggest-override -Wformat-signedness -Wno-format-zero-length -Wmissing-include-dirs -Wshift-overflow=2 -Walloc-zero -Walloca -Wsign-promo -Wconversion -Wduplicated-branches -Wduplicated-cond -Wshadow -Wshadow=local -Wvirtual-inheritance -Wno-virtual-move-assign -Wunsafe-loop-optimizations -Wnormalized -Wpacked -Wredundant-decls -Wctor-dtor-privacy -Wdeprecated-copy-dtor -Wstrict-null-sentinel -Wold-style-cast -Woverloaded-virtual -Wzero-as-null-pointer-constant -Wconditionally-supported -Wwrite-strings -Wunused-const-variable=2 -Wdouble-promotion -Wpointer-arith -Wcast-align=strict -Wcast-qual -Wconversion -Wsign-conversion -Wimplicit-fallthrough=1 -Wmisleading-indentation -Wdangling-else -Wdate-time -Wformat=2 -Wformat-overflow=2 -Wformat-signedness -Wformat-truncation=2 -Wswitch-default -Wstringop-overflow=4 -Warray-bounds=2 -Wattribute-alias=2 -Wcatch-value=2 -Wplacement-new=2 -Wtrampolines -Winvalid-imported-macros -Winvalid-imported-macros") - set(FGL_CONFIG "-std=c++20 -fmax-errors=1 -fconcepts-diagnostics-depth=8 -Werror") + set(FGL_CONFIG "-std=c++23 -fmax-errors=1 -fconcepts-diagnostics-depth=8 -Werror") # Optimization flags set(FGL_OPTIMIZATION_FLAGS_RELEASE "-O2 -s -fdevirtualize-at-ltrans -fdevirtualize-speculatively -funroll-loops") # System agonistc flags diff --git a/src/engine/Camera.cpp b/src/engine/Camera.cpp index 0fb599c..2e6af63 100644 --- a/src/engine/Camera.cpp +++ b/src/engine/Camera.cpp @@ -9,6 +9,7 @@ #include #include +#include namespace fgl::engine { @@ -29,7 +30,7 @@ namespace fgl::engine base_frustum = createFrustum( *this, aspect, fovy, near, far ); } - void Camera::setViewDirection( glm::vec3 position, glm::vec3 direction, glm::vec3 up ) + void Camera::setViewDirection( glm::vec3 position, const Vector direction, glm::vec3 up ) { ZoneScoped; glm::lookAt( position, position + direction, up ); @@ -39,35 +40,126 @@ namespace fgl::engine void Camera::setViewTarget( glm::vec3 position, glm::vec3 target, glm::vec3 up ) { - setViewDirection( position, glm::normalize( target - position ), up ); + setViewDirection( position, Vector( glm::normalize( target - position ) ), up ); } enum RotationOrder { - XYZ, XZY, + XYZ, YXZ, YZX, + ZYX, ZXY, - ZYX + END_OF_ENUM, + DEFAULT = XYZ }; - glm::mat4 taitBryanMatrix( const glm::vec3 rotation, const RotationOrder order = XYZ ) + template < int N > + inline std::tuple< float, float > extract( const Vector rotation, const RotationOrder order ) + { + switch ( order ) + { + case XZY: + switch ( N ) + { + case 1: + return { glm::cos( rotation.x ), glm::sin( rotation.x ) }; + case 2: + return { glm::cos( rotation.z ), glm::sin( rotation.z ) }; + case 3: + return { glm::cos( rotation.y ), glm::sin( rotation.y ) }; + } + break; + case XYZ: + switch ( N ) + { + case 1: + return { glm::cos( rotation.x ), glm::sin( rotation.x ) }; + case 2: + return { glm::cos( rotation.y ), glm::sin( rotation.y ) }; + case 3: + return { glm::cos( rotation.z ), glm::sin( rotation.z ) }; + } + break; + case YXZ: + switch ( N ) + { + case 1: + return { glm::cos( rotation.y ), glm::sin( rotation.y ) }; + case 2: + return { glm::cos( rotation.x ), glm::sin( rotation.x ) }; + case 3: + return { glm::cos( rotation.z ), glm::sin( rotation.z ) }; + } + break; + case YZX: + switch ( N ) + { + case 1: + return { glm::cos( rotation.y ), glm::sin( rotation.y ) }; + case 2: + return { glm::cos( rotation.z ), glm::sin( rotation.z ) }; + case 3: + return { glm::cos( rotation.x ), glm::sin( rotation.x ) }; + } + break; + case ZYX: + switch ( N ) + { + case 1: + return { glm::cos( rotation.z ), glm::sin( rotation.z ) }; + case 2: + return { glm::cos( rotation.y ), glm::sin( rotation.y ) }; + case 3: + return { glm::cos( rotation.x ), glm::sin( rotation.x ) }; + } + break; + case ZXY: + switch ( N ) + { + case 1: + return { glm::cos( rotation.z ), glm::sin( rotation.z ) }; + case 2: + return { glm::cos( rotation.x ), glm::sin( rotation.x ) }; + case 3: + return { glm::cos( rotation.y ), glm::sin( rotation.y ) }; + } + break; + case END_OF_ENUM: + throw std::runtime_error( "Unimplemented rotation order" ); + } + std::unreachable(); + } + + glm::mat4 taitBryanMatrix( const Vector rotation, const RotationOrder order = DEFAULT ) { glm::mat4 mat { 1.0f }; - const float c1 { glm::cos( rotation.x ) }; - const float s1 { glm::sin( rotation.x ) }; - - const float c2 { glm::cos( rotation.y ) }; - const float s2 { glm::sin( rotation.y ) }; - - const float c3 { glm::cos( rotation.z ) }; - const float s3 { glm::sin( rotation.z ) }; + const auto [ c1, s1 ] = extract< 1 >( rotation, order ); + const auto [ c2, s2 ] = extract< 2 >( rotation, order ); + const auto [ c3, s3 ] = extract< 3 >( rotation, order ); switch ( order ) { - case RotationOrder::XYZ: // Pitch, Yaw, Roll + case RotationOrder::XZY: + { + const glm::vec3 row_0 { ( c2 * c3 ), -( s2 ), ( c2 * s3 ) }; + + const glm::vec3 row_1 { ( s1 * s3 ) + ( c1 * c3 * s2 ), + ( c1 * c2 ), + ( c1 * s2 * s3 ) - ( c3 * s1 ) }; + + const glm::vec3 row_2 { ( c3 * s1 * s2 ) - ( c1 * s3 ), + ( c2 * s1 ), + ( c1 * c3 ) + ( s1 * s2 * s3 ) }; + + mat[ 0 ] = glm::vec4( row_0, 0.0f ); + mat[ 1 ] = glm::vec4( row_1, 0.0f ); + mat[ 2 ] = glm::vec4( row_2, 0.0f ); + return mat; + } + case RotationOrder::XYZ: { const glm::vec3 row_0 { ( c2 * c3 ), -( c2 * s3 ), s2 }; const glm::vec3 row_1 { ( c1 * s3 ) + ( c3 * s1 * s2 ), @@ -82,7 +174,33 @@ namespace fgl::engine mat[ 2 ] = glm::vec4( row_2, 0.0f ); return mat; } - case RotationOrder::ZYX: // Yaw, Roll, Pitch + case RotationOrder::YXZ: + { + const glm::vec3 row_0 { ( c1 * c3 ) + ( s1 * s2 * s3 ), ( c3 * s1 * s2 ) - ( c1 * s3 ), c2 * s1 }; + const glm::vec3 row_1 { c2 * s3, c2 * c3, -s2 }; + const glm::vec3 row_2 { ( c1 * s2 * s3 ) - ( c3 * s1 ), ( c1 * c3 * s2 ) + ( s1 * s3 ), c1 * c2 }; + + mat[ 0 ] = glm::vec4( row_0, 0.0f ); + mat[ 1 ] = glm::vec4( row_1, 0.0f ); + mat[ 2 ] = glm::vec4( row_2, 0.0f ); + return mat; + } + case RotationOrder::YZX: + { + const glm::vec3 row_0 { ( c1 * c2 ), + ( s1 * s3 ) - ( c1 * c3 * s2 ), + ( c3 * s1 ) + ( c1 * s2 * s3 ) }; + const glm::vec3 row_1 { s2, c2 * c3, -( c2 * s3 ) }; + const glm::vec3 row_2 { -( c2 * s1 ), + ( c1 * s3 ) + ( c3 * s1 * s2 ), + ( c1 * c3 ) - ( s1 * s2 * s3 ) }; + + mat[ 0 ] = glm::vec4( row_0, 0.0f ); + mat[ 1 ] = glm::vec4( row_1, 0.0f ); + mat[ 2 ] = glm::vec4( row_2, 0.0f ); + return mat; + } + case RotationOrder::ZYX: // Roll, Pitch, Yaw { const glm::vec3 row_0 { ( c1 * c2 ), ( c1 * s2 * s3 ) - ( c3 * s1 ), @@ -97,11 +215,17 @@ namespace fgl::engine mat[ 2 ] = glm::vec4( row_2, 0.0f ); return mat; } - case RotationOrder::YXZ: // Roll, Pitch, Yaw + case RotationOrder::ZXY: // Roll, Yaw, Pitch { - const glm::vec3 row_0 { ( c1 * c3 ) + ( s1 * s2 * s3 ), ( c3 * s1 * s2 ) - ( c1 * s3 ), c2 * s1 }; - const glm::vec3 row_1 { c2 * s3, c2 * c3, -s2 }; - const glm::vec3 row_2 { ( c1 * s2 * s3 ) - ( c3 * s1 ), ( c1 * c3 * s2 ) + ( s1 * s3 ), c1 * c2 }; + const glm::vec3 row_0 { ( c1 * c3 ) - ( s1 * s2 * s3 ), + -( c2 * s1 ), + ( c1 * s3 ) + ( c3 * s1 * s2 ) }; + + const glm::vec3 row_1 { ( c3 * s1 ) + ( c1 * s2 * s3 ), + ( c1 * c2 ), + ( s1 * s3 ) - ( c1 * c3 * s2 ) }; + + const glm::vec3 row_2 { -( c2 * s3 ), ( s2 ), ( c2 * c3 ) }; mat[ 0 ] = glm::vec4( row_0, 0.0f ); mat[ 1 ] = glm::vec4( row_1, 0.0f ); @@ -113,15 +237,28 @@ namespace fgl::engine } } - void Camera::setViewYXZ( glm::vec3 position, glm::vec3 rotation, const ViewMode mode ) + void Camera::setViewYXZ( glm::vec3 position, const Vector rotation, const ViewMode mode ) { ZoneScoped; + //Flip Z due to the fact we use Z+ outside of this function. It must be Z- inside + position.z = -position.z; + switch ( mode ) { case ViewMode::TaitBryan: { - const glm::mat4 rotation_matrix { taitBryanMatrix( rotation ) }; + static auto current_rotation_order { RotationOrder::DEFAULT }; + + ImGui::Begin( "CameraRotation" ); + ImGui::SliderInt( + "Rotation Order", + reinterpret_cast< int* >( ¤t_rotation_order ), + 0, + static_cast< int >( RotationOrder::END_OF_ENUM - 1 ) ); + ImGui::End(); + + const glm::mat4 rotation_matrix { taitBryanMatrix( rotation, current_rotation_order ) }; const glm::vec3 forward { rotation_matrix * glm::vec4( constants::WORLD_FORWARD, 0.0f ) }; diff --git a/src/engine/Camera.hpp b/src/engine/Camera.hpp index ef75f28..6f0681d 100644 --- a/src/engine/Camera.hpp +++ b/src/engine/Camera.hpp @@ -79,7 +79,7 @@ namespace fgl::engine const Vector getDown() const { return -getUp(); } - void setViewDirection( glm::vec3 pos, glm::vec3 direction, glm::vec3 up = constants::WORLD_UP ); + void setViewDirection( glm::vec3 pos, const Vector direction, glm::vec3 up = constants::WORLD_UP ); void setViewTarget( glm::vec3 pos, glm::vec3 target, glm::vec3 up = constants::WORLD_UP ); enum ViewMode @@ -88,7 +88,7 @@ namespace fgl::engine TaitBryan }; - void setViewYXZ( glm::vec3 pos, glm::vec3 rotation, const ViewMode mode = TaitBryan ); + void setViewYXZ( glm::vec3 pos, const Vector rotation, const ViewMode mode = TaitBryan ); }; } // namespace fgl::engine diff --git a/src/engine/EngineContext.cpp b/src/engine/EngineContext.cpp index d36951f..d7fdcec 100644 --- a/src/engine/EngineContext.cpp +++ b/src/engine/EngineContext.cpp @@ -105,7 +105,9 @@ namespace fgl::engine //camera.setOrthographicProjection( -aspect, aspect, -1, 1, -1, 1 ); const float aspect { m_renderer.getAspectRatio() }; - camera.setPerspectiveProjection( glm::radians( 50.0f ), aspect, 0.1f, 100.f ); + camera.setPerspectiveProjection( glm::radians( 90.0f ), aspect, 0.1f, 100.f ); + + const auto old_aspect_ratio { m_renderer.getAspectRatio() }; while ( !m_window.shouldClose() ) { @@ -138,6 +140,11 @@ namespace fgl::engine } #endif + if ( old_aspect_ratio != m_renderer.getAspectRatio() ) + { + camera.setPerspectiveProjection( glm::radians( 90.0f ), m_renderer.getAspectRatio(), 0.1f, 100.f ); + } + camera_controller.moveInPlaneXZ( m_window.window(), delta_time, viewer ); camera.setViewYXZ( viewer.transform.translation, viewer.transform.rotation ); @@ -489,23 +496,6 @@ namespace fgl::engine */ Device::getInstance().endSingleTimeCommands( command_buffer ); - - std::vector< glm::vec3 > lightColors { - { 1.f, .1f, .1f }, { .1f, .1f, 1.f }, { .1f, 1.f, .1f }, - { 1.f, 1.f, .1f }, { .1f, 1.f, 1.f }, { 1.f, 1.f, 1.f } // - }; - - for ( std::size_t i = 0; i < lightColors.size(); ++i ) - { - auto point_light { GameObject::makePointLight( 0.2f ) }; - point_light.color = lightColors[ i ]; - auto rotate_light = glm::rotate( - glm::mat4( 1.0f ), - ( static_cast< float >( i ) * glm::two_pi< float >() ) / static_cast< float >( lightColors.size() ), - { 0.0f, -1.0f, 0.0f } ); - point_light.transform.translation = glm::vec3( rotate_light * glm::vec4( -1.0f, -1.0f, -1.0f, -1.0f ) ); - game_objects.emplace( point_light.getId(), std::move( point_light ) ); - } } void EngineContext::initImGui() diff --git a/src/engine/GameObject.cpp b/src/engine/GameObject.cpp index cc2aae6..8c9558f 100644 --- a/src/engine/GameObject.cpp +++ b/src/engine/GameObject.cpp @@ -52,13 +52,4 @@ namespace fgl::engine }; } - GameObject GameObject::makePointLight( float intensity, float radius, glm::vec3 color ) - { - GameObject game_obj { createGameObject() }; - game_obj.color = color; - game_obj.transform.scale.x = radius; - game_obj.point_light = std::make_unique< PointLightComponent >(); - game_obj.point_light->light_intensity = intensity; - return game_obj; - } } // namespace fgl::engine \ No newline at end of file diff --git a/src/engine/GameObject.hpp b/src/engine/GameObject.hpp index 4d80b3a..daa360b 100644 --- a/src/engine/GameObject.hpp +++ b/src/engine/GameObject.hpp @@ -10,17 +10,19 @@ #include #include "constants.hpp" +#include "engine/primitives/Vector.hpp" namespace fgl::engine { class Model; + //TransformComponent is always in world space struct TransformComponent { - glm::vec3 translation { constants::DEFAULT_VEC3 }; + WorldCoordinate translation { constants::DEFAULT_VEC3 }; glm::vec3 scale { 1.0f, 1.0f, 1.0f }; - glm::vec3 rotation { 0.0f, 0.0f, 0.0f }; + Vector rotation { 0.0f, 0.0f, 0.0f }; //TODO: Figure this out and replace TransformComponent with a template of CType instead glm::mat4 mat4() const; @@ -28,11 +30,6 @@ namespace fgl::engine glm::mat3 normalMatrix() const; }; - struct PointLightComponent - { - float light_intensity { 1.0f }; - }; - class GameObject { public: @@ -46,7 +43,6 @@ namespace fgl::engine std::shared_ptr< Model > model {}; glm::vec3 color {}; TransformComponent transform {}; - std::unique_ptr< PointLightComponent > point_light { nullptr }; private: @@ -66,9 +62,6 @@ namespace fgl::engine return { current_id++ }; } - static GameObject - makePointLight( float intensity = 10.0f, float radius = 0.1f, glm::vec3 color = glm::vec3( 1.0f ) ); - ID getId() const { return m_id; } }; diff --git a/src/engine/KeyboardMovementController.cpp b/src/engine/KeyboardMovementController.cpp index bff7ca7..dd38452 100644 --- a/src/engine/KeyboardMovementController.cpp +++ b/src/engine/KeyboardMovementController.cpp @@ -6,6 +6,8 @@ #include +#include "engine/primitives/Vector.hpp" + namespace fgl::engine { @@ -25,12 +27,14 @@ namespace fgl::engine void KeyboardMovementController::moveInPlaneXZ( GLFWwindow* window, float dt, fgl::engine::GameObject& target ) { - glm::vec3 rotate { 0.0f }; + ImGui::Begin( "CameraMovement" ); - if ( glfwGetKey( window, key_mappings.look_right ) == GLFW_PRESS ) rotate.y += 1.f; - if ( glfwGetKey( window, key_mappings.look_left ) == GLFW_PRESS ) rotate.y -= 1.f; - if ( glfwGetKey( window, key_mappings.look_up ) == GLFW_PRESS ) rotate.x += 1.f; - if ( glfwGetKey( window, key_mappings.look_down ) == GLFW_PRESS ) rotate.x -= 1.f; + Vector rotate { 0.0f }; + + if ( glfwGetKey( window, key_mappings.look_right ) == GLFW_PRESS ) rotate.yaw -= 1.f; + if ( glfwGetKey( window, key_mappings.look_left ) == GLFW_PRESS ) rotate.yaw += 1.f; + if ( glfwGetKey( window, key_mappings.look_up ) == GLFW_PRESS ) rotate.pitch += 1.f; + if ( glfwGetKey( window, key_mappings.look_down ) == GLFW_PRESS ) rotate.pitch -= 1.f; static bool cursor_enabled { true }; static bool cursor_restored { false }; @@ -73,26 +77,26 @@ namespace fgl::engine const auto xpos { pos.x }; const auto ypos { pos.y }; - target.transform.rotation.y += + target.transform.rotation.yaw += static_cast< float >( ( xpos * 0.006 ) * static_cast< double >( look_speed ) ); - target.transform.rotation.x -= + target.transform.rotation.pitch -= static_cast< float >( ( ypos * 0.006 ) * static_cast< double >( look_speed ) ); setCursorPos( window, { 0, 0 } ); } else { - if ( glm::dot( rotate, rotate ) > std::numeric_limits< float >::epsilon() ) + if ( glm::dot( static_cast< glm::vec3 >( rotate ), static_cast< glm::vec3 >( rotate ) ) + > std::numeric_limits< float >::epsilon() ) target.transform.rotation += look_speed * dt * glm::normalize( rotate ); - target.transform.rotation.x = glm::clamp( target.transform.rotation.x, -1.5f, 1.5f ); - target.transform.rotation.y = glm::mod( target.transform.rotation.y, glm::two_pi< float >() ); + target.transform.rotation.pitch = glm::clamp( target.transform.rotation.pitch, -1.5f, 1.5f ); + target.transform.rotation.yaw = glm::mod( target.transform.rotation.yaw, glm::two_pi< float >() ); } - const float yaw { target.transform.rotation.y }; - const glm::vec3 forward_dir { std::sin( yaw ), 0.0f, std::cos( yaw ) }; - const glm::vec3 right_dir { forward_dir.z, 0.0f, -forward_dir.x }; - const glm::vec3 up_dir { 0.0f, -0.1f, 0.0f }; + const glm::vec3 forward_dir { target.transform.rotation.forward() }; + const glm::vec3 right_dir { target.transform.rotation.right() }; + const glm::vec3 up_dir { constants::WORLD_UP }; glm::vec3 move_dir { 0.0f }; if ( glfwGetKey( window, key_mappings.move_forward ) == GLFW_PRESS ) move_dir += forward_dir; @@ -104,6 +108,13 @@ namespace fgl::engine if ( glm::dot( move_dir, move_dir ) > std::numeric_limits< float >::epsilon() ) target.transform.translation += ( move_speed * dt ) * glm::normalize( move_dir ); + + ImGui::Text( "Transform" ); + ImGui::InputFloat( "X", &target.transform.translation.x, -10.0, 10.0 ); + ImGui::InputFloat( "Y", &target.transform.translation.y, -10.0, 10.0 ); + ImGui::InputFloat( "Z", &target.transform.translation.z, -10.0, 10.0 ); + + ImGui::End(); } } // namespace fgl::engine \ No newline at end of file diff --git a/src/engine/primitives/Coordinate.hpp b/src/engine/primitives/Coordinate.hpp index 6a48910..55f4896 100644 --- a/src/engine/primitives/Coordinate.hpp +++ b/src/engine/primitives/Coordinate.hpp @@ -29,6 +29,12 @@ namespace fgl::engine public: + float& up() { return y; } + + float& right() { return x; } + + float& forward() { return z; } + Coordinate() : glm::vec3( constants::DEFAULT_VEC3 ) {} explicit Coordinate( const glm::vec3 position ) : glm::vec3( position ) {} diff --git a/src/engine/primitives/Plane.hpp b/src/engine/primitives/Plane.hpp index 4c1d6e8..9293d12 100644 --- a/src/engine/primitives/Plane.hpp +++ b/src/engine/primitives/Plane.hpp @@ -37,21 +37,6 @@ namespace fgl::engine Plane() = default; - /* - Plane operator*( glm::mat4 matrix ) const - { - assert( valid() ); - - Plane result = *this; - const glm::vec3 new_direction { matrix * glm::vec4( m_direction, 1.0f ) }; - - const float new_distance { glm::dot( new_direction, m_direction ) + m_distance }; - result.m_direction = glm::normalize( new_direction ); - result.m_distance = new_distance; - - return result; - }*/ - //! Returns the closest point on the plane to the 0,0,0 origin Coordinate< CType > getPosition() const { diff --git a/src/engine/primitives/Vector.cpp b/src/engine/primitives/Vector.cpp new file mode 100644 index 0000000..c951494 --- /dev/null +++ b/src/engine/primitives/Vector.cpp @@ -0,0 +1,61 @@ +// +// Created by kj16609 on 2/12/24. +// + +#include "Vector.hpp" + +namespace fgl::engine +{ + + Vector::Vector( const Vector& other ) + { + x = other.x; + y = other.y; + z = other.z; + } + + Vector& Vector::operator=( const Vector& other ) + { + x = other.x; + y = other.y; + z = other.z; + return *this; + } + + Vector::Vector( Vector&& other ) + { + x = other.x; + y = other.y; + z = other.z; + } + + Vector& Vector::operator=( const Vector&& other ) + { + x = other.x; + y = other.y; + z = other.z; + return *this; + } + + Vector& Vector::operator=( const std::initializer_list< float > list ) + { + assert( list.size() == 3 ); + x = *( list.begin() ); + y = *( list.begin() + 1 ); + z = *( list.begin() + 2 ); + return *this; + } + + glm::vec3 Vector::forward() const + { + //TODO: Figure out Z shit + return { std::sin( yaw ), std::cos( yaw ), 0.0f }; + } + + glm::vec3 Vector::right() const + { + const auto forward_dir { forward() }; + return { -forward_dir.y, forward_dir.x, 0.0f }; + } + +} // namespace fgl::engine diff --git a/src/engine/primitives/Vector.hpp b/src/engine/primitives/Vector.hpp index b8851c0..84f73a0 100644 --- a/src/engine/primitives/Vector.hpp +++ b/src/engine/primitives/Vector.hpp @@ -4,6 +4,8 @@ #pragma once +#include "Coordinate.hpp" + namespace fgl::engine { @@ -14,13 +16,34 @@ namespace fgl::engine { public: - explicit Vector( const glm::vec3 direction ) : glm::vec3( direction ) {} + float& roll { y }; + float& pitch { x }; + float& yaw { z }; + + explicit Vector( const float value ) : glm::vec3( value ) {} + + explicit Vector( const glm::vec3 vec ) : glm::vec3( vec ) {} + + explicit Vector( const float x, const float y, const float z ) : glm::vec3( x, y, z ) {} operator glm::vec4() const { return glm::vec4( static_cast< glm::vec3 >( *this ), 0.0f ); } Vector norm() const { return Vector( glm::normalize( static_cast< glm::vec3 >( *this ) ) ); } Vector operator*( const float scalar ) const { return Vector( static_cast< glm::vec3 >( *this ) * scalar ); } + + glm::vec3 right() const; + glm::vec3 forward() const; + + //Copy + Vector( const Vector& other ); + Vector& operator=( const Vector& other ); + + //Move (Should never really move?) + Vector( Vector&& other ); + Vector& operator=( const Vector&& other ); + + Vector& operator=( const std::initializer_list< float > list ); }; inline Vector operator-( const Vector vec )