Fixes translation tests

This commit is contained in:
2024-02-22 00:31:02 -05:00
parent fab4c49233
commit 61b9bf1c12
6 changed files with 144 additions and 53 deletions

View File

@@ -20,7 +20,8 @@ namespace fgl::engine
void Camera::setOrthographicProjection( float left, float right, float top, float bottom, float near, float far )
{
ZoneScoped;
projection_matrix = Matrix< MatrixType::CameraToScreen >( glm::orthoLH( left, right, bottom, top, near, far ) );
projection_matrix =
Matrix< MatrixType::CameraToScreen >( glm::orthoLH_ZO( left, right, bottom, top, near, far ) );
//TODO: Figure out frustum culling for orthographic projection. (If we even wanna use it)
}
@@ -28,7 +29,7 @@ namespace fgl::engine
void Camera::setPerspectiveProjection( float fovy, float aspect, float near, float far )
{
ZoneScoped;
projection_matrix = Matrix< MatrixType::CameraToScreen >( glm::perspectiveLH( fovy, aspect, near, far ) );
projection_matrix = Matrix< MatrixType::CameraToScreen >( glm::perspectiveLH_ZO( fovy, aspect, near, far ) );
base_frustum = createFrustum( aspect, fovy, near, far );
}
@@ -71,6 +72,7 @@ namespace fgl::engine
break;
}
case ViewMode::Euler:
[[fallthrough]];
{
//TODO: Implement
//view_matrix = glm::lookAtLH(position, position + );

View File

@@ -69,6 +69,7 @@ namespace fgl::engine
const Matrix< MatrixType::WorldToScreen > getProjectionViewMatrix() const
{
assert( projection_matrix != constants::MAT4_IDENTITY );
return projection_matrix * view_matrix;
}

View File

@@ -22,11 +22,13 @@ namespace fgl::engine::debug
ZoneScoped;
const ImVec2 window_size { windowSize() };
return Coordinate< CoordinateSpace::Screen >( glm::projectZO(
const Coordinate< CoordinateSpace::Screen > screen_point { glm::projectZO(
static_cast< glm::vec3 >( world_point ),
glm::mat4( 1.0f ),
camera.getProjectionViewMatrix(),
glm::vec4( 0.0f, 0.0f, window_size.x, window_size.y ) ) );
glm::vec4( 0.0f, 0.0f, window_size.x, window_size.y ) ) };
return screen_point;
}
ImVec2 glmToImgui( const glm::vec2 vec )

View File

@@ -37,7 +37,7 @@ namespace fgl::engine
case 2:
return { glm::cos( rotation.y ), glm::sin( rotation.y ) };
case 3:
return { glm::cos( -rotation.z ), glm::sin( -rotation.z ) };
return { glm::cos( rotation.z ), glm::sin( rotation.z ) };
}
break;
case YXZ:
@@ -94,9 +94,12 @@ namespace fgl::engine
{
glm::mat4 mat { 1.0f };
const auto [ c1, s1 ] = extract< 1 >( rotation, order );
const auto [ c2, s2 ] = extract< 2 >( rotation, order );
const auto [ c3, s3 ] = extract< 3 >( rotation, order );
Rotation fixed_rotation { rotation };
fixed_rotation.x = -fixed_rotation.x;
const auto [ c1, s1 ] = extract< 1 >( fixed_rotation, order );
const auto [ c2, s2 ] = extract< 2 >( fixed_rotation, order );
const auto [ c3, s3 ] = extract< 3 >( fixed_rotation, order );
switch ( order )
{

View File

@@ -19,7 +19,7 @@ namespace fgl::engine
ZYX,
ZXY,
END_OF_ENUM,
DEFAULT = ZXY
DEFAULT = XZY
};
glm::mat4 taitBryanMatrix( const Rotation rotation, const RotationOrder order = DEFAULT );

View File

@@ -140,6 +140,7 @@ TEST_CASE( "Camera", "[camera]" )
const auto matrix { camera.getProjectionViewMatrix() };
const glm::vec3 point { matrix * glm::vec4( constants::WORLD_CENTER, 1.0f ) };
CAPTURE( matrix );
CAPTURE( point );
REQUIRE( point.x > 0.0f );
@@ -147,69 +148,151 @@ TEST_CASE( "Camera", "[camera]" )
}
}
WHEN( "Camera is translated down by WORLD_DOWN " )
{
camera.setView( constants::WORLD_CENTER + constants::WORLD_DOWN, Rotation( 0.0f ) );
constexpr int window_width { 1920 };
constexpr int window_height { 1080 };
THEN( "camera.getPosition() should be WORLD_DOWN" )
GIVEN( "A window height of 1920x1080" )
{
WHEN( "Camera is translated down by WORLD_DOWN " )
{
REQUIRE( camera.getPosition() == constants::WORLD_DOWN );
camera.setView(
constants::WORLD_CENTER + constants::WORLD_DOWN + constants::WORLD_BACKWARD, Rotation( 0.0f ) );
THEN( "camera.getPosition() should be WORLD_DOWN" )
{
REQUIRE( camera.getPosition() == constants::WORLD_DOWN + constants::WORLD_BACKWARD );
}
const auto view_matrix { camera.getViewMatrix() };
const auto projection_matrix { camera.getProjectionMatrix() };
const auto matrix { camera.getProjectionViewMatrix() };
CAPTURE( view_matrix );
CAPTURE( projection_matrix );
CAPTURE( matrix );
const glm::vec3 point { glm::projectZO(
constants::WORLD_CENTER,
glm::mat4( 1.0f ),
matrix,
glm::vec4( 0.0f, 0.0f, window_width, window_height ) ) };
THEN( "A point should be above the half way point of the screen" )
{
CAPTURE( point );
//Because vulkan starts at the top left, the y axis is inverted [0, 1] where 0 is the top. 1 is the bottom.
// This means that a point 'below' the half way mark on the screen will actually be more positive.
REQUIRE( point.y < window_height / 2.0f );
}
THEN( "A point should be in the view of the screen" )
{
REQUIRE( point.x >= 0.0f );
REQUIRE( point.x <= window_width );
REQUIRE( point.y >= 0.0f );
REQUIRE( point.y <= window_height );
}
THEN( "A point should be infront of the camera" )
{
REQUIRE( point.z >= 0.0f );
AND_THEN( "The point should not be in front of the camera" )
{
REQUIRE( point.z <= 1.0f );
}
}
}
THEN( "A point at the origin must be translated up" )
WHEN( "Camera is translated up by WORLD_UP" )
{
camera.setView(
constants::WORLD_CENTER + constants::WORLD_UP + constants::WORLD_BACKWARD, Rotation( 0.0f ) );
THEN( "camera.getPosition() should be WORLD_UP" )
{
const auto position { camera.getPosition() };
REQUIRE( position == constants::WORLD_UP + constants::WORLD_BACKWARD );
}
const auto view_matrix { camera.getViewMatrix() };
const auto projection_matrix { camera.getProjectionMatrix() };
const auto matrix { camera.getProjectionViewMatrix() };
const glm::vec3 point { matrix * glm::vec4( constants::WORLD_CENTER, 1.0f ) };
CAPTURE( view_matrix );
CAPTURE( projection_matrix );
CAPTURE( matrix );
const glm::vec3 point { glm::projectZO(
constants::WORLD_CENTER,
glm::mat4( 1.0f ),
matrix,
glm::vec4( 0.0f, 0.0f, window_width, window_height ) ) };
CAPTURE( point );
REQUIRE( point.x == 0.0f );
REQUIRE( point.y > 0.0f );
}
}
THEN( "A point should be below the half way point of the screen" )
{
//Because vulkan starts at the top left, the y axis is inverted [0, 1] where 0 is the top. 1 is the bottom.
// This means that a point 'below' the half way mark on the screen will actually be more positive.
REQUIRE( point.y > ( window_height / 2 ) );
}
WHEN( "Camera is translated up by WORLD_UP" )
{
camera.setView( constants::WORLD_CENTER + constants::WORLD_UP, Rotation( 0.0f ) );
THEN( "A point should be in the view of the screen" )
{
REQUIRE( point.x >= 0.0f );
REQUIRE( point.x <= window_width );
REQUIRE( point.y >= 0.0f );
REQUIRE( point.y <= window_height );
}
THEN( "camera.getPosition() should be WORLD_UP" )
{
const auto position { camera.getPosition() };
REQUIRE( position == constants::WORLD_UP );
THEN( "A point should be in front of the camera" )
{
REQUIRE( point.z > 0.0f );
AND_THEN( "The point should not be behind the camera" )
{
REQUIRE( point.z < 1.0f );
}
}
}
THEN( "A point at the origin should be translated down" )
WHEN( "Camera is translated forward by WORLD_FORWARD" )
{
const auto matrix { camera.getProjectionViewMatrix() };
const glm::vec3 point { matrix * glm::vec4( constants::WORLD_CENTER, 1.0f ) };
camera.setView( constants::WORLD_CENTER + constants::WORLD_FORWARD, Rotation( 0.0f ) );
CAPTURE( point );
THEN( "camera.getPosition() should be WORLD_FORWARD" )
{
const auto position { camera.getPosition() };
REQUIRE( position == constants::WORLD_FORWARD );
}
REQUIRE( point.x == 0.0f );
REQUIRE( point.y < 0.0f );
}
}
AND_WHEN( "A point is processed through the matrix" )
{
const auto matrix { camera.getProjectionViewMatrix() };
const glm::vec3 point { glm::projectZO(
constants::WORLD_CENTER,
glm::mat4( 1.0f ),
matrix,
glm::vec4( 0.0f, 0.0f, window_width, window_height ) ) };
WHEN( "Camera is translated forward by WORLD_FORWARD" )
{
camera.setView( constants::WORLD_CENTER + constants::WORLD_FORWARD, Rotation( 0.0f ) );
THEN( "A point at the origin should be translated back" )
{
CAPTURE( point );
THEN( "camera.getPosition() should be WORLD_FORWARD" )
{
const auto position { camera.getPosition() };
REQUIRE( position == constants::WORLD_FORWARD );
}
THEN( "Point should be in the view of the screen" )
{
REQUIRE( point.x >= 0.0f );
REQUIRE( point.x <= window_width );
REQUIRE( point.y >= 0.0f );
REQUIRE( point.y <= window_height );
}
THEN( "A point at the origin should be translated back" )
{
const auto matrix { camera.getProjectionViewMatrix() };
const auto point { matrix * glm::vec4( constants::WORLD_CENTER, 1.0f ) };
CAPTURE( point );
REQUIRE( point.x <= 0.0f );
REQUIRE( point.y <= 0.0f );
REQUIRE( point.z < 0.0f );
THEN( "Point should be behind the camera" )
{
//Comparing to 1 since the point should be behind the camera (0 to 1 is 'forward' to Z plane. Anything Above 1 is behind)
REQUIRE( point.z > 1.0f );
}
}
}
}
}
}