diff --git a/src/engine/FrameInfo.hpp b/src/engine/FrameInfo.hpp index e640b70..240fd6e 100644 --- a/src/engine/FrameInfo.hpp +++ b/src/engine/FrameInfo.hpp @@ -26,7 +26,7 @@ namespace fgl::engine { class DescriptorSet; } - struct TransformComponent; + class SwapChain; class Camera; diff --git a/src/engine/camera/Camera.hpp b/src/engine/camera/Camera.hpp index 6e90358..75675dd 100644 --- a/src/engine/camera/Camera.hpp +++ b/src/engine/camera/Camera.hpp @@ -58,7 +58,7 @@ namespace fgl::engine Frustum< CoordinateSpace::World > frustum {}; WorldCoordinate last_frustum_pos { constants::WORLD_CENTER }; - TransformComponent m_transform; + WorldTransform m_transform; vk::Extent2D m_target_extent; float m_fov_y { glm::radians( 90.0f ) }; @@ -109,9 +109,9 @@ namespace fgl::engine Rotation& getRotation() { return m_transform.rotation; } - const TransformComponent& getTransform() const { return m_transform; } + const WorldTransform& getTransform() const { return m_transform; } - TransformComponent& getTransform() { return m_transform; } + WorldTransform& getTransform() { return m_transform; } WorldCoordinate getFrustumPosition() const; diff --git a/src/engine/gameobjects/GameObject.hpp b/src/engine/gameobjects/GameObject.hpp index c8613d5..9bcab56 100644 --- a/src/engine/gameobjects/GameObject.hpp +++ b/src/engine/gameobjects/GameObject.hpp @@ -43,7 +43,7 @@ namespace fgl::engine GameObjectID m_id { INVALID_ID }; GameObjectFlagType object_flags { GameObjectFlagMask::MASK_DEFAULT }; - TransformComponent m_transform {}; + GameObjectTransform m_transform {}; std::vector< GameObjectComponentPtr > components {}; @@ -121,9 +121,9 @@ namespace fgl::engine void removeFlag( GameObjectFlagType flag ) { object_flags &= ( ~flag ); } //Transform - TransformComponent& getTransform() { return m_transform; } + GameObjectTransform& getTransform() { return m_transform; } - const TransformComponent& getTransform() const { return m_transform; } + const GameObjectTransform& getTransform() const { return m_transform; } const WorldCoordinate& getPosition() const { return m_transform.translation; } diff --git a/src/engine/gameobjects/components/interface/GameObjectComponent.hpp b/src/engine/gameobjects/components/interface/GameObjectComponent.hpp index 03cdc2d..d650a1f 100644 --- a/src/engine/gameobjects/components/interface/GameObjectComponent.hpp +++ b/src/engine/gameobjects/components/interface/GameObjectComponent.hpp @@ -12,7 +12,7 @@ namespace fgl::engine { - struct ComponentTransform final : public TransformComponent + struct ComponentTransform final : public TransformComponent< CoordinateSpace::World > { enum Mode { diff --git a/src/engine/model/ModelVertex.hpp b/src/engine/model/ModelVertex.hpp index 9906863..d6cc54e 100644 --- a/src/engine/model/ModelVertex.hpp +++ b/src/engine/model/ModelVertex.hpp @@ -36,8 +36,6 @@ namespace fgl::engine bool operator==( const ModelVertex& other ) const; }; - static_assert( offsetof( ModelVertex, m_normal ) > offsetof( SimpleVertex, m_color ) ); - } // namespace fgl::engine namespace std diff --git a/src/engine/model/Primitive.hpp b/src/engine/model/Primitive.hpp index 9eb1aa5..4e419f1 100644 --- a/src/engine/model/Primitive.hpp +++ b/src/engine/model/Primitive.hpp @@ -88,7 +88,7 @@ namespace fgl::engine m_mode( mode ), m_textures() { - assert( m_bounding_box.scale != glm::vec3( 0.0f ) ); + assert( m_bounding_box.m_transform.scale != glm::vec3( 0.0f ) ); } Primitive( @@ -103,7 +103,7 @@ namespace fgl::engine m_mode( mode ), m_textures( std::forward< decltype( m_textures ) >( textures ) ) { - assert( m_bounding_box.scale != glm::vec3( 0.0f ) ); + assert( m_bounding_box.m_transform.scale != glm::vec3( 0.0f ) ); } Primitive() = delete; diff --git a/src/engine/model/builders/SceneBuilder.cpp b/src/engine/model/builders/SceneBuilder.cpp index 112cbe4..81f9b89 100644 --- a/src/engine/model/builders/SceneBuilder.cpp +++ b/src/engine/model/builders/SceneBuilder.cpp @@ -15,6 +15,7 @@ #include #include "engine/assets/stores.hpp" +#include "engine/camera/Camera.hpp" #include "engine/descriptors/DescriptorSet.hpp" #include "engine/gameobjects/GameObject.hpp" #include "engine/image/ImageView.hpp" @@ -393,7 +394,7 @@ namespace fgl::engine static_cast< float >( data[ 2 ] ) }; } - TransformComponent SceneBuilder::loadTransform( int node_idx, const tinygltf::Model& root ) + WorldTransform SceneBuilder::loadTransform( int node_idx, const tinygltf::Model& root ) { const auto node { root.nodes[ node_idx ] }; @@ -404,7 +405,7 @@ namespace fgl::engine static_cast< float >( node.rotation[ 3 ] ) }; const glm::vec3 scale { convertToVec3( node.scale ) }; - TransformComponent transform_component {}; + WorldTransform transform_component {}; transform_component.rotation = rotation; transform_component.scale = scale; transform_component.translation = WorldCoordinate( translation ); diff --git a/src/engine/model/builders/SceneBuilder.hpp b/src/engine/model/builders/SceneBuilder.hpp index 3e96243..58b948f 100644 --- a/src/engine/model/builders/SceneBuilder.hpp +++ b/src/engine/model/builders/SceneBuilder.hpp @@ -56,7 +56,7 @@ namespace fgl::engine void handleScene( const tinygltf::Scene& scene, const tinygltf::Model& root ); void handleNode( const int node_idx, const tinygltf::Model& root ); - TransformComponent loadTransform( int node_idx, const tinygltf::Model& root ); + WorldTransform loadTransform( int node_idx, const tinygltf::Model& root ); std::shared_ptr< Model > loadModel( const int mesh_idx, const tinygltf::Model& root ); Primitive loadPrimitive( const tinygltf::Primitive& prim, const tinygltf::Model& model ); diff --git a/src/engine/primitives/Rotation.cpp b/src/engine/primitives/Rotation.cpp index 671d3ab..ff48071 100644 --- a/src/engine/primitives/Rotation.cpp +++ b/src/engine/primitives/Rotation.cpp @@ -11,7 +11,7 @@ namespace fgl::engine { - Rotation::Rotation() : glm::quat( 1.0f, 0.0f, 0.0f, 0.0f ) + Rotation::Rotation() : Rotation( 0.0f, 0.0f, 0.0f ) {} inline glm::quat buildQuat( const glm::vec3 euler ) diff --git a/src/engine/primitives/TransformComponent.cpp b/src/engine/primitives/TransformComponent.cpp index 4eb565f..7d31ecf 100644 --- a/src/engine/primitives/TransformComponent.cpp +++ b/src/engine/primitives/TransformComponent.cpp @@ -7,7 +7,8 @@ namespace fgl::engine { - glm::mat4 TransformComponent::mat4() const + template < CoordinateSpace CType > + glm::mat4 TransformComponent< CType >::mat4() const { const glm::mat3 rotation_mat { rotation.mat() }; @@ -17,24 +18,31 @@ namespace fgl::engine { translation.vec().x, translation.vec().y, translation.vec().z, 1.0f } }; } - Matrix< MatrixType::ModelToWorld > TransformComponent::mat() const + template < CoordinateSpace CType > + Matrix< MatrixTransformType< CType >() > TransformComponent< CType >::mat() const { - return Matrix< MatrixType::ModelToWorld >( mat4() ); + return Matrix< MatrixTransformType< CType >() >( mat4() ); } - NormalVector TransformComponent::forward() const + template < CoordinateSpace CType > + NormalVector TransformComponent< CType >::forward() const { return rotation.forward(); } - NormalVector TransformComponent::right() const + template < CoordinateSpace CType > + NormalVector TransformComponent< CType >::right() const { return rotation.right(); } - NormalVector TransformComponent::up() const + template < CoordinateSpace CType > + NormalVector TransformComponent< CType >::up() const { return rotation.up(); } + template struct TransformComponent< CoordinateSpace::World >; + template struct TransformComponent< CoordinateSpace::Model >; + } // namespace fgl::engine diff --git a/src/engine/primitives/TransformComponent.hpp b/src/engine/primitives/TransformComponent.hpp index 509a63e..d6a58e6 100644 --- a/src/engine/primitives/TransformComponent.hpp +++ b/src/engine/primitives/TransformComponent.hpp @@ -13,18 +13,37 @@ namespace fgl::engine template < MatrixType > class Matrix; + template < CoordinateSpace CType > + consteval MatrixType MatrixTransformType() + { + switch ( CType ) + { + case CoordinateSpace::Model: + return MatrixType::InvalidMatrix; + case CoordinateSpace::World: + return MatrixType::ModelToWorld; + case CoordinateSpace::Camera: + FGL_UNREACHABLE(); + case CoordinateSpace::Screen: + FGL_UNREACHABLE(); + default: + FGL_UNREACHABLE(); + } + FGL_UNREACHABLE(); + }; + //TransformComponent is always in world space + template < CoordinateSpace CType = CoordinateSpace::World > struct TransformComponent { - WorldCoordinate translation { constants::WORLD_CENTER }; + Coordinate< CType > translation { constants::WORLD_CENTER }; Scale scale { 1.0f, 1.0f, 1.0f }; - Rotation rotation { 0.0f, 0.0f, 0.0f }; //TODO: Figure this out and replace TransformComponent with a template of CType instead glm::mat4 mat4() const; - Matrix< MatrixType::ModelToWorld > mat() const; + Matrix< MatrixTransformType< CType >() > mat() const; NormalVector forward() const; @@ -39,4 +58,9 @@ namespace fgl::engine NormalVector down() const { return -up(); } }; + // A game object will be going from world to camera space + using GameObjectTransform = TransformComponent< CoordinateSpace::World >; + // using ModelTransform = TransformComponent< CoordinateSpace::Model >; + using WorldTransform = TransformComponent< CoordinateSpace::World >; + } // namespace fgl::engine diff --git a/src/engine/primitives/boxes/AxisAlignedBoundingBox.cpp b/src/engine/primitives/boxes/AxisAlignedBoundingBox.cpp index ca76bb3..141ba2f 100644 --- a/src/engine/primitives/boxes/AxisAlignedBoundingBox.cpp +++ b/src/engine/primitives/boxes/AxisAlignedBoundingBox.cpp @@ -116,7 +116,8 @@ namespace fgl::engine m_top_right_forward( constants::DEFAULT_VEC3 ), m_bottom_left_back( -constants::DEFAULT_VEC3 ) { - if ( oobb.rotation == Rotation() ) // If default rotation then we can simply just take it as the box is + if ( oobb.m_transform.rotation + == Rotation() ) // If default rotation then we can simply just take it as the box is { assert( oobb.topRightForward().vec() != constants::DEFAULT_VEC3 ); assert( oobb.bottomLeftBack().vec() != -constants::DEFAULT_VEC3 ); diff --git a/src/engine/primitives/boxes/OrientedBoundingBox.cpp b/src/engine/primitives/boxes/OrientedBoundingBox.cpp index d297cc4..3d1d96e 100644 --- a/src/engine/primitives/boxes/OrientedBoundingBox.cpp +++ b/src/engine/primitives/boxes/OrientedBoundingBox.cpp @@ -93,8 +93,8 @@ namespace fgl::engine // xp == x positive (Highest x point) // xn == x negative (Lowest x point) - const glm::vec3 xp_yp_zp { middle.vec() + scale }; - const glm::vec3 xn_yn_zn { middle.vec() - scale }; + const glm::vec3 xp_yp_zp { m_transform.translation.vec() + static_cast< glm::vec3 >( m_transform.scale ) }; + const glm::vec3 xn_yn_zn { m_transform.translation.vec() - static_cast< glm::vec3 >( m_transform.scale ) }; const auto xn { xn_yn_zn.x }; const auto yn { xn_yn_zn.y }; @@ -152,7 +152,13 @@ namespace fgl::engine points[ 6 ] = Coordinate< CType >( xn_yn_zn ); points[ 7 ] = Coordinate< CType >( xp_yn_zn ); - //Rotate all the points around middle using the rotation + for ( auto i = 0; i < points.size(); ++i ) + { + const glm::mat3 rot_mat { m_transform.rotation.mat() }; + const glm::vec3 point { points[ i ].vec() }; + + points[ i ] = Coordinate< CType >( rot_mat * point ); + } return points; } @@ -162,11 +168,11 @@ namespace fgl::engine const { ZoneScoped; - assert( middle.vec() != constants::DEFAULT_VEC3 ); - assert( scale != glm::vec3( 0.0f ) ); + assert( m_transform.translation.vec() != constants::DEFAULT_VEC3 ); + assert( m_transform.scale != glm::vec3( 0.0f ) ); - assert( other.middle.vec() != constants::DEFAULT_VEC3 ); - assert( other.scale != glm::vec3( 0.0f ) ); + assert( other.m_transform.translation.vec() != constants::DEFAULT_VEC3 ); + assert( other.m_transform.scale != glm::vec3( 0.0f ) ); const auto& other_points { other.points() }; const auto points { this->points() }; @@ -259,7 +265,7 @@ namespace fgl::engine const glm::vec3 midpoint { ( top_right_forward + bottom_left_back ) / glm::vec3( 2.0f ) }; const glm::vec3 scale { bottom_left_back - midpoint }; - return { Coordinate< CoordinateSpace::Model >( midpoint ), scale }; + return OrientedBoundingBox< CoordinateSpace::Model >( Coordinate< CoordinateSpace::Model >( midpoint ), scale ); } //Synthesize the template diff --git a/src/engine/primitives/boxes/OrientedBoundingBox.hpp b/src/engine/primitives/boxes/OrientedBoundingBox.hpp index 64c92a0..c1fc3e3 100644 --- a/src/engine/primitives/boxes/OrientedBoundingBox.hpp +++ b/src/engine/primitives/boxes/OrientedBoundingBox.hpp @@ -9,8 +9,9 @@ #include "BoundingBox.hpp" #include "engine/constants.hpp" -#include "engine/primitives/Rotation.hpp" +#include "engine/logging/logging.hpp" #include "engine/primitives/Scale.hpp" +#include "engine/primitives/TransformComponent.hpp" #include "engine/primitives/matricies/Matrix.hpp" #include "engine/primitives/points/Coordinate.hpp" @@ -25,31 +26,38 @@ namespace fgl::engine struct ModelVertex; template < CoordinateSpace CType > - struct OrientedBoundingBox : public interface::BoundingBox + struct OrientedBoundingBox final : public interface::BoundingBox { - Coordinate< CType > middle; - glm::vec3 scale; - Rotation rotation; + TransformComponent< CType > m_transform; - OrientedBoundingBox() : middle( constants::DEFAULT_VEC3 ), scale( 0.0f ), rotation() {} + OrientedBoundingBox() : m_transform( Coordinate< CType >( constants::DEFAULT_VEC3 ) ) {} - OrientedBoundingBox( - const Coordinate< CType > pos, glm::vec3 inital_scale, const Rotation inital_rotation = {} ) : - middle( pos ), - scale( inital_scale ), - rotation( inital_rotation ) + OrientedBoundingBox( const Coordinate< CType > pos, const glm::vec3 inital_scale ) : + m_transform( pos, Scale( inital_scale ) ) { assert( pos.vec() != constants::DEFAULT_VEC3 ); assert( inital_scale != constants::DEFAULT_VEC3 ); } + OrientedBoundingBox( const TransformComponent< CType >& transform ) : m_transform( transform ) + { + assert( m_transform.translation.vec() != constants::DEFAULT_VEC3 ); + assert( m_transform.scale != constants::DEFAULT_VEC3 ); + } + public: //! Returns the top left (-x, -y, -z) coordinate - inline Coordinate< CType > bottomLeftBack() const { return middle - Scale( glm::abs( scale ) ); } + Coordinate< CType > bottomLeftBack() const + { + return m_transform.translation - Scale( glm::abs( static_cast< glm::vec3 >( m_transform.scale ) ) ); + } //! Returns the bottom right (x, y, z) coordinate - inline Coordinate< CType > topRightForward() const { return middle + Scale( glm::abs( scale ) ); } + Coordinate< CType > topRightForward() const + { + return m_transform.translation + Scale( glm::abs( static_cast< glm::vec3 >( m_transform.scale ) ) ); + } // 6 sides, 2 triangles each, 3 verts per triangle constexpr static std::uint32_t indicies_count { 6 * 2 * 3 }; @@ -59,11 +67,11 @@ namespace fgl::engine std::array< Coordinate< CType >, POINT_COUNT > points() const; std::array< LineSegment< CType >, LINE_COUNT > lines() const; - NormalVector forward() const { return rotation.forward(); } + NormalVector forward() const { return m_transform.forward(); } - NormalVector right() const { return rotation.right(); } + NormalVector right() const { return m_transform.right(); } - NormalVector up() const { return rotation.up(); } + NormalVector up() const { return m_transform.up(); } OrientedBoundingBox combine( const OrientedBoundingBox& other ) const; }; @@ -72,20 +80,30 @@ namespace fgl::engine OrientedBoundingBox< EvolvedType< MType >() > operator*( const Matrix< MType > matrix, const OrientedBoundingBox< CType > bounding_box ) { - assert( bounding_box.middle.vec() != constants::DEFAULT_VEC3 ); - assert( bounding_box.scale != glm::vec3( 0.0f ) ); + assert( bounding_box.m_transform.translation.vec() != constants::DEFAULT_VEC3 ); + assert( bounding_box.m_transform.scale != glm::vec3( 0.0f ) ); - const Coordinate< EvolvedType< MType >() > new_middle { matrix * bounding_box.middle }; + // Here's to hoping anything I don't use here (skew, perspecitve) doesn't cost any extra performance + // Compiler optimizer plz + [[maybe_unused]] glm::vec3 scale, translation, skew; + glm::quat quat; + [[maybe_unused]] glm::vec4 perspective; + glm::decompose( matrix, scale, quat, translation, skew, perspective ); - const glm::vec3 matrix_scale { glm::length( glm::vec3( matrix[ 0 ] ) ), - glm::length( glm::vec3( matrix[ 1 ] ) ), - glm::length( glm::vec3( matrix[ 2 ] ) ) }; + glm::mat4 mat { 1.0f }; + mat = glm::scale( mat, scale ); + mat = glm::translate( mat, translation ); - const glm::vec3 new_scale { bounding_box.scale * matrix_scale }; + const Coordinate< EvolvedType< MType >() > new_middle { Matrix< MType >( mat ) + * bounding_box.m_transform.translation }; - const Rotation new_rot { glm::quat_cast( matrix.rotmat() ) * bounding_box.rotation }; + const glm::vec3 new_scale { bounding_box.m_transform.scale * scale }; - return OrientedBoundingBox< EvolvedType< MType >() >( new_middle, new_scale, new_rot ); + const Rotation new_rot { quat * static_cast< glm::quat >( bounding_box.m_transform.rotation ) }; + + TransformComponent< EvolvedType< MType >() > transform { new_middle, new_scale, new_rot }; + + return OrientedBoundingBox< EvolvedType< MType >() >( transform ); } OrientedBoundingBox< CoordinateSpace::Model > generateBoundingFromVerts( const std::vector< ModelVertex >& verts ); diff --git a/src/engine/primitives/matricies/Matrix.hpp b/src/engine/primitives/matricies/Matrix.hpp index bbcc378..849603c 100644 --- a/src/engine/primitives/matricies/Matrix.hpp +++ b/src/engine/primitives/matricies/Matrix.hpp @@ -4,6 +4,8 @@ #pragma once +#include +#include #include #include "MatrixEvolvedTypes.hpp" @@ -37,6 +39,17 @@ namespace fgl::engine glm::mat3 rotmat() const { return glm::mat3( *this ); } + // When extracting a quaternion from a matrix the matrix ***MUST*** be pure. No scale or translation is able to be in the same matrix + glm::quat quat() const + { + // Here's to hoping the compiler will properly optimize this function to oblivion? + [[maybe_unused]] glm::vec3 scale, translation, skew; + glm::quat quat; + [[maybe_unused]] glm::vec4 perspective; + glm::decompose( *this, scale, quat, translation, skew, perspective ); + return quat; + } + explicit Matrix( const float i_value = 1.0f ) : glm::mat4( i_value ) {} explicit Matrix( const glm::mat4& matrix ) : glm::mat4( matrix ) {} @@ -45,6 +58,8 @@ namespace fgl::engine { return Matrix( static_cast< glm::mat4 >( *this ) * static_cast< glm::mat4 >( other ) ); } + + glm::mat4 inverse() const { return glm::inverse( *this ); } }; //Lines diff --git a/src/engine/primitives/matricies/MatrixEvolvedTypes.hpp b/src/engine/primitives/matricies/MatrixEvolvedTypes.hpp index e543402..37aaa2d 100644 --- a/src/engine/primitives/matricies/MatrixEvolvedTypes.hpp +++ b/src/engine/primitives/matricies/MatrixEvolvedTypes.hpp @@ -11,6 +11,7 @@ namespace fgl::engine enum class MatrixType { + InvalidMatrix, ModelToWorld, WorldToCamera, diff --git a/src/engine/primitives/points/Coordinate.cpp b/src/engine/primitives/points/Coordinate.cpp index c9ee263..7934c24 100644 --- a/src/engine/primitives/points/Coordinate.cpp +++ b/src/engine/primitives/points/Coordinate.cpp @@ -12,30 +12,30 @@ namespace fgl::engine { template < CoordinateSpace CType > - Coordinate< CType >::Coordinate( const Vector vector ) : glm::vec3( vector.vec() ) + Coordinate< CType >::Coordinate( const Vector& vector ) : glm::vec3( vector.vec() ) {} template < CoordinateSpace CType > - Coordinate< CType > Coordinate< CType >::operator+( const Vector other ) const + Coordinate< CType > Coordinate< CType >::operator+( const Vector& other ) const { return Coordinate< CType >( vec() + other.vec() ); } template < CoordinateSpace CType > - Coordinate< CType > Coordinate< CType >::operator-( const Vector other ) const + Coordinate< CType > Coordinate< CType >::operator-( const Vector& other ) const { return Coordinate< CType >( vec() - other.vec() ); } template < CoordinateSpace CType > - Coordinate< CType >& Coordinate< CType >::operator+=( const Vector other ) + Coordinate< CType >& Coordinate< CType >::operator+=( const Vector& other ) { this->vec() += other.vec(); return *this; } template < CoordinateSpace CType > - Coordinate< CType >& Coordinate< CType >::operator-=( const Vector other ) + Coordinate< CType >& Coordinate< CType >::operator-=( const Vector& other ) { this->vec() -= other.vec(); return *this; diff --git a/src/engine/primitives/points/Coordinate.hpp b/src/engine/primitives/points/Coordinate.hpp index c57b355..42e7e61 100644 --- a/src/engine/primitives/points/Coordinate.hpp +++ b/src/engine/primitives/points/Coordinate.hpp @@ -40,7 +40,7 @@ namespace fgl::engine explicit Coordinate( const float value ) : glm::vec3( value ) {} - explicit Coordinate( Vector vector ); + explicit Coordinate( const Vector& vector ); float& up() { return z; } @@ -58,10 +58,10 @@ namespace fgl::engine const glm::vec3& vec() const { return static_cast< const glm::vec3& >( *this ); } - Coordinate operator+( Vector other ) const; - Coordinate operator-( Vector other ) const; - Coordinate& operator+=( Vector other ); - Coordinate& operator-=( Vector other ); + Coordinate operator+( const Vector& other ) const; + Coordinate operator-( const Vector& other ) const; + Coordinate& operator+=( const Vector& other ); + Coordinate& operator-=( const Vector& other ); Coordinate operator+( NormalVector other ) const; Coordinate operator-( NormalVector other ) const; diff --git a/src/engine/systems/DrawPair.cpp b/src/engine/systems/DrawPair.cpp index b9d2eaf..d2a3736 100644 --- a/src/engine/systems/DrawPair.cpp +++ b/src/engine/systems/DrawPair.cpp @@ -43,20 +43,25 @@ namespace fgl::engine const auto model_components { obj.getComponents< ModelComponent >() }; + const Matrix< MatrixType::ModelToWorld > obj_matrix { obj.getTransform().mat() }; + for ( const auto* model_component_ptr : model_components ) { const auto& model_transform { model_component_ptr->m_transform }; + const Matrix< MatrixType::ModelToWorld > matrix { model_transform.mat() * obj_matrix }; + const auto& comp { *model_component_ptr }; for ( const Primitive& primitive : comp->m_primitives ) { if ( !primitive.ready() ) continue; - const Matrix< MatrixType::ModelToWorld > matrix { obj.getTransform().mat() - * model_transform.mat() }; - // Does this primitive pass the bounds check - if ( !frustum.intersects( matrix * primitive.getBoundingBox() ) ) continue; + const OrientedBoundingBox< CoordinateSpace::World > world_bounding_box { + matrix * primitive.getBoundingBox() + }; + + if ( !frustum.intersects( world_bounding_box ) ) continue; //assert( primitive.m_texture ); const ModelMatrixInfo matrix_info { .model_matrix = matrix, diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index a3f2cbe..b52bcdb 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -12,7 +12,7 @@ if (FGL_ENABLE_TESTS) set(CMAKE_CXX_STANDARD_REQUIRED 23) add_executable(FGLTests ${FGL_TEST_SOURCES}) - target_link_libraries(FGLTests PRIVATE FGLEngine Catch2::Catch2WithMain) + target_link_libraries(FGLTests PUBLIC FGLEngine Catch2::Catch2WithMain) target_compile_definitions(FGLTests PUBLIC GLM_FORCE_RADIANS GLM_FORCE_DEPTH_ZERO_TO_ONE GLM_FORCE_LEFT_HANDED) target_compile_features(FGLTests PRIVATE cxx_std_23) diff --git a/src/tests/src/TransformTests.cpp b/src/tests/src/TransformTests.cpp index 2a074b3..edc99ef 100644 --- a/src/tests/src/TransformTests.cpp +++ b/src/tests/src/TransformTests.cpp @@ -10,6 +10,33 @@ using namespace fgl::engine; +/* +TEST_CASE( "Matrix", "[transform][rotation][translation][matrix]" ) +{ + TransformComponent component {}; + component.scale = glm::vec3( 8.0f ); + component.translation = WorldCoordinate( constants::WORLD_FORWARD * 100.0f ); + + WHEN( "Rotation is set to 90.0f yaw" ) + { + component.rotation = Rotation( 0.0f ).yaw() += glm::radians( 90.0f ); + + GIVEN( "The matrix from the transform" ) + { + const auto matrix { component.mat() }; + + THEN( "The extracted rotation should match the transform rotation" ) + { + REQUIRE( component.rotation.w == Catch::Approx( matrix.quat().w ) ); + REQUIRE( component.rotation.x == Catch::Approx( matrix.quat().x ) ); + REQUIRE( component.rotation.y == Catch::Approx( matrix.quat().y ) ); + REQUIRE( component.rotation.z == Catch::Approx( matrix.quat().z ) ); + } + } + } +} +*/ + TEST_CASE( "Transform", "[transform][rotation][translation]" ) { TransformComponent component; @@ -38,7 +65,7 @@ TEST_CASE( "Transform", "[transform][rotation][translation]" ) WHEN( "Rotated +90 Pitch" ) { //Rotate by pitch - component.rotation.pitch() = glm::radians( glm::radians( 90.0f ) ); + component.rotation.pitch() = glm::radians( 90.0f ); THEN( "Forward should be WORLD_UP" ) { @@ -61,7 +88,7 @@ TEST_CASE( "Transform", "[transform][rotation][translation]" ) // Tests behaviour that a point from WORLD_FORWARD should end up WORLD_DOWN when pitched -90 degrees WHEN( "Rotated -90 Pitch" ) { - component.rotation.pitch() = -glm::radians( glm::radians( 90.0f ) ); + component.rotation.pitch() = -glm::radians( 90.0f ); const glm::vec3 rotated_point { component.mat4() * glm::vec4( TEST_POINT, 1.0f ) }; @@ -74,7 +101,7 @@ TEST_CASE( "Transform", "[transform][rotation][translation]" ) // Tests behaviour that a point from WORLD_FORWARD should end up WORLD_RIGHT when yawed 90 degrees WHEN( "Rotated +90 Yaw" ) { - component.rotation.yaw() = glm::radians( glm::radians( 90.0f ) ); + component.rotation.yaw() = glm::radians( 90.0f ); const glm::vec3 rotated_point { component.mat4() * glm::vec4( TEST_POINT, 1.0f ) }; @@ -87,7 +114,7 @@ TEST_CASE( "Transform", "[transform][rotation][translation]" ) // Tests behaviour that a point from WORLD_FORWARD should end up WORLD_LEFT when yawed -90 degrees WHEN( "Rotated -90 Yaw" ) { - component.rotation.yaw() = -glm::radians( glm::radians( 90.0f ) ); + component.rotation.yaw() = -glm::radians( 90.0f ); const glm::vec3 rotated_point { component.mat4() * glm::vec4( TEST_POINT, 1.0f ) }; @@ -101,7 +128,7 @@ TEST_CASE( "Transform", "[transform][rotation][translation]" ) //This behaviour assumes that WORLD_RIGHT is 90 deg YAW+ from WORLD_FORWARD WHEN( "Rotated +90 Roll" ) { - component.rotation.roll() = glm::radians( glm::radians( 90.0f ) ); + component.rotation.roll() = glm::radians( 90.0f ); const glm::vec3 rotated_point { component.mat4() * glm::vec4( constants::WORLD_RIGHT, 1.0f ) }; @@ -114,7 +141,7 @@ TEST_CASE( "Transform", "[transform][rotation][translation]" ) //Tests behaviour that a point from WORLD_RIGHT should end up WORLD_UP when rolled -90 degrees WHEN( "Rotated -90 Roll" ) { - component.rotation.roll() = -glm::radians( glm::radians( 90.0f ) ); + component.rotation.roll() = -glm::radians( 90.0f ); const glm::vec3 rotated_point { component.mat4() * glm::vec4( constants::WORLD_RIGHT, 1.0f ) }; @@ -125,8 +152,6 @@ TEST_CASE( "Transform", "[transform][rotation][translation]" ) } } - - SECTION( "Translation" ) { WHEN( "Translated Z+" ) diff --git a/src/tests/src/VectorTests.cpp b/src/tests/src/VectorTests.cpp index 2d95606..c3a3b57 100644 --- a/src/tests/src/VectorTests.cpp +++ b/src/tests/src/VectorTests.cpp @@ -70,6 +70,12 @@ TEST_CASE( "Rotation", "[vector][transforms]" ) WHEN( "Rotation is default constructed" ) { Rotation rot {}; + + THEN( "Should match a default quaternion" ) + { + REQUIRE( static_cast< glm::quat >( rot ) == glm::quat( 1.0f, 0.0f, 0.0f, 0.0f ) ); + } + THEN( "Yaw should be 0.0f" ) { REQUIRE( rot.yaw() == 0.0f ); @@ -112,7 +118,17 @@ TEST_CASE( "Rotation", "[vector][transforms]" ) { Rotation rotation { rad_90, 0.0f, 0.0f }; - REQUIRE( rotation.pitch() == Catch::Approx( rad_90 ).epsilon( 0.01 ) ); + THEN( "Pitch should return 90" ) + { + REQUIRE( rotation.pitch() == Catch::Approx( rad_90 ).epsilon( 0.01 ) ); + } + + /* + THEN( "Quaternion should be valid" ) + { + REQUIRE( static_cast< glm::quat >( rotation ) == glm::quat( 0.7071068, 0.7071068, 0, 0 ) ); + } + */ } AND_WHEN( "Given 90.0f yaw" ) @@ -130,6 +146,23 @@ TEST_CASE( "Rotation", "[vector][transforms]" ) } } + GIVEN( "A default identity matrix" ) + { + const Matrix< MatrixType::ModelToWorld > matrix { 1.0f }; + + THEN( "The matrix rot() function should match a default rotation" ) + { + const Rotation default_rot {}; + REQUIRE( default_rot.mat() == matrix.rotmat() ); + } + + WHEN( "Multiplied with a default rotation" ) + { + THEN( "Nothing should happen" ) + {} + } + } + SECTION( "Rotation transforms" ) { WHEN( "Rotated +90 yaw from default" ) diff --git a/src/tests/src/gtest_printers.hpp b/src/tests/src/gtest_printers.hpp index 21e46a3..3a1b71c 100644 --- a/src/tests/src/gtest_printers.hpp +++ b/src/tests/src/gtest_printers.hpp @@ -49,6 +49,15 @@ namespace Catch } }; + template <> + struct StringMaker< glm::quat > + { + static std::string convert( const glm::quat& quat ) + { + return std::format( "({},{},{},{})", quat.w, quat.x, quat.y, quat.z ); + } + }; + template < fgl::engine::MatrixType MType > struct StringMaker< fgl::engine::Matrix< MType > > {