Cleanup some octree stuff
This commit is contained in:
@@ -525,6 +525,7 @@ namespace fgl::engine
|
||||
sponza.m_transform.rotation = Rotation( 0.0f, 0.0f, 0.0f );
|
||||
|
||||
m_game_objects_root.addGameObject( std::move( sponza ) );
|
||||
m_game_objects_root.recalculateBoundingBoxes();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#define FGL_FORCE_NOTHING
|
||||
#ifndef FGL_FORCE_NOTHING
|
||||
|
||||
#ifdef __GNUC__
|
||||
@@ -15,6 +14,8 @@
|
||||
#define FGL_COLD __attribute__( ( cold ) )
|
||||
#define FGL_FORCE_INLINE __attribute__( ( always_inline ) )
|
||||
#define FGL_FORCE_INLINE_FLATTEN __attribute__( ( always_inline, flatten ) )
|
||||
#define FGL_ASSUME( ... ) __attribute__( ( assume( __VA_ARGS__ ) ) )
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
#include "GameObject.hpp"
|
||||
|
||||
#include "engine/model/Model.hpp"
|
||||
|
||||
namespace fgl::engine
|
||||
{
|
||||
|
||||
@@ -13,4 +15,9 @@ namespace fgl::engine
|
||||
return { current_id++ };
|
||||
}
|
||||
|
||||
OrientedBoundingBox< CoordinateSpace::World > GameObject::getBoundingBox() const
|
||||
{
|
||||
return this->m_transform.mat() * this->m_model->getBoundingBox();
|
||||
}
|
||||
|
||||
} // namespace fgl::engine
|
||||
@@ -11,6 +11,8 @@
|
||||
|
||||
namespace fgl::engine
|
||||
{
|
||||
template < CoordinateSpace CType >
|
||||
struct OrientedBoundingBox;
|
||||
|
||||
class Model;
|
||||
|
||||
@@ -51,6 +53,8 @@ namespace fgl::engine
|
||||
|
||||
inline const Rotation& getRotation() const { return m_transform.rotation; }
|
||||
|
||||
OrientedBoundingBox< CoordinateSpace::World > getBoundingBox() const;
|
||||
|
||||
static GameObject createGameObject();
|
||||
|
||||
inline ID getId() const { return m_id; }
|
||||
|
||||
@@ -137,10 +137,24 @@ namespace fgl::engine::debug
|
||||
const Coordinate< CoordinateSpace::Screen > end_screen { toScreenSpace( line.getEnd() ) };
|
||||
|
||||
if ( !inView( start_screen.vec() ) && !inView( end_screen.vec() ) ) return;
|
||||
if ( isBehind( start_screen.vec() ) || isBehind( end_screen.vec() ) ) return;
|
||||
|
||||
ImGui::GetForegroundDrawList()->AddLine(
|
||||
glmToImgui( start_screen ), glmToImgui( end_screen ), ImColor( color.x, color.y, color.z ), thickness );
|
||||
if ( isBehind( start_screen.vec() ) )
|
||||
{
|
||||
const auto frustum { getDebugDrawingCamera().getFrustumBounds() };
|
||||
const auto new_line { line.flip() };
|
||||
|
||||
const auto new_point { frustum.intersection( new_line ) };
|
||||
}
|
||||
else if ( isBehind( end_screen.vec() ) )
|
||||
{}
|
||||
else
|
||||
{
|
||||
ImGui::GetForegroundDrawList()->AddLine(
|
||||
glmToImgui( start_screen ),
|
||||
glmToImgui( end_screen ),
|
||||
ImColor( color.x, color.y, color.z ),
|
||||
thickness );
|
||||
}
|
||||
}
|
||||
|
||||
void drawLine(
|
||||
|
||||
@@ -319,4 +319,32 @@ namespace fgl::engine
|
||||
return true;
|
||||
}
|
||||
|
||||
template <>
|
||||
template <>
|
||||
Coordinate< CoordinateSpace::World > Frustum<
|
||||
CoordinateSpace::World >::intersection( const Line< CoordinateSpace::World >& line ) const
|
||||
{
|
||||
Coordinate< CoordinateSpace::World > coordinate { line.getEnd() };
|
||||
|
||||
//Test each. Whatever the line enters exists first is the point to return
|
||||
auto testPlane = [ & ]( const Plane< CoordinateSpace::World >& plane )
|
||||
{
|
||||
const auto old_distance { signedDistance( line.getDirection(), coordinate, line.getPosition() ) };
|
||||
const auto intersection { line.intersection( plane ) };
|
||||
const auto intersection_distance {
|
||||
signedDistance( line.getDirection(), intersection, line.getPosition() )
|
||||
};
|
||||
if ( old_distance < intersection_distance ) coordinate = intersection;
|
||||
};
|
||||
|
||||
testPlane( this->right );
|
||||
testPlane( this->left );
|
||||
testPlane( this->near );
|
||||
testPlane( this->far );
|
||||
testPlane( this->top );
|
||||
testPlane( this->bottom );
|
||||
|
||||
return coordinate;
|
||||
}
|
||||
|
||||
} // namespace fgl::engine
|
||||
|
||||
@@ -81,6 +81,9 @@ namespace fgl::engine
|
||||
template < typename T >
|
||||
bool intersects( const T& t ) const;
|
||||
|
||||
template < typename T >
|
||||
Coordinate< CType > intersection( const T& t ) const;
|
||||
|
||||
std::array< Coordinate< CType >, 4 * 2 > points() const
|
||||
{
|
||||
const Vector pv0 { glm::cross( top.getDirection().vec(), left.getDirection().vec() ) };
|
||||
|
||||
@@ -114,6 +114,8 @@ namespace fgl::engine
|
||||
RotationMatrix mat() const;
|
||||
|
||||
Rotation operator*( const Rotation other ) const;
|
||||
|
||||
bool operator==( const Rotation& other ) const = default;
|
||||
};
|
||||
|
||||
template < RotationModifierType ModifierType >
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "AxisAlignedBoundingBox.hpp"
|
||||
|
||||
#include "OrientedBoundingBox.hpp"
|
||||
#include "engine/primitives/lines/LineSegment.hpp"
|
||||
|
||||
namespace fgl::engine
|
||||
@@ -88,6 +89,67 @@ namespace fgl::engine
|
||||
return lines;
|
||||
}
|
||||
|
||||
template < CoordinateSpace CType >
|
||||
AxisAlignedBoundingBox< CType >& AxisAlignedBoundingBox< CType >::combine( const AxisAlignedBoundingBox& other )
|
||||
{
|
||||
const Coordinate< CType > new_top_right_forward {
|
||||
std::max( this->m_top_right_forward.x, other.m_top_right_forward.x ),
|
||||
std::max( this->m_top_right_forward.y, other.m_top_right_forward.y ),
|
||||
std::max( this->m_top_right_forward.z, other.m_top_right_forward.z ),
|
||||
};
|
||||
|
||||
const Coordinate< CType > new_bottom_left_back {
|
||||
std::min( this->m_bottom_left_back.x, other.m_bottom_left_back.x ),
|
||||
std::min( this->m_bottom_left_back.y, other.m_bottom_left_back.y ),
|
||||
std::min( this->m_bottom_left_back.z, other.m_bottom_left_back.z ),
|
||||
};
|
||||
|
||||
this->m_top_right_forward = new_top_right_forward;
|
||||
this->m_bottom_left_back = new_bottom_left_back;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template < CoordinateSpace CType >
|
||||
AxisAlignedBoundingBox< CType >::AxisAlignedBoundingBox( const OrientedBoundingBox< CType >& oobb ) :
|
||||
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;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Rotation has been done. Need to use the points to figure it out
|
||||
for ( const auto& point : oobb.points() )
|
||||
{
|
||||
m_top_right_forward.x = std::max( m_top_right_forward.x, point.x );
|
||||
m_top_right_forward.y = std::max( m_top_right_forward.y, point.y );
|
||||
m_top_right_forward.z = std::max( m_top_right_forward.z, point.z );
|
||||
|
||||
m_bottom_left_back.x = std::min( m_bottom_left_back.x, point.x );
|
||||
m_bottom_left_back.y = std::min( m_bottom_left_back.y, point.y );
|
||||
m_bottom_left_back.z = std::min( m_bottom_left_back.z, point.z );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template < CoordinateSpace CType >
|
||||
AxisAlignedBoundingBox< CType >& AxisAlignedBoundingBox< CType >::combine( const OrientedBoundingBox< CType >&
|
||||
other )
|
||||
{
|
||||
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;
|
||||
else
|
||||
{
|
||||
return this->combine( aabb );
|
||||
}
|
||||
}
|
||||
|
||||
template class AxisAlignedBoundingBox< CoordinateSpace::Model >;
|
||||
template class AxisAlignedBoundingBox< CoordinateSpace::World >;
|
||||
} // namespace fgl::engine
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
|
||||
namespace fgl::engine
|
||||
{
|
||||
template < CoordinateSpace CType >
|
||||
struct OrientedBoundingBox;
|
||||
|
||||
//! Bounding box alligned with the world axis
|
||||
template < CoordinateSpace CType >
|
||||
class AxisAlignedBoundingBox : public interface::BoundingBox
|
||||
@@ -22,11 +25,6 @@ namespace fgl::engine
|
||||
|
||||
constexpr static auto SpaceType { CType };
|
||||
|
||||
AxisAlignedBoundingBox() :
|
||||
m_top_right_forward( constants::WORLD_CENTER ),
|
||||
m_bottom_left_back( constants::WORLD_CENTER )
|
||||
{}
|
||||
|
||||
explicit AxisAlignedBoundingBox(
|
||||
const Coordinate< CType > top_right_forward, const Coordinate< CType > bottom_left_back ) :
|
||||
m_top_right_forward( top_right_forward ),
|
||||
@@ -37,6 +35,16 @@ namespace fgl::engine
|
||||
AxisAlignedBoundingBox( midpoint + scale, midpoint - scale )
|
||||
{}
|
||||
|
||||
explicit AxisAlignedBoundingBox( const OrientedBoundingBox< CType >& oobb );
|
||||
|
||||
AxisAlignedBoundingBox& combine( const AxisAlignedBoundingBox& other );
|
||||
AxisAlignedBoundingBox& combine( const OrientedBoundingBox< CType >& other );
|
||||
|
||||
bool operator==( const AxisAlignedBoundingBox< CType >& other ) const
|
||||
{
|
||||
return m_top_right_forward == other.m_top_right_forward && m_bottom_left_back == other.m_bottom_left_back;
|
||||
}
|
||||
|
||||
virtual Coordinate< CType > getPosition() const
|
||||
{
|
||||
return fgl::midpoint( m_top_right_forward, m_bottom_left_back );
|
||||
|
||||
@@ -12,11 +12,14 @@ namespace fgl::engine
|
||||
template < CoordinateSpace CType >
|
||||
bool AxisAlignedBoundingCube< CType >::contains( const Coordinate< CType >& coordinate ) const
|
||||
{
|
||||
const Coordinate< CType > centered_coordinate { coordinate - m_middle };
|
||||
const Coordinate< CType > centered_coordinate { coordinate - this->getPosition() };
|
||||
|
||||
return ( ( centered_coordinate.template x ) < m_span && ( centered_coordinate.template x ) > -m_span )
|
||||
&& ( ( centered_coordinate.template y ) < m_span && ( centered_coordinate.template y ) > -m_span )
|
||||
&& ( ( centered_coordinate.template z ) < m_span && ( centered_coordinate.template z ) > -m_span );
|
||||
return ( ( centered_coordinate.template x ) < this->span()
|
||||
&& ( centered_coordinate.template x ) > -this->span() )
|
||||
&& ( ( centered_coordinate.template y ) < this->span()
|
||||
&& ( centered_coordinate.template y ) > -this->span() )
|
||||
&& ( ( centered_coordinate.template z ) < this->span()
|
||||
&& ( centered_coordinate.template z ) > -this->span() );
|
||||
}
|
||||
|
||||
//template class AxisAlignedBoundingCube< CoordinateSpace::Model >;
|
||||
|
||||
@@ -16,31 +16,17 @@ namespace fgl::engine
|
||||
template < CoordinateSpace CType >
|
||||
class AxisAlignedBoundingCube final : public AxisAlignedBoundingBox< CType >
|
||||
{
|
||||
Coordinate< CType > m_middle;
|
||||
float m_span;
|
||||
|
||||
public:
|
||||
|
||||
constexpr static auto SpaceType { CType };
|
||||
|
||||
AxisAlignedBoundingCube() : m_middle( constants::WORLD_CENTER ), m_span( 1.0f ) {}
|
||||
|
||||
explicit AxisAlignedBoundingCube( const Coordinate< CType > middle, const float span ) :
|
||||
m_middle( middle ),
|
||||
m_span( span )
|
||||
AxisAlignedBoundingBox< CType >( middle, Scale( span, span, span ) )
|
||||
{}
|
||||
|
||||
bool contains( const Coordinate< CType >& coordinate ) const;
|
||||
|
||||
float span() const { return m_span; }
|
||||
|
||||
Scale scale() const override { return Scale( m_span, m_span, m_span ); }
|
||||
|
||||
inline Coordinate< CType > topLeftForward() const override { return m_middle + scale(); }
|
||||
|
||||
inline Coordinate< CType > bottomLeftBack() const override { return m_middle - scale(); }
|
||||
|
||||
Coordinate< CType > getPosition() const override { return m_middle; }
|
||||
float span() const { return this->scale().x; }
|
||||
|
||||
constexpr NormalVector right() const { return NormalVector::bypass( constants::WORLD_RIGHT ); }
|
||||
|
||||
|
||||
@@ -76,6 +76,8 @@ namespace fgl::engine
|
||||
|
||||
Coordinate& operator=( const Coordinate& other ) = default;
|
||||
Coordinate& operator=( Coordinate&& other ) = default;
|
||||
|
||||
bool operator==( const Coordinate& other ) const = default;
|
||||
};
|
||||
|
||||
using ModelCoordinate = Coordinate< CoordinateSpace::Model >;
|
||||
|
||||
@@ -29,9 +29,7 @@ namespace fgl::engine
|
||||
{
|
||||
//Test if the object is in the frustum
|
||||
|
||||
const OrientedBoundingBox model_bounding_box {
|
||||
obj.m_model->getBoundingBox( Matrix< MatrixType::ModelToWorld >( obj.m_transform.mat4() ) )
|
||||
};
|
||||
const OrientedBoundingBox model_bounding_box { obj.getBoundingBox() };
|
||||
|
||||
obj.m_is_visible = frustum.intersects( model_bounding_box );
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <glm/gtx/string_cast.hpp>
|
||||
|
||||
#include "engine/debug/drawers.hpp"
|
||||
#include "engine/model/Model.hpp"
|
||||
#include "engine/primitives/Frustum.hpp"
|
||||
|
||||
namespace fgl::engine
|
||||
@@ -19,78 +20,76 @@ namespace fgl::engine
|
||||
std::vector< NodeLeaf* > leafs {};
|
||||
|
||||
//Check if we are inside of the frustum.
|
||||
if ( isInFrustum( frustum ) )
|
||||
if ( !isInFrustum( frustum ) ) return leafs;
|
||||
|
||||
switch ( m_node_data.index() )
|
||||
{
|
||||
switch ( m_node_data.index() )
|
||||
{
|
||||
case 0: // NodeArray
|
||||
{
|
||||
assert( std::holds_alternative< NodeArray >( m_node_data ) );
|
||||
NodeArray& node_array { std::get< NodeArray >( m_node_data ) };
|
||||
//Search deeper
|
||||
case 0: // NodeArray
|
||||
{
|
||||
assert( std::holds_alternative< NodeArray >( m_node_data ) );
|
||||
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 ] );
|
||||
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
|
||||
|
||||
{
|
||||
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() );
|
||||
}
|
||||
|
||||
{
|
||||
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;
|
||||
}
|
||||
case 1: // NodeLeaf
|
||||
{
|
||||
assert( std::holds_alternative< NodeLeaf >( m_node_data ) );
|
||||
leafs.reserve( 4096 );
|
||||
leafs.emplace_back( &std::get< NodeLeaf >( m_node_data ) );
|
||||
|
||||
//debug::world::drawBoundingBox( m_bounds );
|
||||
|
||||
return leafs;
|
||||
const auto ret { node_array[ LEFT ][ FORWARD ][ TOP ]->getAllLeafsInFrustum( frustum ) };
|
||||
leafs = std::move( ret );
|
||||
}
|
||||
default:
|
||||
throw std::runtime_error( "OctTreeNode::Index out of bounds" );
|
||||
}
|
||||
{
|
||||
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() );
|
||||
}
|
||||
|
||||
{
|
||||
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;
|
||||
}
|
||||
case 1: // NodeLeaf
|
||||
{
|
||||
assert( std::holds_alternative< NodeLeaf >( m_node_data ) );
|
||||
leafs.reserve( 4096 );
|
||||
leafs.emplace_back( &std::get< NodeLeaf >( m_node_data ) );
|
||||
|
||||
//debug::world::drawBoundingBox( m_bounds );
|
||||
|
||||
return leafs;
|
||||
}
|
||||
default:
|
||||
throw std::runtime_error( "OctTreeNode::Index out of bounds" );
|
||||
}
|
||||
|
||||
return leafs;
|
||||
}
|
||||
|
||||
OctTreeNode::OctTreeNode( const WorldCoordinate center, float span, OctTreeNode* parent ) :
|
||||
m_fit_bounding_box( center, glm::vec3( span, span, span ) ),
|
||||
m_bounds( center, span ),
|
||||
m_node_data( NodeLeaf() ),
|
||||
m_parent( parent )
|
||||
@@ -198,7 +197,19 @@ namespace fgl::engine
|
||||
|
||||
bool OctTreeNode::isInFrustum( const Frustum< CoordinateSpace::World >& frustum )
|
||||
{
|
||||
return !isEmpty() && frustum.intersects( m_bounds );
|
||||
#if ENABLE_IMGUI
|
||||
if ( isEmpty() ) return false;
|
||||
if ( frustum.intersects( m_fit_bounding_box ) )
|
||||
{
|
||||
debug::world::drawBoundingBox( m_fit_bounding_box );
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
#else
|
||||
return !isEmpty() && frustum.intersects( m_fit_bounding_box );
|
||||
#endif
|
||||
}
|
||||
|
||||
OctTreeNode* OctTreeNode::findID( const GameObject::ID id )
|
||||
@@ -305,4 +316,85 @@ namespace fgl::engine
|
||||
return objects;
|
||||
}
|
||||
|
||||
bool OctTreeNode::recalculateBoundingBoxes()
|
||||
{
|
||||
ZoneScoped;
|
||||
const auto old_bounds { m_fit_bounding_box };
|
||||
if ( std::holds_alternative< NodeArray >( m_node_data ) )
|
||||
{
|
||||
ZoneScopedN( "Process Array" );
|
||||
bool bounding_box_changed { false };
|
||||
auto& nodes { std::get< NodeArray >( m_node_data ) };
|
||||
for ( std::size_t x = 0; x < 2; ++x )
|
||||
{
|
||||
for ( std::size_t y = 0; y < 2; ++y )
|
||||
{
|
||||
for ( std::size_t z = 0; z < 2; ++z )
|
||||
{
|
||||
auto& node { nodes[ x ][ y ][ z ] };
|
||||
bounding_box_changed |= node->recalculateBoundingBoxes();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( bounding_box_changed )
|
||||
{
|
||||
//We need to update our bounding box now.
|
||||
auto new_bounds { nodes[ 0 ][ 0 ][ 0 ]->m_fit_bounding_box };
|
||||
|
||||
for ( std::size_t x = 0; x < 2; ++x )
|
||||
{
|
||||
for ( std::size_t y = 0; y < 2; ++y )
|
||||
{
|
||||
for ( std::size_t z = 0; z < 2; ++z )
|
||||
{
|
||||
auto& node { nodes[ x ][ y ][ z ] };
|
||||
new_bounds.combine( node->m_fit_bounding_box );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( new_bounds == old_bounds )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->m_fit_bounding_box = new_bounds;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
else if ( std::holds_alternative< NodeLeaf >( m_node_data ) )
|
||||
{
|
||||
ZoneScopedN( "Process Leaf" );
|
||||
auto& game_objects { std::get< NodeLeaf >( m_node_data ) };
|
||||
|
||||
if ( game_objects.size() == 0 ) return false;
|
||||
|
||||
AxisAlignedBoundingBox< CoordinateSpace::World > new_bounds { game_objects[ 0 ].getBoundingBox() };
|
||||
|
||||
[[assume( game_objects.size() <= MAX_NODES_IN_LEAF )]];
|
||||
|
||||
for ( const GameObject& obj : game_objects )
|
||||
{
|
||||
new_bounds.combine( obj.getBoundingBox() );
|
||||
}
|
||||
|
||||
if ( new_bounds == old_bounds )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->m_fit_bounding_box = new_bounds;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
std::unreachable();
|
||||
}
|
||||
|
||||
} // namespace fgl::engine
|
||||
@@ -36,7 +36,12 @@ namespace fgl::engine
|
||||
|
||||
class OctTreeNode
|
||||
{
|
||||
//! Fit to each model
|
||||
AxisAlignedBoundingBox< CoordinateSpace::World > m_fit_bounding_box;
|
||||
|
||||
//! Real bounds of the node
|
||||
AxisAlignedBoundingCube< CoordinateSpace::World > m_bounds;
|
||||
|
||||
std::variant< NodeArray, NodeLeaf > m_node_data;
|
||||
|
||||
OctTreeNode* m_parent;
|
||||
@@ -81,6 +86,8 @@ namespace fgl::engine
|
||||
|
||||
public:
|
||||
|
||||
bool recalculateBoundingBoxes();
|
||||
|
||||
std::vector< NodeLeaf* > getAllLeafs();
|
||||
|
||||
std::vector< NodeLeaf* > getAllLeafsInFrustum( const Frustum< CoordinateSpace::World >& frustum );
|
||||
|
||||
5
src/engine/tree/quadtree/QuadTree.cpp
Normal file
5
src/engine/tree/quadtree/QuadTree.cpp
Normal file
@@ -0,0 +1,5 @@
|
||||
//
|
||||
// Created by kj16609 on 3/11/24.
|
||||
//
|
||||
|
||||
#include "QuadTree.hpp"
|
||||
11
src/engine/tree/quadtree/QuadTree.hpp
Normal file
11
src/engine/tree/quadtree/QuadTree.hpp
Normal file
@@ -0,0 +1,11 @@
|
||||
//
|
||||
// Created by kj16609 on 3/11/24.
|
||||
//
|
||||
|
||||
#ifndef GAME_QUADTREE_HPP
|
||||
#define GAME_QUADTREE_HPP
|
||||
|
||||
class QuadTree
|
||||
{};
|
||||
|
||||
#endif //GAME_QUADTREE_HPP
|
||||
Reference in New Issue
Block a user