Optimization

This commit is contained in:
2024-03-12 22:10:02 -04:00
parent 7374f8de8c
commit 5295d9a1f3
19 changed files with 256 additions and 124 deletions

View File

@@ -505,7 +505,7 @@ namespace fgl::engine
model->syncBuffers( command_buffer );
constexpr int val { 4 };
constexpr int val { 32 };
constexpr float x_offset { -( static_cast< float >( val ) * 30.0f ) / 2.0f };
constexpr float y_offset { -( static_cast< float >( val ) * 20.0f ) / 2.0f };

View File

@@ -83,6 +83,8 @@ namespace fgl::engine
DescriptorSet& gbuffer_descriptor_set;
const Frustum< CoordinateSpace::World >& camera_frustum;
std::vector< std::vector< GameObject >* > in_view_leafs {};
};
} // namespace fgl::engine

View File

@@ -81,6 +81,15 @@ namespace fgl::engine
template < typename T >
bool intersects( const T& t ) const;
template < typename T, std::size_t TSize >
inline bool intersects( const std::array< T, TSize >& t ) const
{
for ( std::size_t i = 0; i < TSize; ++i )
if ( intersects( t[ i ] ) ) return true;
return false;
}
template < typename T >
Coordinate< CType > intersection( const T& t ) const;

View File

@@ -17,9 +17,10 @@ namespace fgl::engine
}
template < CoordinateSpace CType >
std::vector< Coordinate< CType > > AxisAlignedBoundingBox< CType >::points() const
std::array< Coordinate< CType >, interface::BoundingBox::POINT_COUNT > AxisAlignedBoundingBox< CType >::points()
const
{
std::vector< Coordinate< CType > > points;
std::array< Coordinate< CType >, POINT_COUNT > points {};
// xp == x positive (Highest x point)
// xn == x negative (Lowest x point)
@@ -40,7 +41,6 @@ namespace fgl::engine
const glm::vec3 xn_yp_zn { xn, yp, zn }; // (- + -)
const glm::vec3 xp_yp_zn { xp, yp, zn }; // (+ + -)
points.resize( 8 );
points[ 0 ] = Coordinate< CType >( xp_yp_zp );
points[ 1 ] = Coordinate< CType >( xn_yp_zp );
points[ 2 ] = Coordinate< CType >( xn_yp_zn );
@@ -62,29 +62,30 @@ namespace fgl::engine
}
template < CoordinateSpace CType >
std::vector< LineSegment< CType > > AxisAlignedBoundingBox< CType >::lines() const
std::array< LineSegment< CType >, interface::BoundingBox::LINE_COUNT > AxisAlignedBoundingBox< CType >::lines()
const
{
const auto points { this->points() };
std::vector< LineSegment< CType > > lines;
std::array< LineSegment< CType >, LINE_COUNT > lines {};
//Top
lines.emplace_back( points[ 0 ], points[ 1 ] );
lines.emplace_back( points[ 1 ], points[ 2 ] );
lines.emplace_back( points[ 2 ], points[ 3 ] );
lines.emplace_back( points[ 3 ], points[ 0 ] );
lines[ 0 ] = LineSegment< CType >( points[ 0 ], points[ 1 ] );
lines[ 1 ] = LineSegment< CType >( points[ 1 ], points[ 2 ] );
lines[ 2 ] = LineSegment< CType >( points[ 2 ], points[ 3 ] );
lines[ 3 ] = LineSegment< CType >( points[ 3 ], points[ 0 ] );
//Bottom
lines.emplace_back( points[ 4 ], points[ 5 ] );
lines.emplace_back( points[ 5 ], points[ 6 ] );
lines.emplace_back( points[ 6 ], points[ 7 ] );
lines.emplace_back( points[ 7 ], points[ 4 ] );
lines[ 4 ] = LineSegment< CType >( points[ 4 ], points[ 5 ] );
lines[ 5 ] = LineSegment< CType >( points[ 5 ], points[ 6 ] );
lines[ 6 ] = LineSegment< CType >( points[ 6 ], points[ 7 ] );
lines[ 7 ] = LineSegment< CType >( points[ 7 ], points[ 4 ] );
//Sides
lines.emplace_back( points[ 0 ], points[ 4 ] );
lines.emplace_back( points[ 1 ], points[ 5 ] );
lines.emplace_back( points[ 2 ], points[ 6 ] );
lines.emplace_back( points[ 3 ], points[ 7 ] );
lines[ 8 ] = LineSegment< CType >( points[ 0 ], points[ 4 ] );
lines[ 9 ] = LineSegment< CType >( points[ 1 ], points[ 5 ] );
lines[ 10 ] = LineSegment< CType >( points[ 2 ], points[ 6 ] );
lines[ 11 ] = LineSegment< CType >( points[ 3 ], points[ 7 ] );
return lines;
}

View File

@@ -56,8 +56,8 @@ namespace fgl::engine
virtual Scale scale() const;
std::vector< Coordinate< CType > > points() const;
std::vector< LineSegment< CType > > lines() const;
std::array< Coordinate< CType >, POINT_COUNT > points() const;
std::array< LineSegment< CType >, LINE_COUNT > lines() const;
constexpr NormalVector right() const { return NormalVector::bypass( constants::WORLD_RIGHT ); }

View File

@@ -12,10 +12,14 @@ namespace fgl::engine::interface
class NormalVector;
//! Dummy class to allow for inheriting to pass 'is_bounding_box[
class BoundingBox
struct BoundingBox
{
public:
constexpr static std::size_t POINT_COUNT { 8 };
constexpr static std::size_t LINE_COUNT { ( POINT_COUNT / 2 ) * 3 };
// Each point has 3 lines (Divide by 2 since we only need 1 line per direction)
virtual ~BoundingBox() {};
};

View File

@@ -84,11 +84,11 @@ namespace fgl::engine
}
template < CoordinateSpace CType >
std::vector< Coordinate< CType > > OrientedBoundingBox< CType >::points() const
std::array< Coordinate< CType >, interface::BoundingBox::POINT_COUNT > OrientedBoundingBox< CType >::points() const
{
assert( middle.vec() != constants::DEFAULT_VEC3 );
assert( scale != glm::vec3( 0.0f ) );
std::vector< Coordinate< CType > > points;
std::array< Coordinate< CType >, POINT_COUNT > points {};
// xp == x positive (Highest x point)
// xn == x negative (Lowest x point)
@@ -129,7 +129,6 @@ namespace fgl::engine
* 6 =========== 7
*/
points.resize( 8 );
points[ 0 ] = Coordinate< CType >( xp_yp_zp );
points[ 1 ] = Coordinate< CType >( xn_yp_zp );
points[ 2 ] = Coordinate< CType >( xn_yp_zn );
@@ -170,41 +169,72 @@ namespace fgl::engine
ZoneScoped;
const auto& other_points { other.points() };
std::vector< Coordinate< CType > > points { this->points() };
points.insert( points.end(), other_points.begin(), other_points.end() );
const auto points { this->points() };
std::array< Coordinate< CType >, interface::BoundingBox::POINT_COUNT * 2 > combined_points {};
std::copy( other_points.begin(), other_points.end(), combined_points.begin() );
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 );
}
template < CoordinateSpace CType >
std::vector< LineSegment< CType > > OrientedBoundingBox< CType >::lines() const
std::array< LineSegment< CType >, interface::BoundingBox::LINE_COUNT > OrientedBoundingBox< CType >::lines() const
{
const auto points { this->points() };
std::vector< LineSegment< CType > > lines;
std::array< LineSegment< CType >, LINE_COUNT > lines;
//Top
lines.emplace_back( points[ 0 ], points[ 1 ] );
lines.emplace_back( points[ 1 ], points[ 2 ] );
lines.emplace_back( points[ 2 ], points[ 3 ] );
lines.emplace_back( points[ 3 ], points[ 0 ] );
lines[ 0 ] = LineSegment< CType >( points[ 0 ], points[ 1 ] );
lines[ 1 ] = LineSegment< CType >( points[ 1 ], points[ 2 ] );
lines[ 2 ] = LineSegment< CType >( points[ 2 ], points[ 3 ] );
lines[ 3 ] = LineSegment< CType >( points[ 3 ], points[ 0 ] );
//Bottom
lines.emplace_back( points[ 4 ], points[ 5 ] );
lines.emplace_back( points[ 5 ], points[ 6 ] );
lines.emplace_back( points[ 6 ], points[ 7 ] );
lines.emplace_back( points[ 7 ], points[ 4 ] );
lines[ 4 ] = LineSegment< CType >( points[ 4 ], points[ 5 ] );
lines[ 5 ] = LineSegment< CType >( points[ 5 ], points[ 6 ] );
lines[ 6 ] = LineSegment< CType >( points[ 6 ], points[ 7 ] );
lines[ 7 ] = LineSegment< CType >( points[ 7 ], points[ 4 ] );
//Sides
lines.emplace_back( points[ 0 ], points[ 4 ] );
lines.emplace_back( points[ 1 ], points[ 5 ] );
lines.emplace_back( points[ 2 ], points[ 6 ] );
lines.emplace_back( points[ 3 ], points[ 7 ] );
lines[ 8 ] = LineSegment< CType >( points[ 0 ], points[ 4 ] );
lines[ 9 ] = LineSegment< CType >( points[ 1 ], points[ 5 ] );
lines[ 10 ] = LineSegment< CType >( points[ 2 ], points[ 6 ] );
lines[ 11 ] = LineSegment< CType >( points[ 3 ], points[ 7 ] );
return lines;
}
template < CoordinateSpace CType, std::size_t TCount >
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() };
// 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 < CoordinateSpace CType >
OrientedBoundingBox< CType > generateBoundingFromPoints( const std::vector< Coordinate< CType > >& points )
{
@@ -234,6 +264,10 @@ namespace fgl::engine
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)

View File

@@ -56,8 +56,8 @@ namespace fgl::engine
consteval static std::array< std::uint32_t, indicies_count > triangleIndicies();
std::vector< Coordinate< CType > > points() const;
std::vector< LineSegment< CType > > lines() const;
std::array< Coordinate< CType >, POINT_COUNT > points() const;
std::array< LineSegment< CType >, LINE_COUNT > lines() const;
NormalVector forward() const { return rotation.forward(); }

View File

@@ -16,8 +16,8 @@ namespace fgl::engine
template < CoordinateSpace CType >
class LineSegment final : public LineBase
{
Coordinate< CType > start;
Coordinate< CType > end;
Coordinate< CType > start { -constants::DEFAULT_VEC3 };
Coordinate< CType > end { constants::DEFAULT_VEC3 };
glm::vec3 getVec3Position() const override { return getPosition().vec(); }
@@ -25,11 +25,7 @@ namespace fgl::engine
public:
NormalVector getDirection() const { return NormalVector( end - start ); }
Coordinate< CType > getPosition() const { return start; }
Coordinate< CType > getEnd() const { return end; }
LineSegment() = default;
explicit LineSegment( const Coordinate< CType > i_start, const Coordinate< CType > i_end ) noexcept :
start( i_start ),
@@ -38,6 +34,12 @@ namespace fgl::engine
explicit LineSegment( const glm::vec3 i_start, glm::vec3 i_end ) : start( i_start ), end( i_end ) {}
NormalVector getDirection() const { return NormalVector( end - start ); }
Coordinate< CType > getPosition() const { return start; }
Coordinate< CType > getEnd() const { return end; }
inline LineSegment flip() const { return LineSegment( end, start ); }
template < typename T >

View File

@@ -51,16 +51,20 @@ namespace fgl::engine
throw std::runtime_error( "Failed to allocate command buffers" );
#if TRACY_ENABLE
m_tracy_ctx.resize( SwapChain::MAX_FRAMES_IN_FLIGHT );
VkPhysicalDevice phy_dev { Device::getInstance().phyDevice() };
VkDevice dev { Device::getInstance().device() };
for ( int i = 0; i < SwapChain::MAX_FRAMES_IN_FLIGHT; ++i )
{
VkPhysicalDevice phy_dev { Device::getInstance().phyDevice() };
VkDevice dev { Device::getInstance().device() };
m_tracy_ctx = TracyVkContext( phy_dev, dev, Device::getInstance().graphicsQueue(), m_command_buffer[ 0 ] );
m_tracy_ctx[ i ] =
TracyVkContext( phy_dev, dev, Device::getInstance().graphicsQueue(), m_command_buffer[ i ] );
}
/*
m_tracy_ctx = TracyVkContextCalibrated(
phy_dev,
dev,
Device::getInstance().graphicsQueue(),
m_command_buffer[ 0 ],
VULKAN_HPP_DEFAULT_DISPATCHER.vkGetPhysicalDeviceCalibrateableTimeDomainsEXT,
VULKAN_HPP_DEFAULT_DISPATCHER.vkGetCalibratedTimestampsEXT );
*/
#endif
}

View File

@@ -29,7 +29,7 @@ namespace fgl::engine
std::vector< vk::CommandBuffer > m_command_buffer {};
std::vector< TracyVkCtx > m_tracy_ctx {};
std::optional< TracyVkCtx > m_tracy_ctx { std::nullopt };
void createCommandBuffers();
void freeCommandBuffers();
@@ -63,7 +63,8 @@ namespace fgl::engine
TracyVkCtx getCurrentTracyCTX() const
{
#if TRACY_ENABLE
return m_tracy_ctx[ current_frame_idx ];
assert( m_tracy_ctx.has_value() );
return m_tracy_ctx.value();
#else
return nullptr;
#endif

View File

@@ -13,15 +13,27 @@
namespace fgl::engine
{
static bool enable_culling { true };
void CullingSystem::pass( FrameInfo& info )
{
ZoneScopedN( "Culling pass" );
const auto frustum { info.camera_frustum };
for ( auto* leaf : info.game_objects.getAllLeafsInFrustum( frustum ) )
ImGui::Checkbox( "Enable culling", &enable_culling );
if ( !enable_culling )
{
return;
}
auto leafs { info.game_objects.getAllLeafsInFrustum( frustum ) };
for ( auto* leaf : leafs )
{
assert( leaf );
for ( auto& obj : *leaf )
{
//Has model?
@@ -43,6 +55,8 @@ namespace fgl::engine
}
}
}
info.in_view_leafs = std::move( leafs );
}
void CullingSystem::runner()

View File

@@ -6,6 +6,8 @@
#include <thread>
#include "concepts.hpp"
namespace fgl::engine
{
struct FrameInfo;
@@ -34,4 +36,7 @@ namespace fgl::engine
void wait();
};
static_assert( is_system< CullingSystem > );
static_assert( is_threaded_system< CullingSystem > );
} // namespace fgl::engine

View File

@@ -113,9 +113,7 @@ namespace fgl::engine
std::uint64_t object_counter { 0 };
std::uint64_t primitive_counter { 0 };
const auto in_view_leafs { info.game_objects.getAllLeafsInFrustum( info.camera_frustum ) };
for ( auto* node : in_view_leafs )
for ( auto* node : info.in_view_leafs )
{
ZoneScopedN( "Process leaf" );
for ( const auto& obj : *node )

View File

@@ -0,0 +1,33 @@
//
// Created by kj16609 on 3/11/24.
//
#ifndef GAME_CONCEPTS_HPP
#define GAME_CONCEPTS_HPP
namespace fgl::engine
{
struct FrameInfo;
template < typename T >
concept is_system = requires( T t, FrameInfo info ) {
{
t.pass( info )
};
};
template < typename T >
concept is_threaded_system = requires( T t, FrameInfo info ) {
requires is_system< T >;
{
t.startPass( info )
};
{
t.wait()
};
};
} // namespace fgl::engine
#endif //GAME_CONCEPTS_HPP

View File

@@ -30,12 +30,13 @@ namespace fgl::engine
#endif
}
std::vector< NodeLeaf* > OctTreeNode::getAllLeafsInFrustum( const Frustum< CoordinateSpace::World >& frustum )
void OctTreeNode::
getAllLeafsInFrustum( const Frustum< CoordinateSpace::World >& frustum, std::vector< NodeLeaf* >& out_leafs )
{
std::vector< NodeLeaf* > leafs {};
//Check if we are inside of the frustum.
if ( !isInFrustum( frustum ) ) return leafs;
if ( !isInFrustum( frustum ) ) return;
auto& leafs { out_leafs };
switch ( m_node_data.index() )
{
@@ -45,62 +46,35 @@ namespace fgl::engine
NodeArray& node_array { std::get< NodeArray >( m_node_data ) };
//Search deeper
#ifndef NDEBUG
for ( int x = 0; x < 2; ++x )
for ( int y = 0; y < 2; ++y )
for ( int z = 0; z < 2; ++z ) assert( node_array[ x ][ y ][ z ] );
#endif
node_array[ LEFT ][ FORWARD ][ TOP ]->getAllLeafsInFrustum( frustum, out_leafs );
node_array[ LEFT ][ FORWARD ][ BOTTOM ]->getAllLeafsInFrustum( frustum, out_leafs );
{
const auto ret { node_array[ LEFT ][ FORWARD ][ TOP ]->getAllLeafsInFrustum( frustum ) };
leafs = std::move( ret );
}
{
const auto ret { node_array[ LEFT ][ FORWARD ][ BOTTOM ]->getAllLeafsInFrustum( frustum ) };
leafs.insert( leafs.end(), ret.begin(), ret.end() );
}
{
const auto ret { node_array[ LEFT ][ BACK ][ TOP ]->getAllLeafsInFrustum( frustum ) };
leafs.insert( leafs.end(), ret.begin(), ret.end() );
}
{
const auto ret { node_array[ LEFT ][ BACK ][ BOTTOM ]->getAllLeafsInFrustum( frustum ) };
leafs.insert( leafs.end(), ret.begin(), ret.end() );
}
node_array[ LEFT ][ BACK ][ TOP ]->getAllLeafsInFrustum( frustum, out_leafs );
node_array[ LEFT ][ BACK ][ BOTTOM ]->getAllLeafsInFrustum( frustum, out_leafs );
{
const auto ret { node_array[ RIGHT ][ FORWARD ][ TOP ]->getAllLeafsInFrustum( frustum ) };
leafs.insert( leafs.end(), ret.begin(), ret.end() );
}
{
const auto ret { node_array[ RIGHT ][ FORWARD ][ BOTTOM ]->getAllLeafsInFrustum( frustum ) };
leafs.insert( leafs.end(), ret.begin(), ret.end() );
}
{
const auto ret { node_array[ RIGHT ][ BACK ][ TOP ]->getAllLeafsInFrustum( frustum ) };
leafs.insert( leafs.end(), ret.begin(), ret.end() );
}
{
const auto ret { node_array[ RIGHT ][ BACK ][ BOTTOM ]->getAllLeafsInFrustum( frustum ) };
leafs.insert( leafs.end(), ret.begin(), ret.end() );
}
return leafs;
node_array[ RIGHT ][ FORWARD ][ TOP ]->getAllLeafsInFrustum( frustum, out_leafs );
node_array[ RIGHT ][ FORWARD ][ BOTTOM ]->getAllLeafsInFrustum( frustum, out_leafs );
node_array[ RIGHT ][ BACK ][ TOP ]->getAllLeafsInFrustum( frustum, out_leafs );
node_array[ RIGHT ][ BACK ][ BOTTOM ]->getAllLeafsInFrustum( frustum, out_leafs );
return;
}
case 1: // NodeLeaf
{
assert( std::holds_alternative< NodeLeaf >( m_node_data ) );
leafs.reserve( 4096 );
leafs.emplace_back( &std::get< NodeLeaf >( m_node_data ) );
NodeLeaf& leaf { std::get< NodeLeaf >( m_node_data ) };
leafs.reserve( LEAF_RESERVE_SIZE );
leafs.emplace_back( &leaf );
//debug::world::drawBoundingBox( m_bounds );
return leafs;
return;
}
default:
throw std::runtime_error( "OctTreeNode::Index out of bounds" );
std::unreachable();
}
return leafs;
std::unreachable();
}
OctTreeNode::OctTreeNode( const WorldCoordinate center, float span, OctTreeNode* parent ) :
@@ -115,6 +89,7 @@ namespace fgl::engine
void OctTreeNode::split( int depth )
{
ZoneScoped;
if ( std::holds_alternative< NodeArray >( m_node_data ) ) return;
auto& game_objects { std::get< NodeLeaf >( m_node_data ) };
@@ -212,7 +187,7 @@ namespace fgl::engine
}
}
bool OctTreeNode::isInFrustum( const Frustum< CoordinateSpace::World >& frustum )
bool OctTreeNode::isInFrustum( const Frustum< CoordinateSpace::World >& frustum ) const
{
#if ENABLE_IMGUI
if ( isEmpty() ) return false;
@@ -308,11 +283,9 @@ namespace fgl::engine
return m_parent->getRoot();
}
std::vector< NodeLeaf* > OctTreeNode::getAllLeafs()
void OctTreeNode::getAllLeafs( std::vector< NodeLeaf* >& objects )
{
ZoneScoped;
std::vector< NodeLeaf* > objects {};
if ( std::holds_alternative< NodeLeaf >( m_node_data ) )
{
auto& leaf { std::get< NodeLeaf >( m_node_data ) };
@@ -335,8 +308,6 @@ namespace fgl::engine
}
}
}
return objects;
}
bool OctTreeNode::recalculateBoundingBoxes()

View File

@@ -5,6 +5,7 @@
#pragma once
#include <bitset>
#include <functional>
#include "engine/GameObject.hpp"
#include "engine/primitives/boxes/AxisAlignedBoundingCube.hpp"
@@ -28,6 +29,34 @@ namespace fgl::engine
class OctTreeNode;
class GameObject;
template < typename T >
class OctTreeAllocator : public std::allocator< T >
{
std::vector< std::vector< std::byte > > blocks;
using BlockIDX = int;
//! Map for each pointer to their respective blocks
std::unordered_map< T*, BlockIDX > m_block_map;
};
template < typename T >
using unique_alloc_ptr = std::unique_ptr< T, std::function< void( T* ) > >;
template < typename T, typename... Ts >
unique_alloc_ptr< T > make_unique_from_allocator( OctTreeAllocator< T >& allocator, Ts... args )
{
T* ptr = allocator.allocate( 1 );
allocator.construct( ptr, args... );
auto deleter = [ &allocator ]( const auto* ptr_i ) -> void
{
allocator.destroy( ptr_i );
allocator.deallocate( ptr_i, 1 );
};
return std::unique_ptr< T, decltype( deleter ) >( ptr, deleter );
}
using NodeArray = std::array< std::array< std::array< std::unique_ptr< OctTreeNode >, 2 >, 2 >, 2 >;
using NodeLeaf = std::vector< GameObject >;
@@ -44,7 +73,10 @@ namespace fgl::engine
//! Real bounds of the node
AxisAlignedBoundingCube< CoordinateSpace::World > m_bounds;
std::variant< NodeArray, NodeLeaf > m_node_data;
using NodeDataT = NodeArray;
using LeafDataT = NodeLeaf;
std::variant< NodeDataT, LeafDataT > m_node_data;
OctTreeNode* m_parent;
@@ -77,7 +109,7 @@ namespace fgl::engine
GameObject extract( const GameObject::ID id );
bool isInFrustum( const Frustum< CoordinateSpace::World >& frustum );
bool isInFrustum( const Frustum< CoordinateSpace::World >& frustum ) const;
bool isEmpty() const
{
@@ -86,13 +118,34 @@ namespace fgl::engine
auto getGameObjectItter( const GameObject::ID id );
void getAllLeafs( std::vector< NodeLeaf* >& out_leafs );
void getAllLeafsInFrustum(
const Frustum< CoordinateSpace::World >& frustum, std::vector< NodeLeaf* >& out_leafs );
public:
bool recalculateBoundingBoxes();
std::vector< NodeLeaf* > getAllLeafs();
constexpr static std::size_t LEAF_RESERVE_SIZE { 1024 };
std::vector< NodeLeaf* > getAllLeafsInFrustum( const Frustum< CoordinateSpace::World >& frustum );
[[nodiscard]] inline std::vector< NodeLeaf* > getAllLeafs()
{
ZoneScoped;
std::vector< NodeLeaf* > leafs;
leafs.reserve( LEAF_RESERVE_SIZE );
this->getAllLeafs( leafs );
return leafs;
}
[[nodiscard]] inline std::vector< NodeLeaf* > getAllLeafsInFrustum( const Frustum< CoordinateSpace::World >&
frustum )
{
ZoneScoped;
std::vector< NodeLeaf* > leafs;
leafs.reserve( LEAF_RESERVE_SIZE );
this->getAllLeafsInFrustum( frustum, leafs );
return leafs;
}
//! Adds a game object, Will split the node if the auto split threshold is reached
OctTreeNode* addGameObject( GameObject&& obj );