Fixes bug with bounding box becoming negatively scaled

This commit is contained in:
2024-03-13 01:15:27 -04:00
parent 5295d9a1f3
commit d2dfa849ce
11 changed files with 70 additions and 339 deletions

View File

@@ -26,6 +26,7 @@
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Wconversion"
#include "debug/imguiMenuDraw.hpp"
#include "imgui/imgui.h"
#include "imgui/imgui_impl_glfw.h"
#include "imgui/imgui_impl_vulkan.h"
@@ -164,7 +165,7 @@ namespace fgl::engine
FrameInfo frame_info { frame_index,
delta_time,
command_buffer,
camera,
{ camera, viewer.m_transform },
global_descriptor_sets[ frame_index ],
m_game_objects_root,
m_renderer.getCurrentTracyCTX(),
@@ -173,6 +174,8 @@ namespace fgl::engine
m_renderer.getGBufferDescriptor( frame_index ),
view_frustum };
debug::imGuiMenuDraw( frame_info );
#if TRACY_ENABLE
auto& tracy_ctx { frame_info.tracy_ctx };
#endif
@@ -182,254 +185,6 @@ namespace fgl::engine
camera_info[ frame_index ] = current_camera_info;
#if ENABLE_IMGUI
{
ZoneScopedN( "ImGui recording" );
ImGui::Begin( "Titor Dev Menu" );
ImGui::Text( "Framerate" );
ImGui::SameLine();
ImGui::Text( "%.1f FPS", static_cast< double >( ImGui::GetIO().Framerate ) );
ImGui::Text( "Frame Time" );
ImGui::SameLine();
ImGui::Text( "%.3f ms", static_cast< double >( 1000.0f / ImGui::GetIO().Framerate ) );
ImGui::Text(
"Average rolling frametime: %.3f ms", static_cast< double >( rolling_ms_average.average() ) );
auto inputVec3 = []( const std::string label, glm::vec3 vec )
{
ImGui::PushID( label.c_str() );
ImGui::PushItemWidth( 80 );
ImGui::Text( label.c_str() );
ImGui::DragFloat( "X", &vec.x, 0.1f );
ImGui::SameLine();
ImGui::DragFloat( "Y", &vec.y, 0.1f );
ImGui::SameLine();
ImGui::DragFloat( "Z", &vec.z, 0.1f );
ImGui::PopItemWidth();
ImGui::PopID();
};
auto inputRVec3 = [ &inputVec3 ]( const std::string label, [[maybe_unused]] Rotation& rot )
{
ImGui::PushID( label.c_str() );
//TODO: Fix this
ImGui::PopID();
};
if ( ImGui::CollapsingHeader( "Camera" ) )
{
if ( ImGui::Button( "Reset camera" ) )
{
viewer.m_transform.translation = WorldCoordinate( constants::WORLD_CENTER );
viewer.m_transform.rotation = {};
}
ImGui::PushItemWidth( 80 );
ImGui::DragFloat( "Pos X", &viewer.m_transform.translation.vec().x, 0.1f );
ImGui::SameLine();
ImGui::DragFloat( "Pos Y", &viewer.m_transform.translation.vec().y, 0.1f );
ImGui::SameLine();
ImGui::DragFloat( "Pos Z", &viewer.m_transform.translation.vec().z, 0.1f );
ImGui::PopItemWidth();
ImGui::Separator();
ImGui::PushItemWidth( 80 );
//TODO: Print rotation here again
ImGui::SameLine();
ImGui::
Text( "Pitch %.4f", static_cast< double >( viewer.m_transform.rotation.pitch().value() ) );
ImGui::SameLine();
ImGui::Text( "Yaw %.4f", static_cast< double >( viewer.m_transform.rotation.yaw().value() ) );
ImGui::SameLine();
ImGui::Text( "Roll %.4f", static_cast< double >( viewer.m_transform.rotation.roll().value() ) );
ImGui::PopItemWidth();
ImGui::Separator();
ImGui::Checkbox( "Update Frustum", &camera.update_frustums );
ImGui::Separator();
ImGui::Checkbox( "Use Alt Frustum matrix", &camera.update_using_alt );
if ( ImGui::CollapsingHeader( "Frustum matrix", &camera.update_using_alt ) )
{
ImGui::PushID( "FrustumMatrix" );
inputVec3( "Translation", Camera::frustum_alt_transform.translation.vec() );
inputRVec3( "Rotation", Camera::frustum_alt_transform.rotation );
ImGui::PopID();
}
if ( camera.update_using_alt || !camera.update_frustums )
{
debug::world::drawFrustum();
}
}
if ( ImGui::CollapsingHeader( "View Frustum" ) )
{
const auto& frustum { camera.getFrustumBounds() };
auto printVec3 = []( const glm::vec3& vec )
{
ImGui::Text(
"(%.2f, %.2f, %.2f)",
static_cast< double >( vec.x ),
static_cast< double >( vec.y ),
static_cast< double >( vec.z ) );
};
auto printPlane = [ printVec3 ]( const auto& plane, const std::string name )
{
const std::string name_str { "Plane " + name + ": " };
ImGui::Text( name_str.c_str() );
ImGui::SameLine( 120.0f );
printVec3( plane.getDirection().vec() );
ImGui::SameLine();
ImGui::Text( "Distance: %.3f", static_cast< double >( plane.distance() ) );
const auto pos { plane.getPosition() };
ImGui::Text(
"Center: %.2f %.2f %.2f",
static_cast< double >( pos.vec().x ),
static_cast< double >( pos.vec().y ),
static_cast< double >( pos.vec().z ) );
};
printPlane( frustum.near, "Near" );
printPlane( frustum.far, "Far" );
printPlane( frustum.top, "Top" );
printPlane( frustum.bottom, "Bottom" );
printPlane( frustum.right, "Right" );
printPlane( frustum.left, "Left" );
}
imGuiFrustumSettings();
imGuiOctTreeSettings();
if ( ImGui::CollapsingHeader( "Game Objects" ) )
{
for ( auto* leaf : m_game_objects_root.getAllLeafs() )
{
for ( auto& game_object : *leaf )
{
if ( game_object.m_model == nullptr ) continue;
ImGui::PushID( std::to_string( game_object.getId() ).c_str() );
if ( ImGui::TreeNode( game_object.m_model->getName().c_str() ) )
{
ImGui::PushID( game_object.m_model->getName().c_str() );
{
ImGui::PushID( "Position" );
ImGui::PushItemWidth( 80 );
ImGui::Text( "Position" );
ImGui::SameLine();
ImGui::DragFloat( "X", &game_object.m_transform.translation.vec().x, 0.1f );
ImGui::SameLine();
ImGui::DragFloat( "Y", &game_object.m_transform.translation.vec().y, 0.1f );
ImGui::SameLine();
ImGui::DragFloat( "Z", &game_object.m_transform.translation.vec().z, 0.1f );
ImGui::PopID();
}
ImGui::Separator();
{
ImGui::PushID( "Rotation" );
ImGui::PushItemWidth( 80 );
ImGui::Text( "Rotation" );
ImGui::SameLine();
ImGui::Text(
"Pitch %.4f",
static_cast< double >( game_object.m_transform.rotation.pitch().value() ) );
ImGui::SameLine();
ImGui::Text(
"Yaw %.4f",
static_cast< double >( game_object.m_transform.rotation.yaw().value() ) );
ImGui::SameLine();
ImGui::Text(
"Roll %.4f",
static_cast< double >( game_object.m_transform.rotation.roll().value() ) );
ImGui::PopID();
}
ImGui::Separator();
{
ImGui::PushID( "Scale" );
ImGui::PushItemWidth( 80 );
ImGui::Text( "Scale" );
ImGui::SameLine();
ImGui::DragFloat( "X", &game_object.m_transform.scale.x, 0.1f );
ImGui::SameLine();
ImGui::DragFloat( "Y", &game_object.m_transform.scale.y, 0.1f );
ImGui::SameLine();
ImGui::DragFloat( "Z", &game_object.m_transform.scale.z, 0.1f );
ImGui::TreePop();
ImGui::PopID();
}
if ( ImGui::CollapsingHeader( "Textures" ) )
{
std::vector< TextureID > textures;
ImGui::PushID( "Textures" );
for ( auto& primitive : game_object.m_model->m_primitives )
{
if ( !primitive.m_texture.has_value() ) continue;
auto& texture { primitive.m_texture.value() };
const auto& extent { texture.getExtent() };
auto& image_view { texture.getImageView() };
auto& sampler { image_view.getSampler() };
if ( !sampler.has_value() ) continue;
ImVec2 size;
size.x = static_cast< float >( extent.width );
size.y = static_cast< float >( extent.height );
if ( std::find( textures.begin(), textures.end(), texture.getID() )
== textures.end() )
{
textures.emplace_back( texture.getID() );
ImGui::Image(
static_cast< ImTextureID >( primitive.m_texture
->getImGuiDescriptorSet() ),
size );
}
}
ImGui::PopID();
}
ImGui::PopID();
}
ImGui::PopID();
}
}
}
//TODO: Add in a collapsable header to view all buffers, And their suballocations
if ( ImGui::CollapsingHeader( "Buffer allocations" ) )
{
for ( const auto& buffer : Buffer::getActiveBufferHandles() )
{
ImGui::Text( "Address: %p", static_cast< void* >( buffer.lock()->address() ) );
ImGui::Text( "Size: %zu", buffer.lock()->size() );
}
}
}
#endif
#if TRACY_ENABLE
m_culling_system.startPass( frame_info );
TracyVkCollect( frame_info.tracy_ctx, command_buffer );
@@ -505,14 +260,15 @@ namespace fgl::engine
model->syncBuffers( command_buffer );
constexpr int val { 32 };
constexpr int x_val { 32 };
constexpr int y_val { x_val };
constexpr float x_offset { -( static_cast< float >( val ) * 30.0f ) / 2.0f };
constexpr float y_offset { -( static_cast< float >( val ) * 20.0f ) / 2.0f };
constexpr float x_offset { -( static_cast< float >( x_val ) * 30.0f ) / 2.0f };
constexpr float y_offset { -( static_cast< float >( y_val ) * 20.0f ) / 2.0f };
for ( int x = 0; x < val; ++x )
for ( int x = 0; x < x_val; ++x )
{
for ( int y = 0; y < val; ++y )
for ( int y = 0; y < y_val; ++y )
{
auto sponza = GameObject::createGameObject();
sponza.m_model = model;
@@ -520,6 +276,7 @@ namespace fgl::engine
x_offset + ( static_cast< float >( y ) * 30.0f ),
y_offset + ( static_cast< float >( x ) * 20.0f ),
float( rand() % 120 ) - 60.0f );
// 0.0f );
sponza.m_transform.scale = { 0.007f, 0.007f, 0.007f };
sponza.m_transform.rotation = Rotation( 0.0f, 0.0f, 0.0f );

View File

@@ -71,7 +71,13 @@ namespace fgl::engine
std::uint16_t frame_idx;
float frame_time;
vk::CommandBuffer command_buffer;
Camera& camera;
struct
{
Camera& camera;
TransformComponent& camera_transform;
} camera_data;
DescriptorSet& global_descriptor_set;
OctTreeNode& game_objects;
TracyVkCtx tracy_ctx;

View File

@@ -29,7 +29,7 @@ namespace fgl::engine
Primitive(
VertexBufferSuballocation&& vertex_buffer,
IndexBufferSuballocation&& index_buffer,
OrientedBoundingBox< CoordinateSpace::Model >& bounding_box ) :
const OrientedBoundingBox< CoordinateSpace::Model >& bounding_box ) :
m_vertex_buffer( std::move( vertex_buffer ) ),
m_index_buffer( std::move( index_buffer ) ),
m_bounding_box( bounding_box )
@@ -38,7 +38,7 @@ namespace fgl::engine
Primitive(
VertexBufferSuballocation&& vertex_buffer,
IndexBufferSuballocation&& index_buffer,
OrientedBoundingBox< CoordinateSpace::Model >& bounding_box,
const OrientedBoundingBox< CoordinateSpace::Model >& bounding_box,
Texture&& texture ) :
m_vertex_buffer( std::move( vertex_buffer ) ),
m_index_buffer( std::move( index_buffer ) ),

View File

@@ -185,7 +185,7 @@ namespace fgl::engine
verts[ i ].m_normal = normals[ i ];
}
ModelBoundingBox bounding_box { generateBoundingFromVerts( verts ) };
const ModelBoundingBox bounding_box { generateBoundingFromVerts( verts ) };
if ( texcoords.size() > 0 && texcoords.size() != verts.size() )
{

View File

@@ -89,13 +89,7 @@ namespace fgl::engine
}
}
std::vector< Coordinate< CoordinateSpace::Model > > vert_pos;
for ( const auto& vert : verts )
{
vert_pos.emplace_back( vert.m_position );
}
OrientedBoundingBox bounding_box { generateBoundingFromPoints( vert_pos ) };
const OrientedBoundingBox bounding_box { generateBoundingFromVerts( verts ) };
m_primitives.emplace_back(
VertexBufferSuballocation( m_vertex_buffer, std::move( verts ) ),

View File

@@ -113,13 +113,13 @@ namespace fgl::engine
template < CoordinateSpace CType >
AxisAlignedBoundingBox< CType >::AxisAlignedBoundingBox( const OrientedBoundingBox< CType >& oobb ) :
m_top_right_forward( -constants::DEFAULT_VEC3 ),
m_bottom_left_back( constants::DEFAULT_VEC3 )
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
{
m_top_right_forward = oobb.middle + oobb.scale;
m_bottom_left_back = oobb.middle - oobb.scale;
m_top_right_forward = oobb.topRightForward();
m_bottom_left_back = oobb.bottomLeftBack();
}
else
{
@@ -135,13 +135,15 @@ namespace fgl::engine
m_bottom_left_back.z = std::min( m_bottom_left_back.z, point.z );
}
}
assert( m_top_right_forward.vec() != constants::DEFAULT_VEC3 );
assert( m_bottom_left_back.vec() != -constants::DEFAULT_VEC3 );
}
template < CoordinateSpace CType >
AxisAlignedBoundingBox< CType >& AxisAlignedBoundingBox< CType >::combine( const OrientedBoundingBox< CType >&
other )
{
AxisAlignedBoundingBox< CType > aabb { other };
const AxisAlignedBoundingBox< CType > aabb { other };
if ( this->m_top_right_forward == Coordinate< CType >( constants::DEFAULT_VEC3 )
|| this->m_bottom_left_back == Coordinate< CType >( constants::DEFAULT_VEC3 ) )
return *this = aabb;

View File

@@ -29,11 +29,19 @@ namespace fgl::engine
const Coordinate< CType > top_right_forward, const Coordinate< CType > bottom_left_back ) :
m_top_right_forward( top_right_forward ),
m_bottom_left_back( bottom_left_back )
{}
{
assert( m_top_right_forward.x > m_bottom_left_back.x );
assert( m_top_right_forward.y > m_bottom_left_back.y );
assert( m_top_right_forward.z > m_bottom_left_back.z );
}
explicit AxisAlignedBoundingBox( const Coordinate< CType > midpoint, const Scale scale ) :
AxisAlignedBoundingBox( midpoint + scale, midpoint - scale )
{}
{
assert( m_top_right_forward.x > m_bottom_left_back.x );
assert( m_top_right_forward.y > m_bottom_left_back.y );
assert( m_top_right_forward.z > m_bottom_left_back.z );
}
explicit AxisAlignedBoundingBox( const OrientedBoundingBox< CType >& oobb );

View File

@@ -8,7 +8,6 @@
#include "engine/model/Vertex.hpp"
#include "engine/primitives/lines/LineSegment.hpp"
#include "engine/primitives/matricies/Matrix.hpp"
#include "engine/primitives/points/Coordinate.hpp"
namespace fgl::engine
@@ -175,7 +174,7 @@ namespace fgl::engine
std::copy( points.begin(), points.end(), combined_points.begin() + POINT_COUNT );
//TODO: There might be a way to do this without needing to do yet another point calculation.
return generateBoundingFromPoints< CType >( points );
return generateBoundingFromPoints< CType >( combined_points );
}
template < CoordinateSpace CType >
@@ -210,86 +209,52 @@ namespace fgl::engine
OrientedBoundingBox< CType > generateBoundingFromPoints( const std::array< Coordinate< CType >, TCount >& points )
{
ZoneScoped;
assert( points.size() > 0 );
// neg (min)
glm::vec3 top_left_front { points[ 0 ].vec() };
glm::vec3 top_right_forward { points[ 0 ].vec() };
// pos (max)
glm::vec3 bottom_right_back { points[ 0 ].vec() };
glm::vec3 bottom_left_back { points[ 0 ].vec() };
for ( const auto& pos : points )
{
top_left_front.x = std::min( pos.vec().x, top_left_front.x );
top_left_front.y = std::min( pos.vec().y, top_left_front.y );
top_left_front.z = std::min( pos.vec().z, top_left_front.z );
top_right_forward.x = std::max( pos.vec().x, top_right_forward.x );
top_right_forward.y = std::max( pos.vec().y, top_right_forward.y );
top_right_forward.z = std::max( pos.vec().z, top_right_forward.z );
bottom_right_back.x = std::max( pos.vec().x, bottom_right_back.x );
bottom_right_back.y = std::max( pos.vec().y, bottom_right_back.y );
bottom_right_back.z = std::max( pos.vec().z, bottom_right_back.z );
bottom_left_back.x = std::min( pos.vec().x, bottom_left_back.x );
bottom_left_back.y = std::min( pos.vec().y, bottom_left_back.y );
bottom_left_back.z = std::min( pos.vec().z, bottom_left_back.z );
}
//Calculate midpoint
const glm::vec3 midpoint { ( top_left_front + bottom_right_back ) / glm::vec3( 2.0f ) };
const glm::vec3 scale { bottom_right_back - midpoint };
const glm::vec3 midpoint { ( top_right_forward + bottom_left_back ) / glm::vec3( 2.0f ) };
const glm::vec3 scale { bottom_left_back - midpoint };
return { Coordinate< CType >( midpoint ), scale };
}
template < CoordinateSpace CType >
OrientedBoundingBox< CType > generateBoundingFromPoints( const std::vector< Coordinate< CType > >& points )
{
ZoneScoped;
assert( points.size() > 0 );
// neg (min)
glm::vec3 top_left_front { points[ 0 ].vec() };
// pos (max)
glm::vec3 bottom_right_back { points[ 0 ].vec() };
for ( const auto& pos : points )
{
top_left_front.x = std::min( pos.vec().x, top_left_front.x );
top_left_front.y = std::min( pos.vec().y, top_left_front.y );
top_left_front.z = std::min( pos.vec().z, top_left_front.z );
bottom_right_back.x = std::max( pos.vec().x, bottom_right_back.x );
bottom_right_back.y = std::max( pos.vec().y, bottom_right_back.y );
bottom_right_back.z = std::max( pos.vec().z, bottom_right_back.z );
}
//Calculate midpoint
const glm::vec3 midpoint { ( top_left_front + bottom_right_back ) / glm::vec3( 2.0f ) };
const glm::vec3 scale { bottom_right_back - midpoint };
return { Coordinate< CType >( midpoint ), scale };
}
template OrientedBoundingBox< CoordinateSpace::Model > generateBoundingFromPoints( const std::vector< Coordinate<
CoordinateSpace::Model > >&
points );
OrientedBoundingBox< CoordinateSpace::Model > generateBoundingFromVerts( const std::vector< Vertex >& verts )
{
// neg (min)
glm::vec3 top_left_front { verts[ 0 ].m_position };
glm::vec3 top_right_forward { verts[ 0 ].m_position };
// pos (max)
glm::vec3 bottom_right_back { verts[ 0 ].m_position };
glm::vec3 bottom_left_back { verts[ 0 ].m_position };
for ( const auto& vert : verts )
{
const auto& pos { vert.m_position };
top_left_front.x = std::min( static_cast< glm::vec3 >( pos ).x, top_left_front.x );
top_left_front.y = std::min( static_cast< glm::vec3 >( pos ).y, top_left_front.y );
top_left_front.z = std::min( static_cast< glm::vec3 >( pos ).z, top_left_front.z );
top_right_forward.x = std::max( pos.x, top_right_forward.x );
top_right_forward.y = std::max( pos.y, top_right_forward.y );
top_right_forward.z = std::max( pos.z, top_right_forward.z );
bottom_right_back.x = std::max( static_cast< glm::vec3 >( pos ).x, bottom_right_back.x );
bottom_right_back.y = std::max( static_cast< glm::vec3 >( pos ).y, bottom_right_back.y );
bottom_right_back.z = std::max( static_cast< glm::vec3 >( pos ).z, bottom_right_back.z );
bottom_left_back.x = std::min( pos.x, bottom_left_back.x );
bottom_left_back.y = std::min( pos.y, bottom_left_back.y );
bottom_left_back.z = std::min( pos.z, bottom_left_back.z );
}
//Calculate midpoint
const glm::vec3 midpoint { ( top_left_front + bottom_right_back ) / glm::vec3( 2.0f ) };
const glm::vec3 scale { bottom_right_back - midpoint };
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 };
}

View File

@@ -41,15 +41,13 @@ namespace fgl::engine
rotation( inital_rotation )
{}
private:
public:
//! Returns the top left (-x, -y, -z) coordinate
inline glm::vec3 bottomLeftBack() const { return middle.vec() - scale; }
inline Coordinate< CType > bottomLeftBack() const { return middle - Scale( glm::abs( scale ) ); }
//! Returns the bottom right (x, y, z) coordinate
inline glm::vec3 topRightForward() const { return middle.vec() + scale; }
public:
inline Coordinate< CType > topRightForward() const { return middle + Scale( glm::abs( scale ) ); }
// 6 sides, 2 triangles each, 3 verts per triangle
constexpr static std::uint32_t indicies_count { 6 * 2 * 3 };
@@ -79,10 +77,7 @@ namespace fgl::engine
return OrientedBoundingBox< EvolvedType< MType >() >( new_middle, new_scale, new_rot );
}
template < CoordinateSpace CType >
OrientedBoundingBox< CType > generateBoundingFromPoints( const std::vector< Coordinate< CType > >& points );
OrientedBoundingBox< CoordinateSpace::Model > generateBoundingFromVerts( const std::vector< Vertex >& points );
OrientedBoundingBox< CoordinateSpace::Model > generateBoundingFromVerts( const std::vector< Vertex >& verts );
using ModelBoundingBox = OrientedBoundingBox< CoordinateSpace::Model >;

View File

@@ -123,6 +123,8 @@ namespace fgl::engine
if ( !obj.m_is_visible ) continue;
// debug::world::drawBoundingBox( obj.getBoundingBox() );
++object_counter;
for ( const auto& primitive : obj.m_model->m_primitives )

View File

@@ -342,6 +342,7 @@ namespace fgl::engine
{
for ( std::size_t z = 0; z < 2; ++z )
{
if ( x == 0 && y == 0 && z == 0 ) continue;
auto& node { nodes[ x ][ y ][ z ] };
new_bounds.combine( node->m_fit_bounding_box );
}
@@ -372,9 +373,10 @@ namespace fgl::engine
[[assume( game_objects.size() <= MAX_NODES_IN_LEAF )]];
for ( const GameObject& obj : game_objects )
for ( std::size_t i = 1; i < game_objects.size(); ++i )
{
new_bounds.combine( obj.getBoundingBox() );
[[assume( i <= MAX_NODES_IN_LEAF )]];
new_bounds.combine( game_objects[ i ].getBoundingBox() );
}
if ( new_bounds == old_bounds )