Fixes bounding box fuckery

This commit is contained in:
2024-08-14 14:22:41 -04:00
parent 576d409092
commit 83d4aa4d89
23 changed files with 227 additions and 83 deletions

View File

@@ -26,7 +26,7 @@ namespace fgl::engine
{
class DescriptorSet;
}
struct TransformComponent;
class SwapChain;
class Camera;

View File

@@ -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;

View File

@@ -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; }

View File

@@ -12,7 +12,7 @@
namespace fgl::engine
{
struct ComponentTransform final : public TransformComponent
struct ComponentTransform final : public TransformComponent< CoordinateSpace::World >
{
enum Mode
{

View File

@@ -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

View File

@@ -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;

View File

@@ -15,6 +15,7 @@
#include <engine/logging/logging.hpp>
#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 );

View File

@@ -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 );

View File

@@ -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 )

View File

@@ -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

View File

@@ -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

View File

@@ -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 );

View File

@@ -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

View File

@@ -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 );

View File

@@ -4,6 +4,8 @@
#pragma once
#include <glm/gtc/quaternion.hpp>
#include <glm/gtx/matrix_decompose.hpp>
#include <glm/mat4x4.hpp>
#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

View File

@@ -11,6 +11,7 @@ namespace fgl::engine
enum class MatrixType
{
InvalidMatrix,
ModelToWorld,
WorldToCamera,

View File

@@ -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;

View File

@@ -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;

View File

@@ -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,

View File

@@ -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)

View File

@@ -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+" )

View File

@@ -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" )

View File

@@ -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 > >
{